* [PATCH v6 01/10] xfs: add EOFBLOCKS inode tagging/untagging
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
@ 2012-11-06 14:50 ` Brian Foster
2012-11-06 14:50 ` [PATCH v6 02/10] xfs: support a tag-based inode_ag_iterator Brian Foster
` (10 subsequent siblings)
11 siblings, 0 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 14:50 UTC (permalink / raw)
To: xfs
Add the XFS_ICI_EOFBLOCKS_TAG inode tag to identify inodes with
speculatively preallocated blocks beyond EOF. An inode is tagged
when speculative preallocation occurs and untagged either via
truncate down or when post-EOF blocks are freed via release or
reclaim.
The tag management is intentionally not aggressive to prefer
simplicity over the complexity of handling all the corner cases
under which post-EOF blocks could be freed (i.e., forward
truncation, fallocate, write error conditions, etc.). This means
that a tagged inode may or may not have post-EOF blocks after a
period of time. The tag is eventually cleared when the inode is
released or reclaimed.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely<tinguely@sgi.com>
---
fs/xfs/xfs_ag.h | 1 +
fs/xfs/xfs_icache.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++
fs/xfs/xfs_icache.h | 3 ++
fs/xfs/xfs_iomap.c | 8 ++++++
fs/xfs/xfs_iops.c | 4 +++
fs/xfs/xfs_trace.h | 5 ++++
fs/xfs/xfs_vnodeops.c | 2 +
7 files changed, 85 insertions(+), 0 deletions(-)
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index 44d65c1..22bd4db 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -233,6 +233,7 @@ typedef struct xfs_perag {
#define XFS_ICI_NO_TAG (-1) /* special flag for an untagged lookup
in xfs_inode_ag_iterator */
#define XFS_ICI_RECLAIM_TAG 0 /* inode is to be reclaimed */
+#define XFS_ICI_EOFBLOCKS_TAG 1 /* inode has blocks beyond EOF */
#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels)
#define XFS_MIN_FREELIST_RAW(bl,cl,mp) \
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 9c8703b..f9afc5f 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1128,3 +1128,65 @@ xfs_reclaim_inodes_count(
return reclaimable;
}
+void
+xfs_inode_set_eofblocks_tag(
+ xfs_inode_t *ip)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ struct xfs_perag *pag;
+ int tagged;
+
+ pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
+ spin_lock(&pag->pag_ici_lock);
+ trace_xfs_inode_set_eofblocks_tag(ip);
+
+ tagged = radix_tree_tagged(&pag->pag_ici_root,
+ XFS_ICI_EOFBLOCKS_TAG);
+ radix_tree_tag_set(&pag->pag_ici_root,
+ XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino),
+ XFS_ICI_EOFBLOCKS_TAG);
+ if (!tagged) {
+ /* propagate the eofblocks tag up into the perag radix tree */
+ spin_lock(&ip->i_mount->m_perag_lock);
+ radix_tree_tag_set(&ip->i_mount->m_perag_tree,
+ XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
+ XFS_ICI_EOFBLOCKS_TAG);
+ spin_unlock(&ip->i_mount->m_perag_lock);
+
+ trace_xfs_perag_set_eofblocks(ip->i_mount, pag->pag_agno,
+ -1, _RET_IP_);
+ }
+
+ spin_unlock(&pag->pag_ici_lock);
+ xfs_perag_put(pag);
+}
+
+void
+xfs_inode_clear_eofblocks_tag(
+ xfs_inode_t *ip)
+{
+ struct xfs_mount *mp = ip->i_mount;
+ struct xfs_perag *pag;
+
+ pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
+ spin_lock(&pag->pag_ici_lock);
+ trace_xfs_inode_clear_eofblocks_tag(ip);
+
+ radix_tree_tag_clear(&pag->pag_ici_root,
+ XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino),
+ XFS_ICI_EOFBLOCKS_TAG);
+ if (!radix_tree_tagged(&pag->pag_ici_root, XFS_ICI_EOFBLOCKS_TAG)) {
+ /* clear the eofblocks tag from the perag radix tree */
+ spin_lock(&ip->i_mount->m_perag_lock);
+ radix_tree_tag_clear(&ip->i_mount->m_perag_tree,
+ XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
+ XFS_ICI_EOFBLOCKS_TAG);
+ spin_unlock(&ip->i_mount->m_perag_lock);
+ trace_xfs_perag_clear_eofblocks(ip->i_mount, pag->pag_agno,
+ -1, _RET_IP_);
+ }
+
+ spin_unlock(&pag->pag_ici_lock);
+ xfs_perag_put(pag);
+}
+
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index 222e22f..db36130 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -35,6 +35,9 @@ void xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan);
void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
+void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip);
+void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
+
int xfs_sync_inode_grab(struct xfs_inode *ip);
int xfs_inode_ag_iterator(struct xfs_mount *mp,
int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags),
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index a066cf1..add06b4 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -41,6 +41,7 @@
#include "xfs_utils.h"
#include "xfs_iomap.h"
#include "xfs_trace.h"
+#include "xfs_icache.h"
#define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \
@@ -450,6 +451,13 @@ retry:
if (!(imap[0].br_startblock || XFS_IS_REALTIME_INODE(ip)))
return xfs_alert_fsblock_zero(ip, &imap[0]);
+ /*
+ * Tag the inode as speculatively preallocated so we can reclaim this
+ * space on demand, if necessary.
+ */
+ if (prealloc)
+ xfs_inode_set_eofblocks_tag(ip);
+
*ret_imap = imap[0];
return 0;
}
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 4e00cf0..81f5c49 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -38,6 +38,7 @@
#include "xfs_vnodeops.h"
#include "xfs_inode_item.h"
#include "xfs_trace.h"
+#include "xfs_icache.h"
#include <linux/capability.h>
#include <linux/xattr.h>
@@ -854,6 +855,9 @@ xfs_setattr_size(
* and do not wait the usual (long) time for writeout.
*/
xfs_iflags_set(ip, XFS_ITRUNCATED);
+
+ /* A truncate down always removes post-EOF blocks. */
+ xfs_inode_clear_eofblocks_tag(ip);
}
if (mask & ATTR_CTIME) {
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 7d36ccf..6f46e03 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -130,6 +130,8 @@ DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag);
DEFINE_PERAG_REF_EVENT(xfs_perag_put);
DEFINE_PERAG_REF_EVENT(xfs_perag_set_reclaim);
DEFINE_PERAG_REF_EVENT(xfs_perag_clear_reclaim);
+DEFINE_PERAG_REF_EVENT(xfs_perag_set_eofblocks);
+DEFINE_PERAG_REF_EVENT(xfs_perag_clear_eofblocks);
TRACE_EVENT(xfs_attr_list_node_descend,
TP_PROTO(struct xfs_attr_list_context *ctx,
@@ -585,6 +587,9 @@ DEFINE_INODE_EVENT(xfs_update_time);
DEFINE_INODE_EVENT(xfs_dquot_dqalloc);
DEFINE_INODE_EVENT(xfs_dquot_dqdetach);
+DEFINE_INODE_EVENT(xfs_inode_set_eofblocks_tag);
+DEFINE_INODE_EVENT(xfs_inode_clear_eofblocks_tag);
+
DECLARE_EVENT_CLASS(xfs_iref_class,
TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip),
TP_ARGS(ip, caller_ip),
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 2ee1f49..e6e1d11 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -238,6 +238,8 @@ xfs_free_eofblocks(
} else {
error = xfs_trans_commit(tp,
XFS_TRANS_RELEASE_LOG_RES);
+ if (!error)
+ xfs_inode_clear_eofblocks_tag(ip);
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v6 02/10] xfs: support a tag-based inode_ag_iterator
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
2012-11-06 14:50 ` [PATCH v6 01/10] xfs: add EOFBLOCKS inode tagging/untagging Brian Foster
@ 2012-11-06 14:50 ` Brian Foster
2012-11-06 14:50 ` [PATCH v6 03/10] xfs: create helper to check whether to free eofblocks on inode Brian Foster
` (9 subsequent siblings)
11 siblings, 0 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 14:50 UTC (permalink / raw)
To: xfs
Genericize xfs_inode_ag_walk() to support an optional radix tree tag
and args argument for the execute function. Create a new wrapper
called xfs_inode_ag_iterator_tag() that performs a tag based walk
of perag's and inodes.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely<tinguely@sgi.com>
---
fs/xfs/xfs_icache.c | 56 ++++++++++++++++++++++++++++++++++++++++-----
fs/xfs/xfs_icache.h | 7 ++++-
fs/xfs/xfs_qm_syscalls.c | 5 ++-
3 files changed, 57 insertions(+), 11 deletions(-)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index f9afc5f..878eb24 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -516,8 +516,11 @@ xfs_inode_ag_walk(
struct xfs_mount *mp,
struct xfs_perag *pag,
int (*execute)(struct xfs_inode *ip,
- struct xfs_perag *pag, int flags),
- int flags)
+ struct xfs_perag *pag, int flags,
+ void *args),
+ int flags,
+ void *args,
+ int tag)
{
uint32_t first_index;
int last_error = 0;
@@ -536,9 +539,17 @@ restart:
int i;
rcu_read_lock();
- nr_found = radix_tree_gang_lookup(&pag->pag_ici_root,
+
+ if (tag == -1)
+ nr_found = radix_tree_gang_lookup(&pag->pag_ici_root,
(void **)batch, first_index,
XFS_LOOKUP_BATCH);
+ else
+ nr_found = radix_tree_gang_lookup_tag(
+ &pag->pag_ici_root,
+ (void **) batch, first_index,
+ XFS_LOOKUP_BATCH, tag);
+
if (!nr_found) {
rcu_read_unlock();
break;
@@ -579,7 +590,7 @@ restart:
for (i = 0; i < nr_found; i++) {
if (!batch[i])
continue;
- error = execute(batch[i], pag, flags);
+ error = execute(batch[i], pag, flags, args);
IRELE(batch[i]);
if (error == EAGAIN) {
skipped++;
@@ -608,8 +619,10 @@ int
xfs_inode_ag_iterator(
struct xfs_mount *mp,
int (*execute)(struct xfs_inode *ip,
- struct xfs_perag *pag, int flags),
- int flags)
+ struct xfs_perag *pag, int flags,
+ void *args),
+ int flags,
+ void *args)
{
struct xfs_perag *pag;
int error = 0;
@@ -619,7 +632,36 @@ xfs_inode_ag_iterator(
ag = 0;
while ((pag = xfs_perag_get(mp, ag))) {
ag = pag->pag_agno + 1;
- error = xfs_inode_ag_walk(mp, pag, execute, flags);
+ error = xfs_inode_ag_walk(mp, pag, execute, flags, args, -1);
+ xfs_perag_put(pag);
+ if (error) {
+ last_error = error;
+ if (error == EFSCORRUPTED)
+ break;
+ }
+ }
+ return XFS_ERROR(last_error);
+}
+
+int
+xfs_inode_ag_iterator_tag(
+ struct xfs_mount *mp,
+ int (*execute)(struct xfs_inode *ip,
+ struct xfs_perag *pag, int flags,
+ void *args),
+ int flags,
+ void *args,
+ int tag)
+{
+ struct xfs_perag *pag;
+ int error = 0;
+ int last_error = 0;
+ xfs_agnumber_t ag;
+
+ ag = 0;
+ while ((pag = xfs_perag_get_tag(mp, ag, tag))) {
+ ag = pag->pag_agno + 1;
+ error = xfs_inode_ag_walk(mp, pag, execute, flags, args, tag);
xfs_perag_put(pag);
if (error) {
last_error = error;
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index db36130..bb80237 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -40,7 +40,10 @@ void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
int xfs_sync_inode_grab(struct xfs_inode *ip);
int xfs_inode_ag_iterator(struct xfs_mount *mp,
- int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags),
- int flags);
+ int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags, void *args),
+ int flags, void *args);
+int xfs_inode_ag_iterator_tag(struct xfs_mount *mp,
+ int (*execute)(struct xfs_inode *ip, struct xfs_perag *pag, int flags, void *args),
+ int flags, void *args, int tag);
#endif
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index 7a9071f..5f53e75 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -846,7 +846,8 @@ STATIC int
xfs_dqrele_inode(
struct xfs_inode *ip,
struct xfs_perag *pag,
- int flags)
+ int flags,
+ void *args)
{
/* skip quota inodes */
if (ip == ip->i_mount->m_quotainfo->qi_uquotaip ||
@@ -882,5 +883,5 @@ xfs_qm_dqrele_all_inodes(
uint flags)
{
ASSERT(mp->m_quotainfo);
- xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags);
+ xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, NULL);
}
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v6 03/10] xfs: create helper to check whether to free eofblocks on inode
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
2012-11-06 14:50 ` [PATCH v6 01/10] xfs: add EOFBLOCKS inode tagging/untagging Brian Foster
2012-11-06 14:50 ` [PATCH v6 02/10] xfs: support a tag-based inode_ag_iterator Brian Foster
@ 2012-11-06 14:50 ` Brian Foster
2012-11-06 14:50 ` [PATCH v6 04/10] xfs: make xfs_free_eofblocks() non-static, return EAGAIN on trylock failure Brian Foster
` (8 subsequent siblings)
11 siblings, 0 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 14:50 UTC (permalink / raw)
To: xfs
This check is used in multiple places to determine whether we
should check for (and potentially free) post EOF blocks on an
inode. Add a helper to consolidate the check.
Note that when we remove an inode from the cache (xfs_inactive()),
we are required to trim post-EOF blocks even if the inode is marked
preallocated or append-only to maintain correct space accounting.
The 'force' parameter to xfs_can_free_eofblocks() specifies whether
we should ignore the prealloc/append-only status of the inode.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely<tinguely@sgi.com>
---
fs/xfs/xfs_inode.c | 37 +++++++++++++++++++++++++++++++++++++
fs/xfs/xfs_inode.h | 1 +
fs/xfs/xfs_vnodeops.c | 19 +++++++------------
3 files changed, 45 insertions(+), 12 deletions(-)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 95f7a73..cc7468b 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -3911,3 +3911,40 @@ xfs_iext_irec_update_extoffs(
ifp->if_u1.if_ext_irec[i].er_extoff += ext_diff;
}
}
+
+/*
+ * Test whether it is appropriate to check an inode for and free post EOF
+ * blocks. The 'force' parameter determines whether we should also consider
+ * regular files that are marked preallocated or append-only.
+ */
+bool
+xfs_can_free_eofblocks(struct xfs_inode *ip, bool force)
+{
+ /* prealloc/delalloc exists only on regular files */
+ if (!S_ISREG(ip->i_d.di_mode))
+ return false;
+
+ /*
+ * Zero sized files with no cached pages and delalloc blocks will not
+ * have speculative prealloc/delalloc blocks to remove.
+ */
+ if (VFS_I(ip)->i_size == 0 &&
+ VN_CACHED(VFS_I(ip)) == 0 &&
+ ip->i_delayed_blks == 0)
+ return false;
+
+ /* If we haven't read in the extent list, then don't do it now. */
+ if (!(ip->i_df.if_flags & XFS_IFEXTENTS))
+ return false;
+
+ /*
+ * Do not free real preallocated or append-only files unless the file
+ * has delalloc blocks and we are forced to remove them.
+ */
+ if (ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND))
+ if (!force || ip->i_delayed_blks == 0)
+ return false;
+
+ return true;
+}
+
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 1fc2065..21b4de3 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -585,6 +585,7 @@ void xfs_iext_irec_compact(xfs_ifork_t *);
void xfs_iext_irec_compact_pages(xfs_ifork_t *);
void xfs_iext_irec_compact_full(xfs_ifork_t *);
void xfs_iext_irec_update_extoffs(xfs_ifork_t *, int, int);
+bool xfs_can_free_eofblocks(struct xfs_inode *, bool);
#define xfs_ipincount(ip) ((unsigned int) atomic_read(&ip->i_pincount))
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index e6e1d11..c4c1539 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -436,11 +436,7 @@ xfs_release(
if (ip->i_d.di_nlink == 0)
return 0;
- if ((S_ISREG(ip->i_d.di_mode) &&
- (VFS_I(ip)->i_size > 0 ||
- (VN_CACHED(VFS_I(ip)) > 0 || ip->i_delayed_blks > 0)) &&
- (ip->i_df.if_flags & XFS_IFEXTENTS)) &&
- (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) {
+ if (xfs_can_free_eofblocks(ip, false)) {
/*
* If we can't get the iolock just skip truncating the blocks
@@ -516,13 +512,12 @@ xfs_inactive(
goto out;
if (ip->i_d.di_nlink != 0) {
- if ((S_ISREG(ip->i_d.di_mode) &&
- (VFS_I(ip)->i_size > 0 ||
- (VN_CACHED(VFS_I(ip)) > 0 || ip->i_delayed_blks > 0)) &&
- (ip->i_df.if_flags & XFS_IFEXTENTS) &&
- (!(ip->i_d.di_flags &
- (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) ||
- ip->i_delayed_blks != 0))) {
+ /*
+ * force is true because we are evicting an inode from the
+ * cache. Post-eof blocks must be freed, lest we end up with
+ * broken free space accounting.
+ */
+ if (xfs_can_free_eofblocks(ip, true)) {
error = xfs_free_eofblocks(mp, ip, false);
if (error)
return VN_INACTIVE_CACHE;
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v6 04/10] xfs: make xfs_free_eofblocks() non-static, return EAGAIN on trylock failure
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
` (2 preceding siblings ...)
2012-11-06 14:50 ` [PATCH v6 03/10] xfs: create helper to check whether to free eofblocks on inode Brian Foster
@ 2012-11-06 14:50 ` Brian Foster
2012-11-06 14:50 ` [PATCH v6 05/10] xfs: create function to scan and clear EOFBLOCKS inodes Brian Foster
` (7 subsequent siblings)
11 siblings, 0 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 14:50 UTC (permalink / raw)
To: xfs
Turn xfs_free_eofblocks() into a non-static function, return EAGAIN to
indicate trylock failure and make sure this error is not propagated in
xfs_release().
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely<tinguely@sgi.com>
---
fs/xfs/xfs_vnodeops.c | 6 +++---
fs/xfs/xfs_vnodeops.h | 1 +
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index c4c1539..c2ddd7a 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -151,7 +151,7 @@ xfs_readlink(
* when the link count isn't zero and by xfs_dm_punch_hole() when
* punching a hole to EOF.
*/
-STATIC int
+int
xfs_free_eofblocks(
xfs_mount_t *mp,
xfs_inode_t *ip,
@@ -200,7 +200,7 @@ xfs_free_eofblocks(
if (need_iolock) {
if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
xfs_trans_cancel(tp, 0);
- return 0;
+ return EAGAIN;
}
}
@@ -463,7 +463,7 @@ xfs_release(
return 0;
error = xfs_free_eofblocks(mp, ip, true);
- if (error)
+ if (error && error != EAGAIN)
return error;
/* delalloc blocks after truncation means it really is dirty */
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index 447e146..52fafc4 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -57,5 +57,6 @@ int xfs_flush_pages(struct xfs_inode *ip, xfs_off_t first,
int xfs_wait_on_pages(struct xfs_inode *ip, xfs_off_t first, xfs_off_t last);
int xfs_zero_eof(struct xfs_inode *, xfs_off_t, xfs_fsize_t);
+int xfs_free_eofblocks(struct xfs_mount *, struct xfs_inode *, bool);
#endif /* _XFS_VNODEOPS_H */
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v6 05/10] xfs: create function to scan and clear EOFBLOCKS inodes
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
` (3 preceding siblings ...)
2012-11-06 14:50 ` [PATCH v6 04/10] xfs: make xfs_free_eofblocks() non-static, return EAGAIN on trylock failure Brian Foster
@ 2012-11-06 14:50 ` Brian Foster
2012-11-06 14:50 ` [PATCH v6 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl Brian Foster
` (6 subsequent siblings)
11 siblings, 0 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 14:50 UTC (permalink / raw)
To: xfs
xfs_inodes_free_eofblocks() implements scanning functionality for
EOFBLOCKS inodes. It uses the AG iterator to walk the tagged inodes
and free post-EOF blocks via the xfs_inode_free_eofblocks() execute
function. The scan can be invoked in best-effort mode or wait
(force) mode.
A best-effort scan (default) handles all inodes that do not have a
dirty cache and we successfully acquire the io lock via trylock. In
wait mode, we continue to cycle through an AG until all inodes are
handled.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely<tinguely@sgi.com>
---
fs/xfs/xfs_icache.c | 43 +++++++++++++++++++++++++++++++++++++++++++
fs/xfs/xfs_icache.h | 1 +
fs/xfs/xfs_trace.h | 1 +
3 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 878eb24..b02a3df 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1170,6 +1170,49 @@ xfs_reclaim_inodes_count(
return reclaimable;
}
+STATIC int
+xfs_inode_free_eofblocks(
+ struct xfs_inode *ip,
+ struct xfs_perag *pag,
+ int flags,
+ void *args)
+{
+ int ret;
+
+ if (!xfs_can_free_eofblocks(ip, false)) {
+ /* inode could be preallocated or append-only */
+ trace_xfs_inode_free_eofblocks_invalid(ip);
+ xfs_inode_clear_eofblocks_tag(ip);
+ return 0;
+ }
+
+ /*
+ * If the mapping is dirty the operation can block and wait for some
+ * time. Unless we are waiting, skip it.
+ */
+ if (!(flags & SYNC_WAIT) &&
+ mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY))
+ return 0;
+
+ ret = xfs_free_eofblocks(ip->i_mount, ip, true);
+
+ /* don't revisit the inode if we're not waiting */
+ if (ret == EAGAIN && !(flags & SYNC_WAIT))
+ ret = 0;
+
+ return ret;
+}
+
+int
+xfs_icache_free_eofblocks(
+ struct xfs_mount *mp,
+ int flags)
+{
+ ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0);
+ return xfs_inode_ag_iterator_tag(mp, xfs_inode_free_eofblocks, flags,
+ NULL, XFS_ICI_EOFBLOCKS_TAG);
+}
+
void
xfs_inode_set_eofblocks_tag(
xfs_inode_t *ip)
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index bb80237..abca9fb 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -37,6 +37,7 @@ void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip);
void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
+int xfs_icache_free_eofblocks(struct xfs_mount *, int);
int xfs_sync_inode_grab(struct xfs_inode *ip);
int xfs_inode_ag_iterator(struct xfs_mount *mp,
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 6f46e03..cb52346 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -589,6 +589,7 @@ DEFINE_INODE_EVENT(xfs_dquot_dqdetach);
DEFINE_INODE_EVENT(xfs_inode_set_eofblocks_tag);
DEFINE_INODE_EVENT(xfs_inode_clear_eofblocks_tag);
+DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid);
DECLARE_EVENT_CLASS(xfs_iref_class,
TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip),
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v6 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
` (4 preceding siblings ...)
2012-11-06 14:50 ` [PATCH v6 05/10] xfs: create function to scan and clear EOFBLOCKS inodes Brian Foster
@ 2012-11-06 14:50 ` Brian Foster
2012-11-06 16:44 ` Mark Tinguely
2012-11-06 22:11 ` Dave Chinner
2012-11-06 14:50 ` [PATCH v6 07/10] xfs: add inode id filtering to eofblocks scan Brian Foster
` (5 subsequent siblings)
11 siblings, 2 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 14:50 UTC (permalink / raw)
To: xfs
The XFS_IOC_FREE_EOFBLOCKS ioctl allows users to invoke an EOFBLOCKS
scan. The xfs_eofblocks structure is defined to support the command
parameters (scan mode).
Signed-off-by: Brian Foster <bfoster@redhat.com>
---
fs/xfs/xfs_fs.h | 17 +++++++++++++++++
fs/xfs/xfs_icache.c | 10 +++++++---
fs/xfs/xfs_icache.h | 2 +-
fs/xfs/xfs_ioctl.c | 20 ++++++++++++++++++++
4 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index c13fed8..26ff43a 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -339,6 +339,22 @@ typedef struct xfs_error_injection {
/*
+ * Speculative preallocation trimming.
+ */
+#define XFS_EOFBLOCKS_VERSION 1
+struct xfs_eofblocks {
+ __u32 eof_version;
+ __u32 eof_flags;
+ __u64 pad[15];
+};
+
+/* eof_flags values */
+#define XFS_EOF_FLAGS_SYNC (1 << 0) /* sync/wait mode scan */
+#define XFS_EOF_FLAGS_VALID \
+ (XFS_EOF_FLAGS_SYNC)
+
+
+/*
* The user-level Handle Request interface structure.
*/
typedef struct xfs_fsop_handlereq {
@@ -456,6 +472,7 @@ typedef struct xfs_handle {
/* XFS_IOC_GETBIOSIZE ---- deprecated 47 */
#define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap)
#define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64)
+#define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_eofblocks)
/*
* ioctl commands that replace IRIX syssgi()'s
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index b02a3df..d0d9273 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1206,11 +1206,15 @@ xfs_inode_free_eofblocks(
int
xfs_icache_free_eofblocks(
struct xfs_mount *mp,
- int flags)
+ struct xfs_eofblocks *eofb)
{
- ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0);
+ int flags = SYNC_TRYLOCK;
+
+ if (eofb && eofb->eof_flags & XFS_EOF_FLAGS_SYNC)
+ flags = SYNC_WAIT;
+
return xfs_inode_ag_iterator_tag(mp, xfs_inode_free_eofblocks, flags,
- NULL, XFS_ICI_EOFBLOCKS_TAG);
+ eofb, XFS_ICI_EOFBLOCKS_TAG);
}
void
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index abca9fb..23e9bf3 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -37,7 +37,7 @@ void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip);
void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
-int xfs_icache_free_eofblocks(struct xfs_mount *, int);
+int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_eofblocks *);
int xfs_sync_inode_grab(struct xfs_inode *ip);
int xfs_inode_ag_iterator(struct xfs_mount *mp,
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index c1df3c6..5b20ab0 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -42,6 +42,7 @@
#include "xfs_inode_item.h"
#include "xfs_export.h"
#include "xfs_trace.h"
+#include "xfs_icache.h"
#include <linux/capability.h>
#include <linux/dcache.h>
@@ -1602,6 +1603,25 @@ xfs_file_ioctl(
error = xfs_errortag_clearall(mp, 1);
return -error;
+ case XFS_IOC_FREE_EOFBLOCKS: {
+ struct xfs_eofblocks eofb;
+
+ if (copy_from_user(&eofb, arg, sizeof(eofb)))
+ return -XFS_ERROR(EFAULT);
+
+ if (eofb.eof_version != XFS_EOFBLOCKS_VERSION)
+ return -XFS_ERROR(EINVAL);
+
+ if (eofb.eof_flags & ~XFS_EOF_FLAGS_VALID)
+ return -XFS_ERROR(EINVAL);
+
+ if (memchr_inv(eofb.pad, 0, sizeof(eofb.pad)))
+ return -XFS_ERROR(EINVAL);
+
+ error = xfs_icache_free_eofblocks(mp, &eofb);
+ return -error;
+ }
+
default:
return -ENOTTY;
}
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v6 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
2012-11-06 14:50 ` [PATCH v6 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl Brian Foster
@ 2012-11-06 16:44 ` Mark Tinguely
2012-11-06 22:11 ` Dave Chinner
1 sibling, 0 replies; 32+ messages in thread
From: Mark Tinguely @ 2012-11-06 16:44 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
On 11/06/12 08:50, Brian Foster wrote:
> The XFS_IOC_FREE_EOFBLOCKS ioctl allows users to invoke an EOFBLOCKS
> scan. The xfs_eofblocks structure is defined to support the command
> parameters (scan mode).
>
> Signed-off-by: Brian Foster<bfoster@redhat.com>
> ---
Looks good.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v6 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
2012-11-06 14:50 ` [PATCH v6 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl Brian Foster
2012-11-06 16:44 ` Mark Tinguely
@ 2012-11-06 22:11 ` Dave Chinner
1 sibling, 0 replies; 32+ messages in thread
From: Dave Chinner @ 2012-11-06 22:11 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
On Tue, Nov 06, 2012 at 09:50:43AM -0500, Brian Foster wrote:
> The XFS_IOC_FREE_EOFBLOCKS ioctl allows users to invoke an EOFBLOCKS
> scan. The xfs_eofblocks structure is defined to support the command
> parameters (scan mode).
>
> Signed-off-by: Brian Foster <bfoster@redhat.com>
> ---
> fs/xfs/xfs_fs.h | 17 +++++++++++++++++
> fs/xfs/xfs_icache.c | 10 +++++++---
> fs/xfs/xfs_icache.h | 2 +-
> fs/xfs/xfs_ioctl.c | 20 ++++++++++++++++++++
> 4 files changed, 45 insertions(+), 4 deletions(-)
>
> diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
> index c13fed8..26ff43a 100644
> --- a/fs/xfs/xfs_fs.h
> +++ b/fs/xfs/xfs_fs.h
> @@ -339,6 +339,22 @@ typedef struct xfs_error_injection {
>
>
> /*
> + * Speculative preallocation trimming.
> + */
> +#define XFS_EOFBLOCKS_VERSION 1
> +struct xfs_eofblocks {
> + __u32 eof_version;
> + __u32 eof_flags;
> + __u64 pad[15];
> +};
> +
> +/* eof_flags values */
> +#define XFS_EOF_FLAGS_SYNC (1 << 0) /* sync/wait mode scan */
> +#define XFS_EOF_FLAGS_VALID \
> + (XFS_EOF_FLAGS_SYNC)
> +
> +
> +/*
> * The user-level Handle Request interface structure.
> */
> typedef struct xfs_fsop_handlereq {
> @@ -456,6 +472,7 @@ typedef struct xfs_handle {
> /* XFS_IOC_GETBIOSIZE ---- deprecated 47 */
> #define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap)
> #define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64)
> +#define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_eofblocks)
>
> /*
> * ioctl commands that replace IRIX syssgi()'s
> diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
> index b02a3df..d0d9273 100644
> --- a/fs/xfs/xfs_icache.c
> +++ b/fs/xfs/xfs_icache.c
> @@ -1206,11 +1206,15 @@ xfs_inode_free_eofblocks(
> int
> xfs_icache_free_eofblocks(
> struct xfs_mount *mp,
> - int flags)
> + struct xfs_eofblocks *eofb)
> {
> - ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0);
> + int flags = SYNC_TRYLOCK;
> +
> + if (eofb && eofb->eof_flags & XFS_EOF_FLAGS_SYNC)
gcc will throw a warning about that.
if (eofb && (eofb->eof_flags & XFS_EOF_FLAGS_SYNC))
Apart from that, looks good.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v6 07/10] xfs: add inode id filtering to eofblocks scan
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
` (5 preceding siblings ...)
2012-11-06 14:50 ` [PATCH v6 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl Brian Foster
@ 2012-11-06 14:50 ` Brian Foster
2012-11-06 16:41 ` Mark Tinguely
2012-11-06 22:17 ` Dave Chinner
2012-11-06 14:50 ` [PATCH v6 08/10] xfs: support multiple inode id filtering in " Brian Foster
` (4 subsequent siblings)
11 siblings, 2 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 14:50 UTC (permalink / raw)
To: xfs
Support inode ID filtering in the eofblocks scan. The caller must
set the associated XFS_EOF_FLAGS_*ID bit and ID field.
Signed-off-by: Brian Foster <bfoster@redhat.com>
---
fs/xfs/xfs_fs.h | 11 +++++++++--
fs/xfs/xfs_icache.c | 22 ++++++++++++++++++++++
2 files changed, 31 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 26ff43a..88eb1bc 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -345,13 +345,20 @@ typedef struct xfs_error_injection {
struct xfs_eofblocks {
__u32 eof_version;
__u32 eof_flags;
- __u64 pad[15];
+ uid_t eof_uid;
+ gid_t eof_gid;
+ prid_t eof_prid;
+ __u32 pad[27];
};
/* eof_flags values */
#define XFS_EOF_FLAGS_SYNC (1 << 0) /* sync/wait mode scan */
+#define XFS_EOF_FLAGS_UID (1 << 1) /* filter by uid */
+#define XFS_EOF_FLAGS_GID (1 << 2) /* filter by gid */
+#define XFS_EOF_FLAGS_PRID (1 << 3) /* filter by project id */
#define XFS_EOF_FLAGS_VALID \
- (XFS_EOF_FLAGS_SYNC)
+ (XFS_EOF_FLAGS_SYNC|XFS_EOF_FLAGS_UID|XFS_EOF_FLAGS_GID| \
+ XFS_EOF_FLAGS_PRID)
/*
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index d0d9273..699d1b0 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1171,6 +1171,21 @@ xfs_reclaim_inodes_count(
}
STATIC int
+xfs_inode_match_id(
+ struct xfs_inode *ip,
+ struct xfs_eofblocks *eofb)
+{
+ if (eofb->eof_flags & XFS_EOF_FLAGS_UID)
+ return ip->i_d.di_uid == eofb->eof_uid;
+ else if (eofb->eof_flags & XFS_EOF_FLAGS_GID)
+ return ip->i_d.di_gid == eofb->eof_gid;
+ else if (eofb->eof_flags & XFS_EOF_FLAGS_PRID)
+ return xfs_get_projid(ip) == eofb->eof_prid;
+
+ return 0;
+}
+
+STATIC int
xfs_inode_free_eofblocks(
struct xfs_inode *ip,
struct xfs_perag *pag,
@@ -1178,6 +1193,7 @@ xfs_inode_free_eofblocks(
void *args)
{
int ret;
+ struct xfs_eofblocks *eofb = args;
if (!xfs_can_free_eofblocks(ip, false)) {
/* inode could be preallocated or append-only */
@@ -1194,6 +1210,12 @@ xfs_inode_free_eofblocks(
mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY))
return 0;
+ if (eofb &&
+ (eofb->eof_flags & (XFS_EOF_FLAGS_UID|XFS_EOF_FLAGS_GID|
+ XFS_EOF_FLAGS_PRID)) &&
+ !xfs_inode_match_id(ip, eofb))
+ return 0;
+
ret = xfs_free_eofblocks(ip->i_mount, ip, true);
/* don't revisit the inode if we're not waiting */
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v6 07/10] xfs: add inode id filtering to eofblocks scan
2012-11-06 14:50 ` [PATCH v6 07/10] xfs: add inode id filtering to eofblocks scan Brian Foster
@ 2012-11-06 16:41 ` Mark Tinguely
2012-11-06 17:57 ` Brian Foster
2012-11-06 22:17 ` Dave Chinner
1 sibling, 1 reply; 32+ messages in thread
From: Mark Tinguely @ 2012-11-06 16:41 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
On 11/06/12 08:50, Brian Foster wrote:
> Support inode ID filtering in the eofblocks scan. The caller must
> set the associated XFS_EOF_FLAGS_*ID bit and ID field.
>
> Signed-off-by: Brian Foster<bfoster@redhat.com>
> ---
turn 0;
>
> + if (eofb&&
vvvvvvv
> + (eofb->eof_flags& (XFS_EOF_FLAGS_UID|XFS_EOF_FLAGS_GID|
> + XFS_EOF_FLAGS_PRID))&&
^^^^^^
Not a big deal but wouldn't xfs_inode_match_id() also check these flags?
> + !xfs_inode_match_id(ip, eofb))
> + return 0;
> +
Consider this
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v6 07/10] xfs: add inode id filtering to eofblocks scan
2012-11-06 16:41 ` Mark Tinguely
@ 2012-11-06 17:57 ` Brian Foster
0 siblings, 0 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 17:57 UTC (permalink / raw)
To: Mark Tinguely; +Cc: xfs
On 11/06/2012 11:41 AM, Mark Tinguely wrote:
> On 11/06/12 08:50, Brian Foster wrote:
>> Support inode ID filtering in the eofblocks scan. The caller must
>> set the associated XFS_EOF_FLAGS_*ID bit and ID field.
>>
>> Signed-off-by: Brian Foster<bfoster@redhat.com>
>> ---
>
> turn 0;
>>
>> + if (eofb&&
>
> vvvvvvv
>> + (eofb->eof_flags& (XFS_EOF_FLAGS_UID|XFS_EOF_FLAGS_GID|
>> + XFS_EOF_FLAGS_PRID))&&
> ^^^^^^
> Not a big deal but wouldn't xfs_inode_match_id() also check these flags?
>
Yes it does, but at this point in the patch xfs_inode_match_id() is
implemented in an opt-in way that would alter the codepath (i.e., it
would always return 0 if no ID flags were specified and skip every inode).
I thought about defining another directive to combine the ID flags and
clean that up a bit, but as you probably noticed, the following patch
reimplements xfs_inode_match_id() such that it opts-out inodes and
allows this check in xfs_inode_free_eofblocks() to go away.
Brian
>> + !xfs_inode_match_id(ip, eofb))
>> + return 0;
>> +
>
>
> Consider this
>
> Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v6 07/10] xfs: add inode id filtering to eofblocks scan
2012-11-06 14:50 ` [PATCH v6 07/10] xfs: add inode id filtering to eofblocks scan Brian Foster
2012-11-06 16:41 ` Mark Tinguely
@ 2012-11-06 22:17 ` Dave Chinner
1 sibling, 0 replies; 32+ messages in thread
From: Dave Chinner @ 2012-11-06 22:17 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
On Tue, Nov 06, 2012 at 09:50:44AM -0500, Brian Foster wrote:
> Support inode ID filtering in the eofblocks scan. The caller must
> set the associated XFS_EOF_FLAGS_*ID bit and ID field.
>
> Signed-off-by: Brian Foster <bfoster@redhat.com>
> ---
> fs/xfs/xfs_fs.h | 11 +++++++++--
> fs/xfs/xfs_icache.c | 22 ++++++++++++++++++++++
> 2 files changed, 31 insertions(+), 2 deletions(-)
>
> diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
> index 26ff43a..88eb1bc 100644
> --- a/fs/xfs/xfs_fs.h
> +++ b/fs/xfs/xfs_fs.h
> @@ -345,13 +345,20 @@ typedef struct xfs_error_injection {
> struct xfs_eofblocks {
> __u32 eof_version;
> __u32 eof_flags;
> - __u64 pad[15];
> + uid_t eof_uid;
> + gid_t eof_gid;
> + prid_t eof_prid;
> + __u32 pad[27];
> };
The typical way of doing this to ensure that the structure remains
the same size and people are aware of alignment issues is this:
- __u64 pad[15];
+ uid_t eof_uid;
+ gid_t eof_gid;
+ prid_t eof_prid;
+ __u32 pad32;
+ __u64 pad64[13];
That way it is clear that we need pad out to 8 byte boundaries even
on 32 bit systems.
>
> /* eof_flags values */
> #define XFS_EOF_FLAGS_SYNC (1 << 0) /* sync/wait mode scan */
> +#define XFS_EOF_FLAGS_UID (1 << 1) /* filter by uid */
> +#define XFS_EOF_FLAGS_GID (1 << 2) /* filter by gid */
> +#define XFS_EOF_FLAGS_PRID (1 << 3) /* filter by project id */
> #define XFS_EOF_FLAGS_VALID \
> - (XFS_EOF_FLAGS_SYNC)
> + (XFS_EOF_FLAGS_SYNC|XFS_EOF_FLAGS_UID|XFS_EOF_FLAGS_GID| \
> + XFS_EOF_FLAGS_PRID)
A little bit of white space goes a long way:
#define XFS_EOF_FLAGS_VALID \
(XFS_EOF_FLAGS_SYNC | \
XFS_EOF_FLAGS_UID | \
XFS_EOF_FLAGS_GID | \
XFS_EOF_FLAGS_PRID)
Is much easier to read and extend in future.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v6 08/10] xfs: support multiple inode id filtering in eofblocks scan
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
` (6 preceding siblings ...)
2012-11-06 14:50 ` [PATCH v6 07/10] xfs: add inode id filtering to eofblocks scan Brian Foster
@ 2012-11-06 14:50 ` Brian Foster
2012-11-06 16:48 ` Mark Tinguely
2012-11-06 22:20 ` Dave Chinner
2012-11-06 14:50 ` [PATCH v6 09/10] xfs: add minimum file size filtering to " Brian Foster
` (3 subsequent siblings)
11 siblings, 2 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 14:50 UTC (permalink / raw)
To: xfs
Enhance the eofblocks scan code to filter based on multiply specified
inode id values. When multiple inode id values are specified, only
inodes that match all id values are selected.
Signed-off-by: Brian Foster <bfoster@redhat.com>
---
fs/xfs/xfs_icache.c | 24 +++++++++++++-----------
1 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 699d1b0..d7372b1 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1175,14 +1175,19 @@ xfs_inode_match_id(
struct xfs_inode *ip,
struct xfs_eofblocks *eofb)
{
- if (eofb->eof_flags & XFS_EOF_FLAGS_UID)
- return ip->i_d.di_uid == eofb->eof_uid;
- else if (eofb->eof_flags & XFS_EOF_FLAGS_GID)
- return ip->i_d.di_gid == eofb->eof_gid;
- else if (eofb->eof_flags & XFS_EOF_FLAGS_PRID)
- return xfs_get_projid(ip) == eofb->eof_prid;
+ if (eofb->eof_flags & XFS_EOF_FLAGS_UID &&
+ ip->i_d.di_uid != eofb->eof_uid)
+ return 0;
- return 0;
+ if (eofb->eof_flags & XFS_EOF_FLAGS_GID &&
+ ip->i_d.di_gid != eofb->eof_gid)
+ return 0;
+
+ if (eofb->eof_flags & XFS_EOF_FLAGS_PRID &&
+ xfs_get_projid(ip) != eofb->eof_prid)
+ return 0;
+
+ return 1;
}
STATIC int
@@ -1210,10 +1215,7 @@ xfs_inode_free_eofblocks(
mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY))
return 0;
- if (eofb &&
- (eofb->eof_flags & (XFS_EOF_FLAGS_UID|XFS_EOF_FLAGS_GID|
- XFS_EOF_FLAGS_PRID)) &&
- !xfs_inode_match_id(ip, eofb))
+ if (eofb && !xfs_inode_match_id(ip, eofb))
return 0;
ret = xfs_free_eofblocks(ip->i_mount, ip, true);
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v6 09/10] xfs: add minimum file size filtering to eofblocks scan
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
` (7 preceding siblings ...)
2012-11-06 14:50 ` [PATCH v6 08/10] xfs: support multiple inode id filtering in " Brian Foster
@ 2012-11-06 14:50 ` Brian Foster
2012-11-06 16:57 ` Mark Tinguely
2012-11-06 22:25 ` Dave Chinner
2012-11-06 14:50 ` [PATCH v6 10/10] xfs: add background scanning to clear eofblocks inodes Brian Foster
` (2 subsequent siblings)
11 siblings, 2 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 14:50 UTC (permalink / raw)
To: xfs
Support minimum file size filtering in the eofblocks scan. The
caller must set the XFS_EOF_FLAGS_MINFILESIZE flags bit and minimum
file size value in bytes.
Signed-off-by: Brian Foster <bfoster@redhat.com>
---
fs/xfs/xfs_fs.h | 6 ++++--
fs/xfs/xfs_icache.c | 11 +++++++++--
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 88eb1bc..082b743 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -348,7 +348,8 @@ struct xfs_eofblocks {
uid_t eof_uid;
gid_t eof_gid;
prid_t eof_prid;
- __u32 pad[27];
+ __u64 eof_min_file_size;
+ __u32 pad[25];
};
/* eof_flags values */
@@ -356,9 +357,10 @@ struct xfs_eofblocks {
#define XFS_EOF_FLAGS_UID (1 << 1) /* filter by uid */
#define XFS_EOF_FLAGS_GID (1 << 2) /* filter by gid */
#define XFS_EOF_FLAGS_PRID (1 << 3) /* filter by project id */
+#define XFS_EOF_FLAGS_MINFILESIZE (1 << 4) /* filter by min file size */
#define XFS_EOF_FLAGS_VALID \
(XFS_EOF_FLAGS_SYNC|XFS_EOF_FLAGS_UID|XFS_EOF_FLAGS_GID| \
- XFS_EOF_FLAGS_PRID)
+ XFS_EOF_FLAGS_PRID|XFS_EOF_FLAGS_MINFILESIZE)
/*
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index d7372b1..6e63228 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1215,8 +1215,15 @@ xfs_inode_free_eofblocks(
mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY))
return 0;
- if (eofb && !xfs_inode_match_id(ip, eofb))
- return 0;
+ if (eofb) {
+ if (!xfs_inode_match_id(ip, eofb))
+ return 0;
+
+ /* skip the inode if the file size is too small */
+ if (eofb->eof_flags & XFS_EOF_FLAGS_MINFILESIZE &&
+ XFS_ISIZE(ip) < eofb->eof_min_file_size)
+ return 0;
+ }
ret = xfs_free_eofblocks(ip->i_mount, ip, true);
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v6 09/10] xfs: add minimum file size filtering to eofblocks scan
2012-11-06 14:50 ` [PATCH v6 09/10] xfs: add minimum file size filtering to " Brian Foster
@ 2012-11-06 16:57 ` Mark Tinguely
2012-11-06 17:08 ` Roger Willcocks
2012-11-06 22:25 ` Dave Chinner
1 sibling, 1 reply; 32+ messages in thread
From: Mark Tinguely @ 2012-11-06 16:57 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
On 11/06/12 08:50, Brian Foster wrote:
> Support minimum file size filtering in the eofblocks scan. The
> caller must set the XFS_EOF_FLAGS_MINFILESIZE flags bit and minimum
> file size value in bytes.
>
> Signed-off-by: Brian Foster<bfoster@redhat.com>
> ---
> fs/xfs/xfs_fs.h | 6 ++++--
> fs/xfs/xfs_icache.c | 11 +++++++++--
> 2 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
> index 88eb1bc..082b743 100644
> --- a/fs/xfs/xfs_fs.h
> +++ b/fs/xfs/xfs_fs.h
> @@ -348,7 +348,8 @@ struct xfs_eofblocks {
> uid_t eof_uid;
> gid_t eof_gid;
> prid_t eof_prid;
> - __u32 pad[27];
> + __u64 eof_min_file_size;
> + __u32 pad[25]
^^
Glad you bumped it to a unsigned 64 bit value.
Are __u64 items 64 bits? if so, the pad would be 24
> };
>
Looks good.
Reviewed-by: Mark Tinguely <tinguely@sgi.com?
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v6 09/10] xfs: add minimum file size filtering to eofblocks scan
2012-11-06 16:57 ` Mark Tinguely
@ 2012-11-06 17:08 ` Roger Willcocks
2012-11-06 18:00 ` Brian Foster
0 siblings, 1 reply; 32+ messages in thread
From: Roger Willcocks @ 2012-11-06 17:08 UTC (permalink / raw)
To: Mark Tinguely; +Cc: Brian Foster, xfs
On Tue, 2012-11-06 at 10:57 -0600, Mark Tinguely wrote:
> On 11/06/12 08:50, Brian Foster wrote:
> > Support minimum file size filtering in the eofblocks scan. The
> > caller must set the XFS_EOF_FLAGS_MINFILESIZE flags bit and minimum
> > file size value in bytes.
> >
> > Signed-off-by: Brian Foster<bfoster@redhat.com>
> > ---
> > fs/xfs/xfs_fs.h | 6 ++++--
> > fs/xfs/xfs_icache.c | 11 +++++++++--
> > 2 files changed, 13 insertions(+), 4 deletions(-)
> >
> > diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
> > index 88eb1bc..082b743 100644
> > --- a/fs/xfs/xfs_fs.h
> > +++ b/fs/xfs/xfs_fs.h
> > @@ -348,7 +348,8 @@ struct xfs_eofblocks {
> > uid_t eof_uid;
> > gid_t eof_gid;
> > prid_t eof_prid;
> > - __u32 pad[27];
> > + __u64 eof_min_file_size;
> > + __u32 pad[25]
> ^^
> Glad you bumped it to a unsigned 64 bit value.
> Are __u64 items 64 bits? if so, the pad would be 24
>
It should probably be:
__u32 pad_align_64;
__u64 eof_min_file_size;
__u32 pad[24];
> > };
> >
>
> Looks good.
>
> Reviewed-by: Mark Tinguely <tinguely@sgi.com?
>
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
>
--
Roger Willcocks <roger@filmlight.ltd.uk>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v6 09/10] xfs: add minimum file size filtering to eofblocks scan
2012-11-06 17:08 ` Roger Willcocks
@ 2012-11-06 18:00 ` Brian Foster
2012-11-06 19:23 ` Mark Tinguely
0 siblings, 1 reply; 32+ messages in thread
From: Brian Foster @ 2012-11-06 18:00 UTC (permalink / raw)
To: Roger Willcocks; +Cc: Mark Tinguely, xfs
On 11/06/2012 12:08 PM, Roger Willcocks wrote:
>
> On Tue, 2012-11-06 at 10:57 -0600, Mark Tinguely wrote:
>> On 11/06/12 08:50, Brian Foster wrote:
>>> Support minimum file size filtering in the eofblocks scan. The
>>> caller must set the XFS_EOF_FLAGS_MINFILESIZE flags bit and minimum
>>> file size value in bytes.
>>>
>>> Signed-off-by: Brian Foster<bfoster@redhat.com>
>>> ---
>>> fs/xfs/xfs_fs.h | 6 ++++--
>>> fs/xfs/xfs_icache.c | 11 +++++++++--
>>> 2 files changed, 13 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
>>> index 88eb1bc..082b743 100644
>>> --- a/fs/xfs/xfs_fs.h
>>> +++ b/fs/xfs/xfs_fs.h
>>> @@ -348,7 +348,8 @@ struct xfs_eofblocks {
>>> uid_t eof_uid;
>>> gid_t eof_gid;
>>> prid_t eof_prid;
>>> - __u32 pad[27];
>>> + __u64 eof_min_file_size;
>>> + __u32 pad[25]
>> ^^
>> Glad you bumped it to a unsigned 64 bit value.
>> Are __u64 items 64 bits? if so, the pad would be 24
>>
>
> It should probably be:
>
> __u32 pad_align_64;
> __u64 eof_min_file_size;
> __u32 pad[24];
>
Doh... forgot about alignment. Thanks for catching that guys.
The new pad_align field means I have to fix up the padded zero check as
well, which makes me wonder if I should reorder things now or actually
split more of the padding space into two (__u32/__u64, rather than
mistakenly converting to a __u32 like I've done here) fields to support
extending the data structure with fields of either size without having
to update the version. E.g., we end up with something like the following:
struct xfs_eofblocks {
__u32 version;
__u32 flags;
uid_t uid;
gid_t gid;
prid_t prid;
__u32 pad32[9];
__u64 minfilesize;
__u64 pad64[8];
};
Thoughts?
Brian
>
>>> };
>>>
>>
>> Looks good.
>>
>> Reviewed-by: Mark Tinguely <tinguely@sgi.com?
>>
>> _______________________________________________
>> xfs mailing list
>> xfs@oss.sgi.com
>> http://oss.sgi.com/mailman/listinfo/xfs
>>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v6 09/10] xfs: add minimum file size filtering to eofblocks scan
2012-11-06 18:00 ` Brian Foster
@ 2012-11-06 19:23 ` Mark Tinguely
2012-11-06 22:29 ` Dave Chinner
0 siblings, 1 reply; 32+ messages in thread
From: Mark Tinguely @ 2012-11-06 19:23 UTC (permalink / raw)
To: Brian Foster; +Cc: Roger Willcocks, xfs
On 11/06/12 12:00, Brian Foster wrote:
> On 11/06/2012 12:08 PM, Roger Willcocks wrote:
>>
>> On Tue, 2012-11-06 at 10:57 -0600, Mark Tinguely wrote:
>>> On 11/06/12 08:50, Brian Foster wrote:
>>>> Support minimum file size filtering in the eofblocks scan. The
>>>> caller must set the XFS_EOF_FLAGS_MINFILESIZE flags bit and minimum
>>>> file size value in bytes.
>>>>
>>>> Signed-off-by: Brian Foster<bfoster@redhat.com>
>>>> ---
>>>> fs/xfs/xfs_fs.h | 6 ++++--
>>>> fs/xfs/xfs_icache.c | 11 +++++++++--
>>>> 2 files changed, 13 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
>>>> index 88eb1bc..082b743 100644
>>>> --- a/fs/xfs/xfs_fs.h
>>>> +++ b/fs/xfs/xfs_fs.h
>>>> @@ -348,7 +348,8 @@ struct xfs_eofblocks {
>>>> uid_t eof_uid;
>>>> gid_t eof_gid;
>>>> prid_t eof_prid;
>>>> - __u32 pad[27];
>>>> + __u64 eof_min_file_size;
>>>> + __u32 pad[25]
>>> ^^
>>> Glad you bumped it to a unsigned 64 bit value.
>>> Are __u64 items 64 bits? if so, the pad would be 24
>>>
>>
>> It should probably be:
>>
>> __u32 pad_align_64;
>> __u64 eof_min_file_size;
>> __u32 pad[24];
>>
>
> Doh... forgot about alignment. Thanks for catching that guys.
>
> The new pad_align field means I have to fix up the padded zero check as
> well, which makes me wonder if I should reorder things now or actually
> split more of the padding space into two (__u32/__u64, rather than
> mistakenly converting to a __u32 like I've done here) fields to support
> extending the data structure with fields of either size without having
> to update the version. E.g., we end up with something like the following:
>
> struct xfs_eofblocks {
> __u32 version;
> __u32 flags;
> uid_t uid;
> gid_t gid;
> prid_t prid;
> __u32 pad32[9];
> __u64 minfilesize;
> __u64 pad64[8];
> };
>
> Thoughts?
>
> Brian
>
I vote to keep the padding continuous at the end of the series
and the padding check simple:
struct xfs_eofblocks {
__u32 version;
__u32 flags;
__u64 minfilesize;
uid_t uid;
gid_t gid;
prid_t prid;
__u32 pad32[25];
}
--Mark.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread* Re: [PATCH v6 09/10] xfs: add minimum file size filtering to eofblocks scan
2012-11-06 19:23 ` Mark Tinguely
@ 2012-11-06 22:29 ` Dave Chinner
0 siblings, 0 replies; 32+ messages in thread
From: Dave Chinner @ 2012-11-06 22:29 UTC (permalink / raw)
To: Mark Tinguely; +Cc: Brian Foster, Roger Willcocks, xfs
On Tue, Nov 06, 2012 at 01:23:40PM -0600, Mark Tinguely wrote:
> On 11/06/12 12:00, Brian Foster wrote:
> >On 11/06/2012 12:08 PM, Roger Willcocks wrote:
> >>
> >>On Tue, 2012-11-06 at 10:57 -0600, Mark Tinguely wrote:
> >>>On 11/06/12 08:50, Brian Foster wrote:
> >>>>Support minimum file size filtering in the eofblocks scan. The
> >>>>caller must set the XFS_EOF_FLAGS_MINFILESIZE flags bit and minimum
> >>>>file size value in bytes.
> >>>>
> >>>>Signed-off-by: Brian Foster<bfoster@redhat.com>
> >>>>---
> >>>> fs/xfs/xfs_fs.h | 6 ++++--
> >>>> fs/xfs/xfs_icache.c | 11 +++++++++--
> >>>> 2 files changed, 13 insertions(+), 4 deletions(-)
> >>>>
> >>>>diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
> >>>>index 88eb1bc..082b743 100644
> >>>>--- a/fs/xfs/xfs_fs.h
> >>>>+++ b/fs/xfs/xfs_fs.h
> >>>>@@ -348,7 +348,8 @@ struct xfs_eofblocks {
> >>>> uid_t eof_uid;
> >>>> gid_t eof_gid;
> >>>> prid_t eof_prid;
> >>>>- __u32 pad[27];
> >>>>+ __u64 eof_min_file_size;
> >>>>+ __u32 pad[25]
> >>> ^^
> >>>Glad you bumped it to a unsigned 64 bit value.
> >>>Are __u64 items 64 bits? if so, the pad would be 24
> >>>
> >>
> >>It should probably be:
> >>
> >>__u32 pad_align_64;
> >>__u64 eof_min_file_size;
> >>__u32 pad[24];
> >>
> >
> >Doh... forgot about alignment. Thanks for catching that guys.
> >
> >The new pad_align field means I have to fix up the padded zero check as
> >well, which makes me wonder if I should reorder things now or actually
> >split more of the padding space into two (__u32/__u64, rather than
> >mistakenly converting to a __u32 like I've done here) fields to support
> >extending the data structure with fields of either size without having
> >to update the version. E.g., we end up with something like the following:
> >
> >struct xfs_eofblocks {
> > __u32 version;
> > __u32 flags;
> > uid_t uid;
> > gid_t gid;
> > prid_t prid;
> > __u32 pad32[9];
> > __u64 minfilesize;
> > __u64 pad64[8];
> >};
Just pad the 32 bit hole. If someone is adding an odd number of 32
bit variables later, they can fill the hole, otherwise is can remain
there until we add an odd number of 32 bit variables.
> I vote to keep the padding continuous at the end of the series
> and the padding check simple:
>
> struct xfs_eofblocks {
> __u32 version;
> __u32 flags;
> __u64 minfilesize;
> uid_t uid;
> gid_t gid;
> prid_t prid;
> __u32 pad32[25];
That just leaves us open to exactly the same mistake - there's
no indication that alignment and padding holes explicitly might
be important for this structure.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v6 09/10] xfs: add minimum file size filtering to eofblocks scan
2012-11-06 14:50 ` [PATCH v6 09/10] xfs: add minimum file size filtering to " Brian Foster
2012-11-06 16:57 ` Mark Tinguely
@ 2012-11-06 22:25 ` Dave Chinner
1 sibling, 0 replies; 32+ messages in thread
From: Dave Chinner @ 2012-11-06 22:25 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
On Tue, Nov 06, 2012 at 09:50:46AM -0500, Brian Foster wrote:
> Support minimum file size filtering in the eofblocks scan. The
> caller must set the XFS_EOF_FLAGS_MINFILESIZE flags bit and minimum
> file size value in bytes.
>
> Signed-off-by: Brian Foster <bfoster@redhat.com>
> ---
> fs/xfs/xfs_fs.h | 6 ++++--
> fs/xfs/xfs_icache.c | 11 +++++++++--
> 2 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
> index 88eb1bc..082b743 100644
> --- a/fs/xfs/xfs_fs.h
> +++ b/fs/xfs/xfs_fs.h
> @@ -348,7 +348,8 @@ struct xfs_eofblocks {
> uid_t eof_uid;
> gid_t eof_gid;
> prid_t eof_prid;
> - __u32 pad[27];
> + __u64 eof_min_file_size;
> + __u32 pad[25];
And that's an exact example of why you should pad out to 8 byte
boundaries like I suggested earlier ;)
What this ends up with is:
prid eof_prid;
<implicit, arch dependent 4 byte hole>
__u64 eof_min_file_size;
__32 pad[25];
What you should have is something like:
prid eof_prid;
__u32 pad32;
__u64 eof_min_file_size;
__u64 pad64[12];
You should check the way the compiler sees the user visible
structures with pahole - it shows up problems like this in an
obvious manner ;)
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v6 10/10] xfs: add background scanning to clear eofblocks inodes
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
` (8 preceding siblings ...)
2012-11-06 14:50 ` [PATCH v6 09/10] xfs: add minimum file size filtering to " Brian Foster
@ 2012-11-06 14:50 ` Brian Foster
2012-11-06 17:04 ` Mark Tinguely
2012-11-06 22:30 ` Dave Chinner
2012-11-07 17:21 ` [PATCH v7 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl Brian Foster
2012-11-08 22:38 ` [PATCH v6 00/10] speculative preallocation inode tracking Ben Myers
11 siblings, 2 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-06 14:50 UTC (permalink / raw)
To: xfs
Create a new mount workqueue and delayed_work to enable background
scanning and freeing of eofblocks inodes. The scanner kicks in once
speculative preallocation occurs and stops requeueing itself when
no eofblocks inodes exist.
The scan interval is based on the new
'speculative_prealloc_lifetime' tunable (default to 5m). The
background scanner performs unfiltered, best effort scans (which
skips inodes under lock contention or with a dirty cache mapping).
Signed-off-by: Brian Foster <bfoster@redhat.com>
---
fs/xfs/xfs_globals.c | 4 +++-
fs/xfs/xfs_icache.c | 29 +++++++++++++++++++++++++++++
fs/xfs/xfs_icache.h | 1 +
fs/xfs/xfs_linux.h | 1 +
fs/xfs/xfs_mount.c | 2 ++
fs/xfs/xfs_mount.h | 3 +++
fs/xfs/xfs_super.c | 9 +++++++++
fs/xfs/xfs_sysctl.c | 9 +++++++++
fs/xfs/xfs_sysctl.h | 1 +
9 files changed, 58 insertions(+), 1 deletions(-)
diff --git a/fs/xfs/xfs_globals.c b/fs/xfs/xfs_globals.c
index 76e81cf..5399ef2 100644
--- a/fs/xfs/xfs_globals.c
+++ b/fs/xfs/xfs_globals.c
@@ -21,7 +21,8 @@
/*
* Tunable XFS parameters. xfs_params is required even when CONFIG_SYSCTL=n,
* other XFS code uses these values. Times are measured in centisecs (i.e.
- * 100ths of a second).
+ * 100ths of a second) with the exception of eofb_timer, which is measured in
+ * seconds.
*/
xfs_param_t xfs_params = {
/* MIN DFLT MAX */
@@ -40,4 +41,5 @@ xfs_param_t xfs_params = {
.rotorstep = { 1, 1, 255 },
.inherit_nodfrg = { 0, 1, 1 },
.fstrm_timer = { 1, 30*100, 3600*100},
+ .eofb_timer = { 1, 300, 3600*24},
};
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 6e63228..509b85b 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -615,6 +615,32 @@ restart:
return last_error;
}
+/*
+ * Background scanning to trim post-EOF preallocated space. This is queued
+ * based on the 'background_prealloc_discard_period' tunable (5m by default).
+ */
+STATIC void
+xfs_queue_eofblocks(
+ struct xfs_mount *mp)
+{
+ rcu_read_lock();
+ if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_EOFBLOCKS_TAG))
+ queue_delayed_work(mp->m_eofblocks_workqueue,
+ &mp->m_eofblocks_work,
+ msecs_to_jiffies(xfs_eofb_secs * 1000));
+ rcu_read_unlock();
+}
+
+void
+xfs_eofblocks_worker(
+ struct work_struct *work)
+{
+ struct xfs_mount *mp = container_of(to_delayed_work(work),
+ struct xfs_mount, m_eofblocks_work);
+ xfs_icache_free_eofblocks(mp, NULL);
+ xfs_queue_eofblocks(mp);
+}
+
int
xfs_inode_ag_iterator(
struct xfs_mount *mp,
@@ -1273,6 +1299,9 @@ xfs_inode_set_eofblocks_tag(
XFS_ICI_EOFBLOCKS_TAG);
spin_unlock(&ip->i_mount->m_perag_lock);
+ /* kick off background trimming */
+ xfs_queue_eofblocks(ip->i_mount);
+
trace_xfs_perag_set_eofblocks(ip->i_mount, pag->pag_agno,
-1, _RET_IP_);
}
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index 23e9bf3..0448578 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -38,6 +38,7 @@ void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip);
void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_eofblocks *);
+void xfs_eofblocks_worker(struct work_struct *);
int xfs_sync_inode_grab(struct xfs_inode *ip);
int xfs_inode_ag_iterator(struct xfs_mount *mp,
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index 828662f..0a134ca 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -118,6 +118,7 @@
#define xfs_rotorstep xfs_params.rotorstep.val
#define xfs_inherit_nodefrag xfs_params.inherit_nodfrg.val
#define xfs_fstrm_centisecs xfs_params.fstrm_timer.val
+#define xfs_eofb_secs xfs_params.eofb_timer.val
#define current_cpu() (raw_smp_processor_id())
#define current_pid() (current->pid)
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 6f1c997..41ae7e1 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1428,6 +1428,8 @@ xfs_unmountfs(
__uint64_t resblks;
int error;
+ cancel_delayed_work_sync(&mp->m_eofblocks_work);
+
xfs_qm_unmount_quotas(mp);
xfs_rtunmount_inodes(mp);
IRELE(mp->m_rootip);
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index a631ca3..dc306a0 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -196,6 +196,8 @@ typedef struct xfs_mount {
#endif
struct xfs_mru_cache *m_filestream; /* per-mount filestream data */
struct delayed_work m_reclaim_work; /* background inode reclaim */
+ struct delayed_work m_eofblocks_work; /* background eof blocks
+ trimming */
__int64_t m_update_flags; /* sb flags we need to update
on the next remount,rw */
struct shrinker m_inode_shrink; /* inode reclaim shrinker */
@@ -207,6 +209,7 @@ typedef struct xfs_mount {
struct workqueue_struct *m_cil_workqueue;
struct workqueue_struct *m_reclaim_workqueue;
struct workqueue_struct *m_log_workqueue;
+ struct workqueue_struct *m_eofblocks_workqueue;
} xfs_mount_t;
/*
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 3d9ea94..ab8839b 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -874,8 +874,15 @@ xfs_init_mount_workqueues(
if (!mp->m_log_workqueue)
goto out_destroy_reclaim;
+ mp->m_eofblocks_workqueue = alloc_workqueue("xfs-eofblocks/%s",
+ WQ_NON_REENTRANT, 0, mp->m_fsname);
+ if (!mp->m_eofblocks_workqueue)
+ goto out_destroy_log;
+
return 0;
+out_destroy_log:
+ destroy_workqueue(mp->m_log_workqueue);
out_destroy_reclaim:
destroy_workqueue(mp->m_reclaim_workqueue);
out_destroy_cil:
@@ -892,6 +899,7 @@ STATIC void
xfs_destroy_mount_workqueues(
struct xfs_mount *mp)
{
+ destroy_workqueue(mp->m_eofblocks_workqueue);
destroy_workqueue(mp->m_log_workqueue);
destroy_workqueue(mp->m_reclaim_workqueue);
destroy_workqueue(mp->m_cil_workqueue);
@@ -1393,6 +1401,7 @@ xfs_fs_fill_super(
mutex_init(&mp->m_growlock);
atomic_set(&mp->m_active_trans, 0);
INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);
+ INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker);
mp->m_super = sb;
sb->s_fs_info = mp;
diff --git a/fs/xfs/xfs_sysctl.c b/fs/xfs/xfs_sysctl.c
index ee2d2ad..2801b5c 100644
--- a/fs/xfs/xfs_sysctl.c
+++ b/fs/xfs/xfs_sysctl.c
@@ -202,6 +202,15 @@ static ctl_table xfs_table[] = {
.extra1 = &xfs_params.fstrm_timer.min,
.extra2 = &xfs_params.fstrm_timer.max,
},
+ {
+ .procname = "speculative_prealloc_lifetime",
+ .data = &xfs_params.eofb_timer.val,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &xfs_params.eofb_timer.min,
+ .extra2 = &xfs_params.eofb_timer.max,
+ },
/* please keep this the last entry */
#ifdef CONFIG_PROC_FS
{
diff --git a/fs/xfs/xfs_sysctl.h b/fs/xfs/xfs_sysctl.h
index b9937d4..bd8e157 100644
--- a/fs/xfs/xfs_sysctl.h
+++ b/fs/xfs/xfs_sysctl.h
@@ -47,6 +47,7 @@ typedef struct xfs_param {
xfs_sysctl_val_t rotorstep; /* inode32 AG rotoring control knob */
xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */
xfs_sysctl_val_t fstrm_timer; /* Filestream dir-AG assoc'n timeout. */
+ xfs_sysctl_val_t eofb_timer; /* Interval between eofb scan wakeups */
} xfs_param_t;
/*
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v6 10/10] xfs: add background scanning to clear eofblocks inodes
2012-11-06 14:50 ` [PATCH v6 10/10] xfs: add background scanning to clear eofblocks inodes Brian Foster
@ 2012-11-06 17:04 ` Mark Tinguely
2012-11-06 22:30 ` Dave Chinner
1 sibling, 0 replies; 32+ messages in thread
From: Mark Tinguely @ 2012-11-06 17:04 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
On 11/06/12 08:50, Brian Foster wrote:
> Create a new mount workqueue and delayed_work to enable background
> scanning and freeing of eofblocks inodes. The scanner kicks in once
> speculative preallocation occurs and stops requeueing itself when
> no eofblocks inodes exist.
>
> The scan interval is based on the new
> 'speculative_prealloc_lifetime' tunable (default to 5m). The
> background scanner performs unfiltered, best effort scans (which
> skips inodes under lock contention or with a dirty cache mapping).
>
> Signed-off-by: Brian Foster<bfoster@redhat.com>
> ---
Looks good. Nice series.
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v6 10/10] xfs: add background scanning to clear eofblocks inodes
2012-11-06 14:50 ` [PATCH v6 10/10] xfs: add background scanning to clear eofblocks inodes Brian Foster
2012-11-06 17:04 ` Mark Tinguely
@ 2012-11-06 22:30 ` Dave Chinner
1 sibling, 0 replies; 32+ messages in thread
From: Dave Chinner @ 2012-11-06 22:30 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
On Tue, Nov 06, 2012 at 09:50:47AM -0500, Brian Foster wrote:
> Create a new mount workqueue and delayed_work to enable background
> scanning and freeing of eofblocks inodes. The scanner kicks in once
> speculative preallocation occurs and stops requeueing itself when
> no eofblocks inodes exist.
>
> The scan interval is based on the new
> 'speculative_prealloc_lifetime' tunable (default to 5m). The
> background scanner performs unfiltered, best effort scans (which
> skips inodes under lock contention or with a dirty cache mapping).
>
> Signed-off-by: Brian Foster <bfoster@redhat.com>
Looks good.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v7 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
` (9 preceding siblings ...)
2012-11-06 14:50 ` [PATCH v6 10/10] xfs: add background scanning to clear eofblocks inodes Brian Foster
@ 2012-11-07 17:21 ` Brian Foster
2012-11-07 17:21 ` [PATCH v7 07/10] xfs: add inode id filtering to eofblocks scan Brian Foster
2012-11-07 17:21 ` [PATCH v7 09/10] xfs: add minimum file size " Brian Foster
2012-11-08 22:38 ` [PATCH v6 00/10] speculative preallocation inode tracking Ben Myers
11 siblings, 2 replies; 32+ messages in thread
From: Brian Foster @ 2012-11-07 17:21 UTC (permalink / raw)
To: xfs
The XFS_IOC_FREE_EOFBLOCKS ioctl allows users to invoke an EOFBLOCKS
scan. The xfs_eofblocks structure is defined to support the command
parameters (scan mode).
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
---
v7:
- Added parens around the if flags check in xfs_icache_free_eofblocks().
fs/xfs/xfs_fs.h | 17 +++++++++++++++++
fs/xfs/xfs_icache.c | 10 +++++++---
fs/xfs/xfs_icache.h | 2 +-
fs/xfs/xfs_ioctl.c | 20 ++++++++++++++++++++
4 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index c13fed8..26ff43a 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -339,6 +339,22 @@ typedef struct xfs_error_injection {
/*
+ * Speculative preallocation trimming.
+ */
+#define XFS_EOFBLOCKS_VERSION 1
+struct xfs_eofblocks {
+ __u32 eof_version;
+ __u32 eof_flags;
+ __u64 pad[15];
+};
+
+/* eof_flags values */
+#define XFS_EOF_FLAGS_SYNC (1 << 0) /* sync/wait mode scan */
+#define XFS_EOF_FLAGS_VALID \
+ (XFS_EOF_FLAGS_SYNC)
+
+
+/*
* The user-level Handle Request interface structure.
*/
typedef struct xfs_fsop_handlereq {
@@ -456,6 +472,7 @@ typedef struct xfs_handle {
/* XFS_IOC_GETBIOSIZE ---- deprecated 47 */
#define XFS_IOC_GETBMAPX _IOWR('X', 56, struct getbmap)
#define XFS_IOC_ZERO_RANGE _IOW ('X', 57, struct xfs_flock64)
+#define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_eofblocks)
/*
* ioctl commands that replace IRIX syssgi()'s
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index b02a3df..b79aebe 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1206,11 +1206,15 @@ xfs_inode_free_eofblocks(
int
xfs_icache_free_eofblocks(
struct xfs_mount *mp,
- int flags)
+ struct xfs_eofblocks *eofb)
{
- ASSERT((flags & ~(SYNC_TRYLOCK|SYNC_WAIT)) == 0);
+ int flags = SYNC_TRYLOCK;
+
+ if (eofb && (eofb->eof_flags & XFS_EOF_FLAGS_SYNC))
+ flags = SYNC_WAIT;
+
return xfs_inode_ag_iterator_tag(mp, xfs_inode_free_eofblocks, flags,
- NULL, XFS_ICI_EOFBLOCKS_TAG);
+ eofb, XFS_ICI_EOFBLOCKS_TAG);
}
void
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index abca9fb..23e9bf3 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -37,7 +37,7 @@ void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);
void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip);
void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);
-int xfs_icache_free_eofblocks(struct xfs_mount *, int);
+int xfs_icache_free_eofblocks(struct xfs_mount *, struct xfs_eofblocks *);
int xfs_sync_inode_grab(struct xfs_inode *ip);
int xfs_inode_ag_iterator(struct xfs_mount *mp,
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index c1df3c6..5b20ab0 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -42,6 +42,7 @@
#include "xfs_inode_item.h"
#include "xfs_export.h"
#include "xfs_trace.h"
+#include "xfs_icache.h"
#include <linux/capability.h>
#include <linux/dcache.h>
@@ -1602,6 +1603,25 @@ xfs_file_ioctl(
error = xfs_errortag_clearall(mp, 1);
return -error;
+ case XFS_IOC_FREE_EOFBLOCKS: {
+ struct xfs_eofblocks eofb;
+
+ if (copy_from_user(&eofb, arg, sizeof(eofb)))
+ return -XFS_ERROR(EFAULT);
+
+ if (eofb.eof_version != XFS_EOFBLOCKS_VERSION)
+ return -XFS_ERROR(EINVAL);
+
+ if (eofb.eof_flags & ~XFS_EOF_FLAGS_VALID)
+ return -XFS_ERROR(EINVAL);
+
+ if (memchr_inv(eofb.pad, 0, sizeof(eofb.pad)))
+ return -XFS_ERROR(EINVAL);
+
+ error = xfs_icache_free_eofblocks(mp, &eofb);
+ return -error;
+ }
+
default:
return -ENOTTY;
}
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* [PATCH v7 07/10] xfs: add inode id filtering to eofblocks scan
2012-11-07 17:21 ` [PATCH v7 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl Brian Foster
@ 2012-11-07 17:21 ` Brian Foster
2012-11-07 20:33 ` Dave Chinner
2012-11-07 17:21 ` [PATCH v7 09/10] xfs: add minimum file size " Brian Foster
1 sibling, 1 reply; 32+ messages in thread
From: Brian Foster @ 2012-11-07 17:21 UTC (permalink / raw)
To: xfs
Support inode ID filtering in the eofblocks scan. The caller must
set the associated XFS_EOF_FLAGS_*ID bit and ID field.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
---
v7:
- Separate padding into two fields to explicitly handle alignment requirements.
- Fix up style of flags defines.
fs/xfs/xfs_fs.h | 14 ++++++++++++--
fs/xfs/xfs_icache.c | 22 ++++++++++++++++++++++
fs/xfs/xfs_ioctl.c | 3 ++-
3 files changed, 36 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 26ff43a..7113564 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -345,13 +345,23 @@ typedef struct xfs_error_injection {
struct xfs_eofblocks {
__u32 eof_version;
__u32 eof_flags;
- __u64 pad[15];
+ uid_t eof_uid;
+ gid_t eof_gid;
+ prid_t eof_prid;
+ __u32 pad32;
+ __u64 pad64[13];
};
/* eof_flags values */
#define XFS_EOF_FLAGS_SYNC (1 << 0) /* sync/wait mode scan */
+#define XFS_EOF_FLAGS_UID (1 << 1) /* filter by uid */
+#define XFS_EOF_FLAGS_GID (1 << 2) /* filter by gid */
+#define XFS_EOF_FLAGS_PRID (1 << 3) /* filter by project id */
#define XFS_EOF_FLAGS_VALID \
- (XFS_EOF_FLAGS_SYNC)
+ (XFS_EOF_FLAGS_SYNC | \
+ XFS_EOF_FLAGS_UID | \
+ XFS_EOF_FLAGS_GID | \
+ XFS_EOF_FLAGS_PRID)
/*
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index b79aebe..393cd36 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1171,6 +1171,21 @@ xfs_reclaim_inodes_count(
}
STATIC int
+xfs_inode_match_id(
+ struct xfs_inode *ip,
+ struct xfs_eofblocks *eofb)
+{
+ if (eofb->eof_flags & XFS_EOF_FLAGS_UID)
+ return ip->i_d.di_uid == eofb->eof_uid;
+ else if (eofb->eof_flags & XFS_EOF_FLAGS_GID)
+ return ip->i_d.di_gid == eofb->eof_gid;
+ else if (eofb->eof_flags & XFS_EOF_FLAGS_PRID)
+ return xfs_get_projid(ip) == eofb->eof_prid;
+
+ return 0;
+}
+
+STATIC int
xfs_inode_free_eofblocks(
struct xfs_inode *ip,
struct xfs_perag *pag,
@@ -1178,6 +1193,7 @@ xfs_inode_free_eofblocks(
void *args)
{
int ret;
+ struct xfs_eofblocks *eofb = args;
if (!xfs_can_free_eofblocks(ip, false)) {
/* inode could be preallocated or append-only */
@@ -1194,6 +1210,12 @@ xfs_inode_free_eofblocks(
mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY))
return 0;
+ if (eofb &&
+ (eofb->eof_flags & (XFS_EOF_FLAGS_UID|XFS_EOF_FLAGS_GID|
+ XFS_EOF_FLAGS_PRID)) &&
+ !xfs_inode_match_id(ip, eofb))
+ return 0;
+
ret = xfs_free_eofblocks(ip->i_mount, ip, true);
/* don't revisit the inode if we're not waiting */
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 5b20ab0..c1c3ef8 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -1615,7 +1615,8 @@ xfs_file_ioctl(
if (eofb.eof_flags & ~XFS_EOF_FLAGS_VALID)
return -XFS_ERROR(EINVAL);
- if (memchr_inv(eofb.pad, 0, sizeof(eofb.pad)))
+ if (memchr_inv(&eofb.pad32, 0, sizeof(eofb.pad32)) ||
+ memchr_inv(eofb.pad64, 0, sizeof(eofb.pad64)))
return -XFS_ERROR(EINVAL);
error = xfs_icache_free_eofblocks(mp, &eofb);
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v7 07/10] xfs: add inode id filtering to eofblocks scan
2012-11-07 17:21 ` [PATCH v7 07/10] xfs: add inode id filtering to eofblocks scan Brian Foster
@ 2012-11-07 20:33 ` Dave Chinner
0 siblings, 0 replies; 32+ messages in thread
From: Dave Chinner @ 2012-11-07 20:33 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
On Wed, Nov 07, 2012 at 12:21:13PM -0500, Brian Foster wrote:
> Support inode ID filtering in the eofblocks scan. The caller must
> set the associated XFS_EOF_FLAGS_*ID bit and ID field.
>
> Signed-off-by: Brian Foster <bfoster@redhat.com>
> Reviewed-by: Mark Tinguely <tinguely@sgi.com>
> ---
>
> v7:
> - Separate padding into two fields to explicitly handle alignment requirements.
> - Fix up style of flags defines.
>
> fs/xfs/xfs_fs.h | 14 ++++++++++++--
> fs/xfs/xfs_icache.c | 22 ++++++++++++++++++++++
> fs/xfs/xfs_ioctl.c | 3 ++-
> 3 files changed, 36 insertions(+), 3 deletions(-)
>
> diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
> index 26ff43a..7113564 100644
> --- a/fs/xfs/xfs_fs.h
> +++ b/fs/xfs/xfs_fs.h
> @@ -345,13 +345,23 @@ typedef struct xfs_error_injection {
> struct xfs_eofblocks {
> __u32 eof_version;
> __u32 eof_flags;
> - __u64 pad[15];
> + uid_t eof_uid;
> + gid_t eof_gid;
> + prid_t eof_prid;
> + __u32 pad32;
> + __u64 pad64[13];
> };
Looks good.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH v7 09/10] xfs: add minimum file size filtering to eofblocks scan
2012-11-07 17:21 ` [PATCH v7 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl Brian Foster
2012-11-07 17:21 ` [PATCH v7 07/10] xfs: add inode id filtering to eofblocks scan Brian Foster
@ 2012-11-07 17:21 ` Brian Foster
2012-11-07 20:33 ` Dave Chinner
1 sibling, 1 reply; 32+ messages in thread
From: Brian Foster @ 2012-11-07 17:21 UTC (permalink / raw)
To: xfs
Support minimum file size filtering in the eofblocks scan. The
caller must set the XFS_EOF_FLAGS_MINFILESIZE flags bit and minimum
file size value in bytes.
Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
---
v7:
- Add eof_min_file_size such that it is aligned.
- Updated flags style.
fs/xfs/xfs_fs.h | 7 +++++--
fs/xfs/xfs_icache.c | 11 +++++++++--
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 7113564..8455c9c 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -349,7 +349,8 @@ struct xfs_eofblocks {
gid_t eof_gid;
prid_t eof_prid;
__u32 pad32;
- __u64 pad64[13];
+ __u64 eof_min_file_size;
+ __u64 pad64[12];
};
/* eof_flags values */
@@ -357,11 +358,13 @@ struct xfs_eofblocks {
#define XFS_EOF_FLAGS_UID (1 << 1) /* filter by uid */
#define XFS_EOF_FLAGS_GID (1 << 2) /* filter by gid */
#define XFS_EOF_FLAGS_PRID (1 << 3) /* filter by project id */
+#define XFS_EOF_FLAGS_MINFILESIZE (1 << 4) /* filter by min file size */
#define XFS_EOF_FLAGS_VALID \
(XFS_EOF_FLAGS_SYNC | \
XFS_EOF_FLAGS_UID | \
XFS_EOF_FLAGS_GID | \
- XFS_EOF_FLAGS_PRID)
+ XFS_EOF_FLAGS_PRID | \
+ XFS_EOF_FLAGS_MINFILESIZE)
/*
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 6f3ccb6..c5c0ff0 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1215,8 +1215,15 @@ xfs_inode_free_eofblocks(
mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY))
return 0;
- if (eofb && !xfs_inode_match_id(ip, eofb))
- return 0;
+ if (eofb) {
+ if (!xfs_inode_match_id(ip, eofb))
+ return 0;
+
+ /* skip the inode if the file size is too small */
+ if (eofb->eof_flags & XFS_EOF_FLAGS_MINFILESIZE &&
+ XFS_ISIZE(ip) < eofb->eof_min_file_size)
+ return 0;
+ }
ret = xfs_free_eofblocks(ip->i_mount, ip, true);
--
1.7.7.6
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 32+ messages in thread* Re: [PATCH v7 09/10] xfs: add minimum file size filtering to eofblocks scan
2012-11-07 17:21 ` [PATCH v7 09/10] xfs: add minimum file size " Brian Foster
@ 2012-11-07 20:33 ` Dave Chinner
0 siblings, 0 replies; 32+ messages in thread
From: Dave Chinner @ 2012-11-07 20:33 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
On Wed, Nov 07, 2012 at 12:21:14PM -0500, Brian Foster wrote:
> Support minimum file size filtering in the eofblocks scan. The
> caller must set the XFS_EOF_FLAGS_MINFILESIZE flags bit and minimum
> file size value in bytes.
>
> Signed-off-by: Brian Foster <bfoster@redhat.com>
> Reviewed-by: Mark Tinguely <tinguely@sgi.com>
> ---
>
> v7:
> - Add eof_min_file_size such that it is aligned.
> - Updated flags style.
>
> fs/xfs/xfs_fs.h | 7 +++++--
> fs/xfs/xfs_icache.c | 11 +++++++++--
> 2 files changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
> index 7113564..8455c9c 100644
> --- a/fs/xfs/xfs_fs.h
> +++ b/fs/xfs/xfs_fs.h
> @@ -349,7 +349,8 @@ struct xfs_eofblocks {
> gid_t eof_gid;
> prid_t eof_prid;
> __u32 pad32;
> - __u64 pad64[13];
> + __u64 eof_min_file_size;
> + __u64 pad64[12];
> };
Looks good.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH v6 00/10] speculative preallocation inode tracking
2012-11-06 14:50 [PATCH v6 00/10] speculative preallocation inode tracking Brian Foster
` (10 preceding siblings ...)
2012-11-07 17:21 ` [PATCH v7 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl Brian Foster
@ 2012-11-08 22:38 ` Ben Myers
11 siblings, 0 replies; 32+ messages in thread
From: Ben Myers @ 2012-11-08 22:38 UTC (permalink / raw)
To: Brian Foster; +Cc: xfs
Hey Brian,
On Tue, Nov 06, 2012 at 09:50:37AM -0500, Brian Foster wrote:
> Hi all,
>
> Sorry for the delay. Here is v6 of the speculative prealloc tracking patchset.
> The first 5 patches are basically unchanged, the xfs_quota_type() patch is
> dropped and the subsequent patches have been reworked to gear the eofblocks
> ioctl() to filter based on inode ID's rather than being quota-centric, related to
> the following discussion:
>
> http://oss.sgi.com/archives/xfs/2012-10/msg00439.html
>
> My initial intent was to leave the ability to filter on multiple ID's
> concurrently as a follow-on change, but it seemed relatively straightforward as I
> was hacking on this so I included it in this set (patch 8). It is included as a
> standalone patch so I can leave it or drop it if necessary.
>
> This set has been tested via xfstests with debug on and off with no obvious
> regressions and sanity tested via Dave's xfs_spaceman tool and the prealloc add-on
> (which I will post an update for as well).
committed to git://oss.sgi.com/xfs/xfs.git, master and for-next branches.
Regards,
Ben
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 32+ messages in thread