speculative preallocation inode tracking
v5 cover speculative preallocation inode tracking
Hi all,
This is v3 of the speculative preallocation inode tracking patchset. This functionality tracks inodes with post-EOF speculative preallocation for the purpose of background and on-demand trimming.
Background scanning occurs on a longish interval (5 minutes by default) and in a best-effort mode (i.e., inodes are skipped due to lock contention or dirty cache). The intent is to clear up post-EOF blocks on inodes that might have allocations hanging around due to open-write-close sequences (NFS).
On demand scanning is provided via a new ioctl and supports various parameters such as scan mode, filtering by quota id and minimum file size. A pending use case for on demand scanning is for accurate quota accounting via the gluster scale out filesystem (i.e., to free up preallocated space when near a usage limit).
Brian
v5:
- Rebased against the die-xfssyncd-die patchset.
- Renamed xfs_inodes_free_eofblocks() to xfs_icache_free_eofblocks().
- Migrated xfs_can_free_eofblocks() from static inline to xfs_inode.c.
- Fixed xfs_eofblocks version field and added version check to ioctl().
- Reworked quota filtering to use standard quota fields. Added patch 7 to support.
- Split min. file size filtering into a separate patch.
- Reworked background scanning based on rebase. Created a new eofblocks workqueue, renamed the tunable and based its value in seconds.
v4:
- Fix the broken need_iolock parameter to the xfs_free_eofblocks() call in patch 5 (thanks to Ben M. for testing). This is a one line change. All other patches equivalent to v3. This version survives an xfstests run (with XFS_DEBUG enabled this time :P).
v3:
- Pushed dirty cache check up into patch 5 (minor clean up).
- Reworked xfs_can_free_eofblocks() in patch 3 as per Dave C.'s review.
- Rebased from linus' tree to the XFS tree.
v2:
- Remove unnecessary inode flag clear helper.
- Condense eofblocks set/clear tag functions.
- Move clear tag call into xfs_free_eofblocks().
- Modify AG walk infrastructure to support tag-based walk and utilize this functionality for the eofblocks scan (as opposed to the previous code duplicated from reclaim scanning).
- Improve ioctl functionality: new data structure fields/flags, validate quota is enabled.
- Increase default background scanning interval to 5 minutes, add tunable.
Brian Foster (10):
xfs: add EOFBLOCKS inode tagging/untagging
xfs: support a tag-based inode_ag_iterator
xfs: create helper to check whether to free eofblocks on inode
xfs: make xfs_free_eofblocks() non-static, return EAGAIN on trylock
failure
xfs: create function to scan and clear EOFBLOCKS inodes
xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
xfs: make xfs_quota_type() non-static
xfs: add quota id filtering to eofblocks scan
xfs: add minimum file size filtering to eofblocks scan
xfs: add background scanning to clear eofblocks inodes
fs/xfs/xfs_ag.h | 1 + fs/xfs/xfs_fs.h | 20 ++++ fs/xfs/xfs_globals.c | 1 + fs/xfs/xfs_icache.c | 220 ++++++++++++++++++++++++++++++++++++++++++++-- fs/xfs/xfs_icache.h | 12 ++- fs/xfs/xfs_inode.c | 37 ++++++++ fs/xfs/xfs_inode.h | 1 + fs/xfs/xfs_ioctl.c | 24 +++++ fs/xfs/xfs_iomap.c | 8 ++ fs/xfs/xfs_iops.c | 4 + fs/xfs/xfs_linux.h | 1 + fs/xfs/xfs_mount.c | 2 + fs/xfs/xfs_mount.h | 3 + fs/xfs/xfs_qm_syscalls.c | 5 +- fs/xfs/xfs_quota.h | 1 + fs/xfs/xfs_quotaops.c | 2 +- fs/xfs/xfs_super.c | 9 ++ fs/xfs/xfs_sysctl.c | 9 ++ fs/xfs/xfs_sysctl.h | 1 + fs/xfs/xfs_trace.h | 6 ++ fs/xfs/xfs_vnodeops.c | 27 +++--- fs/xfs/xfs_vnodeops.h | 1 + 22 files changed, 368 insertions(+), 27 deletions(-)
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 1/10 xfs: add EOFBLOCKS inode tagging/untagging
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.
--- 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(-)
fs/xfs/xfs_ag.h +1 -0
@@ -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) \
fs/xfs/xfs_icache.c +62 -0
65 lines not on this page · raw message
fs/xfs/xfs_icache.h +3 -0
@@ -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),
fs/xfs/xfs_iomap.c +8 -0
@@ -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 ; }
fs/xfs/xfs_iops.c +4 -0
@@ -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 ) {
fs/xfs/xfs_trace.h +5 -0
@@ -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),
fs/xfs/xfs_vnodeops.c +2 -0
@@ -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 );
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 2/10 xfs: support a tag-based inode_ag_iterator
In reply to Brian FosterGenericize 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.
--- 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(-)
fs/xfs/xfs_icache.c +49 -7
@@ -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 @@ intxfs_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;
fs/xfs/xfs_icache.h +5 -2
@@ -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
fs/xfs/xfs_qm_syscalls.c +3 -2
@@ -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 ); }
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 3/10 xfs: create helper to check whether to free eofblocks on inode
In reply to Brian FosterThis 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.
--- 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(-)
fs/xfs/xfs_inode.c +37 -0
@@ -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; +} +
fs/xfs/xfs_inode.h +1 -0
@@ -600,6 +600,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))
fs/xfs/xfs_vnodeops.c +7 -12
@@ -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 ;
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 03/10] xfs: create helper to check whether to free eofblocks on inode
Quoted 11 lines · Brian Foster
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 toxfs_can_free_eofblocks()specifies whether we should ignore the prealloc/append-only status of the inode.Signed-off-by Brian Foster <[email protected]>
Looks good. I'm glad this little mess is going away :)
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 4/10 xfs: make xfs_free_eofblocks() non-static, return EAGAIN on trylock failure
In reply to Brian FosterTurn 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().
--- fs/xfs/xfs_vnodeops.c | 6 +++--- fs/xfs/xfs_vnodeops.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-)
fs/xfs/xfs_vnodeops.c +3 -3
@@ -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 */
fs/xfs/xfs_vnodeops.h +1 -0
@@ -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 */
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 5/10 xfs: create function to scan and clear EOFBLOCKS inodes
In reply to Brian Fosterxfs_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.
--- 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(-)
fs/xfs/xfs_icache.c +43 -0
@@ -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)
fs/xfs/xfs_icache.h +1 -0
@@ -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,
fs/xfs/xfs_trace.h +1 -0
@@ -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),
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 05/10] xfs: create function to scan and clear EOFBLOCKS inodes
Quoted 6 lines · Brian Foster
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 thexfs_inode_free_eofblocks()execute function. The scan can be invoked in best-effort mode or wait (force) mode.
Quoted 6 lines
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 <[email protected]>
Looks fine.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 6/10 xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
In reply to Brian FosterThe 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).
--- fs/xfs/xfs_fs.h | 15 +++++++++++++++ fs/xfs/xfs_icache.c | 5 +++-- fs/xfs/xfs_icache.h | 2 +- fs/xfs/xfs_ioctl.c | 16 ++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-)
fs/xfs/xfs_fs.h +15 -0
@@ -339,6 +339,20 @@ typedef struct xfs_error_injection {/* +* Speculative preallocation trimming. +*/ +#define XFS_EOFBLOCKS_VERSION 1 +struct xfs_eofblocks { +__u32 eof_version; +__u32 eof_flags; +unsigned char pad[12 ]; +}; + +/* eof_flags values */ +#define XFS_EOF_FLAGS_SYNC 0x01/* sync/wait mode scan */ + + +/* * The user-level Handle Request interface structure. */ typedef struct xfs_fsop_handlereq {
@@ -456,6 +470,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
fs/xfs/xfs_icache.c +3 -2
@@ -1206,11 +1206,12 @@ xfs_inode_free_eofblocks(int xfs_icache_free_eofblocks (struct xfs_mount *mp, -int flags) +int flags, +struct xfs_eofblocks *eofb) {ASSERT ((flags & ~(SYNC_TRYLOCK |SYNC_WAIT )) ==0 );return xfs_inode_ag_iterator_tag (mp, xfs_inode_free_eofblocks, flags, -NULL ,XFS_ICI_EOFBLOCKS_TAG ); + eofb,XFS_ICI_EOFBLOCKS_TAG ); }void
fs/xfs/xfs_icache.h +1 -1
@@ -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 *,int ,struct xfs_eofblocks *);int xfs_sync_inode_grab (struct xfs_inode *ip); int xfs_inode_ag_iterator(struct xfs_mount *mp,
fs/xfs/xfs_ioctl.c +16 -0
@@ -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,21 @@ xfs_file_ioctl( error =xfs_errortag_clearall (mp,1 );return -error; +case XFS_IOC_FREE_EOFBLOCKS : { +struct xfs_eofblocks eofb; +int flags; + +if (copy_from_user (&eofb, arg,sizeof (eofb))) +return -XFS_ERROR (EFAULT ); + +if (eofb.eof_version !=XFS_EOFBLOCKS_VERSION ) +return -XFS_ERROR (EINVAL ); + + flags = (eofb.eof_flags &XFS_EOF_FLAGS_SYNC ) ?SYNC_WAIT :SYNC_TRYLOCK ; + error =xfs_icache_free_eofblocks (mp, flags, &eofb); +return -error; + } +default :return -ENOTTY ; }
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Hey Brian,
Quoted 3 lines · Brian Foster
The
XFS_IOC_FREE_EOFBLOCKSioctl allows users to invoke an EOFBLOCKS scan. Thexfs_eofblocksstructure is defined to support the command parameters (scan mode).
It would help to have an xfstest to exercise this ioctl to pull in with this series. Do you have any code that could be wrangled into a test case?
Regards,
Ben
Quoted 115 lines
Signed-off-by Brian Foster <[email protected]>--- fs/xfs/xfs_fs.h | 15 +++++++++++++++ fs/xfs/xfs_icache.c | 5 +++-- fs/xfs/xfs_icache.h | 2 +- fs/xfs/xfs_ioctl.c | 16 ++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-)fs/xfs/xfs_fs.h +15
-0@@ -339,6 +339,20 @@ typedef struct xfs_error_injection {/* +* Speculative preallocation trimming. +*/ +#define XFS_EOFBLOCKS_VERSION 1 +struct xfs_eofblocks { +__u32 eof_version; +__u32 eof_flags; +unsigned char pad[12 ]; +}; + +/* eof_flags values */ +#define XFS_EOF_FLAGS_SYNC 0x01/* sync/wait mode scan */ + + +/* * The user-level Handle Request interface structure. */ typedef struct xfs_fsop_handlereq {@@ -456,6 +470,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 fs/xfs/xfs_icache.c +3
-2@@ -1206,11 +1206,12 @@ xfs_inode_free_eofblocks(int xfs_icache_free_eofblocks (struct xfs_mount *mp, -int flags) +int flags, +struct xfs_eofblocks *eofb) {ASSERT ((flags & ~(SYNC_TRYLOCK |SYNC_WAIT )) ==0 );return xfs_inode_ag_iterator_tag (mp, xfs_inode_free_eofblocks, flags, -NULL ,XFS_ICI_EOFBLOCKS_TAG ); + eofb,XFS_ICI_EOFBLOCKS_TAG ); }void fs/xfs/xfs_icache.h +1
-1@@ -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 *,int ,struct xfs_eofblocks *);int xfs_sync_inode_grab (struct xfs_inode *ip); int xfs_inode_ag_iterator(struct xfs_mount *mp,fs/xfs/xfs_ioctl.c +16
-0@@ -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,21 @@ xfs_file_ioctl( error =xfs_errortag_clearall (mp,1 );return -error; +case XFS_IOC_FREE_EOFBLOCKS : { +struct xfs_eofblocks eofb; +int flags; + +if (copy_from_user (&eofb, arg,sizeof (eofb))) +return -XFS_ERROR (EFAULT ); + +if (eofb.eof_version !=XFS_EOFBLOCKS_VERSION ) +return -XFS_ERROR (EINVAL ); + + flags = (eofb.eof_flags &XFS_EOF_FLAGS_SYNC ) ?SYNC_WAIT :SYNC_TRYLOCK ; + error =xfs_icache_free_eofblocks (mp, flags, &eofb); +return -error; + } +default :return -ENOTTY ; }Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Quoted 10 lines · Ben Myers
Hey Brian,
Quoted 3 lines · Brian Foster
The
XFS_IOC_FREE_EOFBLOCKSioctl allows users to invoke an EOFBLOCKS scan. Thexfs_eofblocksstructure is defined to support the command parameters (scan mode).It would help to have an xfstest to exercise this ioctl to pull in with this series. Do you have any code that could be wrangled into a test case?
Yes, makes sense. I have some very basic test code I could put somewhere to invoke the ioctl(). One of the questions I've been meaning to ask is whether it would be relevant for that code to live in a common tool, such as adding a new command to xfs_io. Then perhaps create an xfstests test using that. Thoughts?
FYI, I have a few other things on my plate at the moment so unfortunately it will be a bit before I can get back to XFS work... But I'm fine with the set pending until I can come up with some test coverage if that is preferable, of course.
Brian
Quoted 114 lines
Regards,
BenQuoted 111 lines
Signed-off-by Brian Foster <[email protected]>--- fs/xfs/xfs_fs.h | 15 +++++++++++++++ fs/xfs/xfs_icache.c | 5 +++-- fs/xfs/xfs_icache.h | 2 +- fs/xfs/xfs_ioctl.c | 16 ++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-)fs/xfs/xfs_fs.h +15
-0@@ -339,6 +339,20 @@ typedef struct xfs_error_injection {/* +* Speculative preallocation trimming. +*/ +#define XFS_EOFBLOCKS_VERSION 1 +struct xfs_eofblocks { +__u32 eof_version; +__u32 eof_flags; +unsigned char pad[12 ]; +}; + +/* eof_flags values */ +#define XFS_EOF_FLAGS_SYNC 0x01/* sync/wait mode scan */ + + +/* * The user-level Handle Request interface structure. */ typedef struct xfs_fsop_handlereq {@@ -456,6 +470,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 fs/xfs/xfs_icache.c +3
-2@@ -1206,11 +1206,12 @@ xfs_inode_free_eofblocks(int xfs_icache_free_eofblocks (struct xfs_mount *mp, -int flags) +int flags, +struct xfs_eofblocks *eofb) {ASSERT ((flags & ~(SYNC_TRYLOCK |SYNC_WAIT )) ==0 );return xfs_inode_ag_iterator_tag (mp, xfs_inode_free_eofblocks, flags, -NULL ,XFS_ICI_EOFBLOCKS_TAG ); + eofb,XFS_ICI_EOFBLOCKS_TAG ); }void fs/xfs/xfs_icache.h +1
-1@@ -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 *,int ,struct xfs_eofblocks *);int xfs_sync_inode_grab (struct xfs_inode *ip); int xfs_inode_ag_iterator(struct xfs_mount *mp,fs/xfs/xfs_ioctl.c +16
-0@@ -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,21 @@ xfs_file_ioctl( error =xfs_errortag_clearall (mp,1 );return -error; +case XFS_IOC_FREE_EOFBLOCKS : { +struct xfs_eofblocks eofb; +int flags; + +if (copy_from_user (&eofb, arg,sizeof (eofb))) +return -XFS_ERROR (EFAULT ); + +if (eofb.eof_version !=XFS_EOFBLOCKS_VERSION ) +return -XFS_ERROR (EINVAL ); + + flags = (eofb.eof_flags &XFS_EOF_FLAGS_SYNC ) ?SYNC_WAIT :SYNC_TRYLOCK ; + error =xfs_icache_free_eofblocks (mp, flags, &eofb); +return -error; + } +default :return -ENOTTY ; }Signature · 1 line
1.7.7.6
Quoted 4 lines
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Hey Brian,
Quoted 12 lines · Brian Foster
Quoted 10 lines · Ben Myers
Hey Brian,
Quoted 3 lines · Brian Foster
The
XFS_IOC_FREE_EOFBLOCKSioctl allows users to invoke an EOFBLOCKS scan. Thexfs_eofblocksstructure is defined to support the command parameters (scan mode).It would help to have an xfstest to exercise this ioctl to pull in with this series. Do you have any code that could be wrangled into a test case?
Quoted 5 lines
Yes, makes sense. I have some very basic test code I could put somewhere to invoke the
ioctl(). One of the questions I've been meaning to ask is whether it would be relevant for that code to live in a common tool, such as adding a new command toxfs_io. Then perhaps create an xfstests test using that. Thoughts?
IMO you are right on the mark. xfs_io is a great place for this.
Quoted 4 lines
FYI, I have a few other things on my plate at the moment so unfortunately it will be a bit before I can get back to XFS work... But I'm fine with the set pending until I can come up with some test coverage if that is preferable, of course.
I do think it is preferable to have a test case go in with the code where possible. Since you don't mind waiting a bit, that seems to be the way to go. The other option could be to look for a volunteer to work on the test. ;)
Regards,
Ben
Quoted 116 lines
Brian
Quoted 114 lines
Regards,
BenQuoted 111 lines
Signed-off-by Brian Foster <[email protected]>--- fs/xfs/xfs_fs.h | 15 +++++++++++++++ fs/xfs/xfs_icache.c | 5 +++-- fs/xfs/xfs_icache.h | 2 +- fs/xfs/xfs_ioctl.c | 16 ++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-)fs/xfs/xfs_fs.h +15
-0@@ -339,6 +339,20 @@ typedef struct xfs_error_injection {/* +* Speculative preallocation trimming. +*/ +#define XFS_EOFBLOCKS_VERSION 1 +struct xfs_eofblocks { +__u32 eof_version; +__u32 eof_flags; +unsigned char pad[12 ]; +}; + +/* eof_flags values */ +#define XFS_EOF_FLAGS_SYNC 0x01/* sync/wait mode scan */ + + +/* * The user-level Handle Request interface structure. */ typedef struct xfs_fsop_handlereq {@@ -456,6 +470,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 fs/xfs/xfs_icache.c +3
-2@@ -1206,11 +1206,12 @@ xfs_inode_free_eofblocks(int xfs_icache_free_eofblocks (struct xfs_mount *mp, -int flags) +int flags, +struct xfs_eofblocks *eofb) {ASSERT ((flags & ~(SYNC_TRYLOCK |SYNC_WAIT )) ==0 );return xfs_inode_ag_iterator_tag (mp, xfs_inode_free_eofblocks, flags, -NULL ,XFS_ICI_EOFBLOCKS_TAG ); + eofb,XFS_ICI_EOFBLOCKS_TAG ); }void fs/xfs/xfs_icache.h +1
-1@@ -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 *,int ,struct xfs_eofblocks *);int xfs_sync_inode_grab (struct xfs_inode *ip); int xfs_inode_ag_iterator(struct xfs_mount *mp,fs/xfs/xfs_ioctl.c +16
-0@@ -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,21 @@ xfs_file_ioctl( error =xfs_errortag_clearall (mp,1 );return -error; +case XFS_IOC_FREE_EOFBLOCKS : { +struct xfs_eofblocks eofb; +int flags; + +if (copy_from_user (&eofb, arg,sizeof (eofb))) +return -XFS_ERROR (EFAULT ); + +if (eofb.eof_version !=XFS_EOFBLOCKS_VERSION ) +return -XFS_ERROR (EINVAL ); + + flags = (eofb.eof_flags &XFS_EOF_FLAGS_SYNC ) ?SYNC_WAIT :SYNC_TRYLOCK ; + error =xfs_icache_free_eofblocks (mp, flags, &eofb); +return -error; + } +default :return -ENOTTY ; }Signature · 1 line
1.7.7.6
Quoted 5 lines
Quoted 4 lines
Quoted 4 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Quoted 23 lines · Ben Myers
Hey Brian,
Quoted 12 lines · Brian Foster
Quoted 10 lines · Ben Myers
Hey Brian,
Quoted 3 lines · Brian Foster
The
XFS_IOC_FREE_EOFBLOCKSioctl allows users to invoke an EOFBLOCKS scan. Thexfs_eofblocksstructure is defined to support the command parameters (scan mode).It would help to have an xfstest to exercise this ioctl to pull in with this series. Do you have any code that could be wrangled into a test case?
Quoted 5 lines
Yes, makes sense. I have some very basic test code I could put somewhere to invoke the
ioctl(). One of the questions I've been meaning to ask is whether it would be relevant for that code to live in a common tool, such as adding a new command toxfs_io. Then perhaps create an xfstests test using that. Thoughts?IMO you are right on the mark.
xfs_iois a great place for this.
Quoted 8 lines
Quoted 4 lines
FYI, I have a few other things on my plate at the moment so unfortunately it will be a bit before I can get back to XFS work... But I'm fine with the set pending until I can come up with some test coverage if that is preferable, of course.
I do think it is preferable to have a test case go in with the code where possible. Since you don't mind waiting a bit, that seems to be the way to go. The other option could be to look for a volunteer to work on the test. ;)
FWIW, given the background cleanup code can be trivially verified to work (open, apend, close, repeat, wait 5 minutes) and is the functionality that is needed in mainline, having something to test the ioctls should not stop the patchset from being merged.
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Quoted 29 lines · Dave Chinner
Quoted 28 lines · Ben Myers
Hey Brian,
Quoted 12 lines · Brian Foster
Quoted 10 lines · Ben Myers
Hey Brian,
Quoted 3 lines · Brian Foster
The
XFS_IOC_FREE_EOFBLOCKSioctl allows users to invoke an EOFBLOCKS scan. Thexfs_eofblocksstructure is defined to support the command parameters (scan mode).It would help to have an xfstest to exercise this ioctl to pull in with this series. Do you have any code that could be wrangled into a test case?
Quoted 5 lines
Yes, makes sense. I have some very basic test code I could put somewhere to invoke the
ioctl(). One of the questions I've been meaning to ask is whether it would be relevant for that code to live in a common tool, such as adding a new command toxfs_io. Then perhaps create an xfstests test using that. Thoughts?IMO you are right on the mark.
xfs_iois a great place for this.Quoted 4 lines
FYI, I have a few other things on my plate at the moment so unfortunately it will be a bit before I can get back to XFS work... But I'm fine with the set pending until I can come up with some test coverage if that is preferable, of course.
Quoted 8 lines
Quoted 3 lines
I do think it is preferable to have a test case go in with the code where possible. Since you don't mind waiting a bit, that seems to be the way to go. The other option could be to look for a volunteer to work on the test. ;)
FWIW, given the background cleanup code can be trivially verified to work (open, apend, close, repeat, wait 5 minutes) and is the functionality that is needed in mainline, having something to test the ioctls should not stop the patchset from being merged.
i.e.:
$ for i in `seq 0 512`; do
Quoted 2 lines
xfs_io-f -c "pwrite $((i * 4096)) 4096"/mnt/scratch/foodone
$ stat -c %b /mnt/scratch/foo 8192 $ sync; stat -c %b /mnt/scratch/foo 8192 $ sleep 30; stat -c %b /mnt/scratch/foo 8192 $ sleep 300; stat -c %b /mnt/scratch/foo 4104
It works. ;)
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Hi Fellas,
Quoted 30 lines · Dave Chinner
Quoted 29 lines · Dave Chinner
Quoted 28 lines · Ben Myers
Hey Brian,
Quoted 12 lines · Brian Foster
Quoted 10 lines · Ben Myers
Hey Brian,
Quoted 3 lines · Brian Foster
The
XFS_IOC_FREE_EOFBLOCKSioctl allows users to invoke an EOFBLOCKS scan. Thexfs_eofblocksstructure is defined to support the command parameters (scan mode).It would help to have an xfstest to exercise this ioctl to pull in with this series. Do you have any code that could be wrangled into a test case?
Quoted 5 lines
Yes, makes sense. I have some very basic test code I could put somewhere to invoke the
ioctl(). One of the questions I've been meaning to ask is whether it would be relevant for that code to live in a common tool, such as adding a new command toxfs_io. Then perhaps create an xfstests test using that. Thoughts?IMO you are right on the mark.
xfs_iois a great place for this.Quoted 4 lines
FYI, I have a few other things on my plate at the moment so unfortunately it will be a bit before I can get back to XFS work... But I'm fine with the set pending until I can come up with some test coverage if that is preferable, of course.
Quoted 8 lines
Quoted 8 lines
Quoted 3 lines
I do think it is preferable to have a test case go in with the code where possible. Since you don't mind waiting a bit, that seems to be the way to go. The other option could be to look for a volunteer to work on the test. ;)
FWIW, given the background cleanup code can be trivially verified to work (open, apend, close, repeat, wait 5 minutes) and is the functionality that is needed in mainline, having something to test the ioctls should not stop the patchset from being merged.
Can we be assured that we'll get an xfstest for it eventually?
I think we can pull this in if Brian is willing post his test code. Initially it needn't be posted as an xfstest, that's fine. As it stands today it appears that Brian is the only one to ever use the ioctl and there is no way for anyone else to test it. Not an ideal situation.
I think this is a reasonable request. Usually it's Christoph who asks for a test case. ;)
Quoted 14 lines
i.e.:
$ for i in `seq 0 512`; doQuoted 2 lines
xfs_io-f -c "pwrite $((i * 4096)) 4096"/mnt/scratch/foodone$ stat -c %b /mnt/scratch/foo 8192 $ sync; stat -c %b /mnt/scratch/foo 8192 $ sleep 30; stat -c %b /mnt/scratch/foo 8192 $ sleep 300; stat -c %b /mnt/scratch/foo 4104
Quoted 1 line
It works. ;)
Nice!
Regards,
Ben
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Quoted 7 lines · Ben Myers
Hi Fellas,
Quoted 4 lines · Dave Chinner
Quoted 3 lines · Dave Chinner
Quoted 2 lines · Ben Myers
Hey Brian,
...
Quoted 11 lines
Quoted 8 lines
Quoted 8 lines
Quoted 3 lines
I do think it is preferable to have a test case go in with the code where possible. Since you don't mind waiting a bit, that seems to be the way to go. The other option could be to look for a volunteer to work on the test. ;)
FWIW, given the background cleanup code can be trivially verified to work (open, apend, close, repeat, wait 5 minutes) and is the functionality that is needed in mainline, having something to test the ioctls should not stop the patchset from being merged.
Can we be assured that we'll get an xfstest for it eventually?
Absolutely. Getting a command into xfs_io to support such a test is now the top of my todo list with regard to XFS. :)
Quoted 5 lines
I think we can pull this in if Brian is willing post his test code. Initially it needn't be posted as an xfstest, that's fine. As it stands today it appears that Brian is the only one to ever use the ioctl and there is no way for anyone else to test it. Not an ideal situation.
The impetus for this work was some prototype quota work for the gluster distributed filesystem. Beyond testing via that, I just had a very simple/stupid program with the command and data structure bits copy/pasted in to open a file and invoke an xfsctl() with hardcoded parameters. I don't consider it post-worthy or very useful, but attached nonetheless since I have a couple things to deal with before I get a chance to play with xfs_io.
Quoted 3 lines
I think this is a reasonable request. Usually it's Christoph who asks for a test case. ;)
Agree.
Brian
Quoted 14 lines
Quoted 14 lines
i.e.:
$ for i in `seq 0 512`; doQuoted 2 lines
xfs_io-f -c "pwrite $((i * 4096)) 4096"/mnt/scratch/foodone$ stat -c %b /mnt/scratch/foo 8192 $ sync; stat -c %b /mnt/scratch/foo 8192 $ sleep 30; stat -c %b /mnt/scratch/foo 8192 $ sleep 300; stat -c %b /mnt/scratch/foo 4104
Quoted 7 lines
Quoted 1 line
It works. ;)
Nice!
Regards,
Ben
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <xfs/xfs.h>
#include <sys/quota.h>
#ifndef PRJQUOTA
#define PRJQUOTA 2
#endif
/*
* Speculative preallocation trimming.
*/
#define XFS_EOFBLOCKS_VERSION 1
struct xfs_eofblocks {
__s32 eof_version;
__u32 eof_flags;
__u32 eof_q_id;
__u32 eof_q_type;
__u32 eof_min_file_size;
unsigned char pad[12];
};/* eof_flags values */
#define XFS_EOF_FLAGS_SYNC 0x01 /* sync/wait mode scan */ #define XFS_EOF_FLAGS_QUOTA 0x02 /* filter by quota id */ #define XFS_EOF_FLAGS_MINFILESIZE 0x04 /* filter by min file size */
#define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_eofblocks)
int main(int argc, char *argv[])
{
int ret, fd;
struct xfs_eofblocks eofb;
fd = open(argv[1], O_RDONLY);
if (fd < 0) {
perror("open");
return -1;
}
memset(&eofb, 0, sizeof(struct xfs_eofblocks));
eofb.eof_version = XFS_EOFBLOCKS_VERSION;
eofb.eof_flags |= XFS_EOF_FLAGS_SYNC;
//eofb.eof_flags |= XFS_EOF_FLAGS_QUOTA;
//eofb.eof_q_id = 42;
//eofb.eof_q_type = PRJQUOTA;
eofb.eof_flags |= XFS_EOF_FLAGS_MINFILESIZE;
eofb.eof_min_file_size = 1024 * 1024 * 101;
ret = xfsctl(NULL, fd, XFS_IOC_FREE_EOFBLOCKS, &eofb);
if (ret < 0)
perror("xfsctl");
if (close(fd) < 0)
perror("close");
return 0;
}_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Hey Brian,
Quoted 16 lines · Brian Foster
Quoted 5 lines · Ben Myers
Quoted 4 lines · Dave Chinner
Quoted 3 lines · Dave Chinner
Quoted 2 lines · Ben Myers
Hey Brian,
...
Quoted 9 lines
Quoted 8 lines
Quoted 8 lines
Quoted 3 lines
I do think it is preferable to have a test case go in with the code where possible. Since you don't mind waiting a bit, that seems to be the way to go. The other option could be to look for a volunteer to work on the test. ;)
FWIW, given the background cleanup code can be trivially verified to work (open, apend, close, repeat, wait 5 minutes) and is the functionality that is needed in mainline, having something to test the ioctls should not stop the patchset from being merged.
Quoted 5 lines
Quoted 2 lines
Can we be assured that we'll get an xfstest for it eventually?
Absolutely. Getting a command into
xfs_ioto support such a test is now the top of my todo list with regard to XFS. :)
Excellent!
Quoted 8 lines
Quoted 5 lines
I think we can pull this in if Brian is willing post his test code. Initially it needn't be posted as an xfstest, that's fine. As it stands today it appears that Brian is the only one to ever use the ioctl and there is no way for anyone else to test it. Not an ideal situation.
The impetus for this work was some prototype quota work for the gluster distributed filesystem.
Now I'm curious where you're coming from. Is gluster your primary project?
Quoted 6 lines
Beyond testing via that, I just had a very
simple/stupid program with the command and data structure bits copy/pasted in to open a file and invoke anxfsctl()with hardcoded parameters. I don't consider it post-worthy or very useful, but attached nonetheless since I have a couple things to deal with before I get a chance to play withxfs_io.
Thanks for posting it anyway. That's enough for an interested party to do a little fooling. I believe Mark is finishing up a review of this series, so we'll get it in soon.
Regards,
Ben
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Quoted 33 lines · Ben Myers
Hey Brian,
Quoted 16 lines · Brian Foster
Quoted 5 lines · Ben Myers
Quoted 4 lines · Dave Chinner
Quoted 3 lines · Dave Chinner
Quoted 2 lines · Ben Myers
Hey Brian,
...
Quoted 9 lines
Quoted 8 lines
Quoted 8 lines
Quoted 3 lines
I do think it is preferable to have a test case go in with the code where possible. Since you don't mind waiting a bit, that seems to be the way to go. The other option could be to look for a volunteer to work on the test. ;)
FWIW, given the background cleanup code can be trivially verified to work (open, apend, close, repeat, wait 5 minutes) and is the functionality that is needed in mainline, having something to test the ioctls should not stop the patchset from being merged.
Quoted 5 lines
Quoted 2 lines
Can we be assured that we'll get an xfstest for it eventually?
Absolutely. Getting a command into
xfs_ioto support such a test is now the top of my todo list with regard to XFS. :)Excellent!
Quoted 6 lines
Quoted 5 lines
I think we can pull this in if Brian is willing post his test code. Initially it needn't be posted as an xfstest, that's fine. As it stands today it appears that Brian is the only one to ever use the ioctl and there is no way for anyone else to test it. Not an ideal situation.
Quoted 5 lines
Quoted 2 lines
The impetus for this work was some prototype quota work for the gluster distributed filesystem.
Now I'm curious where you're coming from. Is gluster your primary project?
gluster is the primary component of our appliance. We recommend running our "bricks" on top of XFS, so one of my goals has been to get more involved with XFS development as well. :) This was a nice little project for me to break some ground on (actually I have some associated XFS quota prealloc throttling changes in the works as well, but I'll prioritize the testing work here first). ;)
Quoted 11 lines
Quoted 6 lines
Beyond testing via that, I just had a very
simple/stupid program with the command and data structure bits copy/pasted in to open a file and invoke anxfsctl()with hardcoded parameters. I don't consider it post-worthy or very useful, but attached nonetheless since I have a couple things to deal with before I get a chance to play withxfs_io.Thanks for posting it anyway. That's enough for an interested party to do a little fooling. I believe Mark is finishing up a review of this series, so we'll get it in soon.
Sounds good. Thanks.
Brian
Quoted 3 lines
Regards,
Ben
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
In reply to Brian FosterQuoted 10 lines · Brian Foster
Quoted 6 lines · Ben Myers
Quoted 4 lines
Quoted 4 lines
FWIW, given the background cleanup code can be trivially verified to work (open, apend, close, repeat, wait 5 minutes) and is the functionality that is needed in mainline, having something to test the ioctls should not stop the patchset from being merged.
Can we be assured that we'll get an xfstest for it eventually?
Absolutely. Getting a command into
xfs_ioto support such a test is now the top of my todo list with regard to XFS. :)
Here's a patch to the new xfs_spaceman program I'm writing that adds control for these ioctls.
Cheers,
Dave.
Signature · 17 lines
Dave Chinner [email protected] spaceman: add new speculative prealloc control From: Dave Chinner <[email protected]> Add an control interface for purging speculative preallocation via the new ioctls. Signed-off-by: Dave Chinner <[email protected]> --- spaceman/Makefile | 2 +- spaceman/init.c | 1 + spaceman/prealloc.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++ spaceman/space.h | 1 + 4 files changed, 168 insertions(+), 1 deletion(-)
spaceman/Makefile +1 -1
@@ -8,7 +8,7 @@ include $(TOPDIR)/include/builddefs LTCOMMAND = xfs_spaceman HFILES = init.h space.h CFILES = init.c \ - file.c freesp.c + file.c freesp.c prealloc.c LLDLIBS = $(LIBXCMD) LTDEPENDENCIES = $(LIBXCMD)
spaceman/init.c +1 -0
@@ -40,6 +40,7 @@ init_commands(void)file_init ();freesp_init ();help_init (); +prealloc_init ();quit_init (); }
spaceman/prealloc.c new file +165 -0
165 lines not on this page · raw message
spaceman/space.h +1 -0
@@ -35,3 +35,4 @@ extern void file_init(void);extern void help_init (void );extern void quit_init (void );extern void freesp_init (void ); +extern void prealloc_init (void );
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Quoted 7 lines · Dave Chinner
Quoted 6 lines · Brian Foster
Quoted 5 lines · Ben Myers
Quoted 4 lines
Quoted 4 lines
FWIW, given the background cleanup code can be trivially verified to work (open, apend, close, repeat, wait 5 minutes) and is the functionality that is needed in mainline, having something to test the ioctls should not stop the patchset from being merged.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
Can we be assured that we'll get an xfstest for it eventually?
Absolutely. Getting a command into
xfs_ioto support such a test is now the top of my todo list with regard to XFS. :)Here's a patch to the new
xfs_spacemanprogram I'm writing that adds control for these ioctls.
Very cool, thanks. Catchy name for the tool as well, btw ;).
For some reason my mailer is stripping out the patch, but my only comment is with regard to minlen. Shouldn't that variable be handled as an unsigned? Now that I think of it, that makes me wonder if I should make that a 64-bit unsigned in xfs_eofblocks..?
Brian
Quoted 4 lines
Cheers,
Dave.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Quoted 13 lines · Brian Foster
Quoted 12 lines · Dave Chinner
Quoted 10 lines · Brian Foster
Quoted 6 lines · Ben Myers
Quoted 4 lines
Quoted 4 lines
FWIW, given the background cleanup code can be trivially verified to work (open, apend, close, repeat, wait 5 minutes) and is the functionality that is needed in mainline, having something to test the ioctls should not stop the patchset from being merged.
Can we be assured that we'll get an xfstest for it eventually?
Absolutely. Getting a command into
xfs_ioto support such a test is now the top of my todo list with regard to XFS. :)
Quoted 7 lines
Quoted 3 lines
Here's a patch to the new
xfs_spacemanprogram I'm writing that adds control for these ioctls.Very cool, thanks. Catchy name for the tool as well, btw ;).
For some reason my mailer is stripping out the patch,
Probably because I simply added it inline below my sig. The mailer is probably dropping everything below the /^-- $/ line that marks the sig...
Quoted 4 lines
but my only
comment is with regard to minlen. Shouldn't that variable be handled as an unsigned?
Probably, but a ssize_t would be better, and ....
Quoted 2 lines
Now that I think of it, that makes me wonder if I should make that a 64-bit unsigned in
xfs_eofblocks..?
... yes, a __u64 would be better.
I've got a couple more comments now I've actually used and tested it, so I'll do that today....
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
In reply to Brian FosterQuoted 18 lines · Brian Foster
The
XFS_IOC_FREE_EOFBLOCKSioctl allows users to invoke an EOFBLOCKS scan. Thexfs_eofblocksstructure is defined to support the command parameters (scan mode).Signed-off-by Brian Foster <[email protected]>--- fs/xfs/xfs_fs.h | 15 +++++++++++++++ fs/xfs/xfs_icache.c | 5 +++-- fs/xfs/xfs_icache.h | 2 +- fs/xfs/xfs_ioctl.c | 16 ++++++++++++++++ 4 files changed, 35 insertions(+), 3 deletions(-)fs/xfs/xfs_fs.h +0
-0@@ -339,6 +339,20 @@ typedef struct xfs_error_injection {
fs/xfs/xfs_fs.h typedef struct xfs_error_injection { · line 349
Quoted 10 lines
fs/xfs/xfs_fs.h +8
-0/* +* Speculative preallocation trimming. +*/ +#define XFS_EOFBLOCKS_VERSION 1 +struct xfs_eofblocks { +__u32 eof_version; +__u32 eof_flags; +unsigned char pad[12 ]; +};
12 bytes of padding is a bit wierd at this point. It's problematic for 32bit userspace on 64 bit kernels, in that the size of the structure can end up different (i.e. 20 bytes on 32b, 24 bytes on 64b) depending on the architectures natural alignment.
I can also see that adding multiple extra variables to the structure are quite likely (e.g. per-ag control, start/end inode numbers, etc), so 12 bytes of padding really isn't sufficient, IMO. I'd tend to pad out to, say, 128 bytes rather than 32, just in case. i.e:
__u64 pad[15];
And then take away from this padding space as you add functioanlity in fucture patches.
This extra padding means the version number won't need to increase any time soon, as it will be a while before we run out of either padding or flag space, instead of as soon as we add a new function to the ioctl....
fs/xfs/xfs_fs.h typedef struct xfs_error_injection { · line 352
Quoted 3 lines
fs/xfs/xfs_fs.h +3
-0+ +/* eof_flags values */ +#define XFS_EOF_FLAGS_SYNC 0x01/* sync/wait mode scan */
I kind of prefer flags being defined by (1 << 0) style to keep larger flag numbers concise, but that's not a big deal.
Quoted 15 lines
fs/xfs/xfs_ioctl.c +1
-0@@ -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,21 @@ xfs_file_ioctl( error =xfs_errortag_clearall (mp,1 );return -error;
fs/xfs/xfs_ioctl.c xfs_file_ioctl( · line 1614
Quoted 10 lines
fs/xfs/xfs_ioctl.c +9
-0+case XFS_IOC_FREE_EOFBLOCKS : { +struct xfs_eofblocks eofb; +int flags; + +if (copy_from_user (&eofb, arg,sizeof (eofb))) +return -XFS_ERROR (EFAULT ); + +if (eofb.eof_version !=XFS_EOFBLOCKS_VERSION ) +return -XFS_ERROR (EINVAL );
Checking that no unsupported flags are set here is necessary. Also, checking the padding is zero is probably a good idea, as it will force applications to zero the structure properly before being able to use this interface properly....
fs/xfs/xfs_ioctl.c xfs_file_ioctl( · line 1616
Quoted 1 line
fs/xfs/xfs_ioctl.c +1
-0+ flags = (eofb.eof_flags &XFS_EOF_FLAGS_SYNC ) ?SYNC_WAIT :SYNC_TRYLOCK ;
Line if a bit too long. However, would it be better to place this inside xfs_icache_free_eofblocks()?
fs/xfs/xfs_ioctl.c xfs_file_ioctl( · line 1617
Quoted 1 line
fs/xfs/xfs_ioctl.c +1
-0+ error =xfs_icache_free_eofblocks (mp, flags, &eofb);
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Quoted 1 line · Dave Chinner
On Fri, Oct 05, 2012 at 10:17:12AM -0400, Brian Foster wrote:
...
Quoted 22 lines
fs/xfs/xfs_fs.h typedef struct xfs_error_injection { · line 349
Quoted 9 lines
/*
+ * Speculative preallocation trimming.
+ */fs/xfs/xfs_fs.h +6
-0+#define XFS_EOFBLOCKS_VERSION 1 +struct xfs_eofblocks { +__u32 eof_version; +__u32 eof_flags; +unsigned char pad[12 ]; +};12 bytes of padding is a bit wierd at this point. It's problematic for 32bit userspace on 64 bit kernels, in that the size of the structure can end up different (i.e. 20 bytes on 32b, 24 bytes on 64b) depending on the architectures natural alignment.
I can also see that adding multiple extra variables to the structure are quite likely (e.g. per-ag control, start/end inode numbers, etc), so 12 bytes of padding really isn't sufficient, IMO. I'd tend to pad out to, say, 128 bytes rather than 32, just in case. i.e:
__u64 pad[15];
Quoted 8 lines
And then take away from this padding space as you add functioanlity in fucture patches.
This extra padding means the version number won't need to increase any time soon, as it will be a while before we run out of either padding or flag space, instead of as soon as we add a new function to the ioctl....
Ok, I'll convert the file size parameter to a __u64 (as per discussed in the spaceman eofblocks command thread) and expand the padding.
Quoted 7 lines
fs/xfs/xfs_fs.h typedef struct xfs_error_injection { · line 352
Quoted 3 lines
fs/xfs/xfs_fs.h +3
-0+ +/* eof_flags values */ +#define XFS_EOF_FLAGS_SYNC 0x01/* sync/wait mode scan */ I kind of prefer flags being defined by (1 << 0) style to keep larger flag numbers concise, but that's not a big deal.
Eh, I find this cleaner than looking at the raw values as well.
Quoted 16 lines
Quoted 16 lines
fs/xfs/xfs_ioctl.c +1
-0@@ -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,21 @@ xfs_file_ioctl( error =xfs_errortag_clearall (mp,1 );return -error;
Quoted 15 lines
fs/xfs/xfs_ioctl.c xfs_file_ioctl( · line 1614
Quoted 9 lines
fs/xfs/xfs_ioctl.c +9
-0+case XFS_IOC_FREE_EOFBLOCKS : { +struct xfs_eofblocks eofb; +int flags; + +if (copy_from_user (&eofb, arg,sizeof (eofb))) +return -XFS_ERROR (EFAULT ); + +if (eofb.eof_version !=XFS_EOFBLOCKS_VERSION ) +return -XFS_ERROR (EINVAL );Checking that no unsupported flags are set here is necessary. Also, checking the padding is zero is probably a good idea, as it will force applications to zero the structure properly before being able to use this interface properly....
Ok.
Quoted 5 lines
fs/xfs/xfs_ioctl.c xfs_file_ioctl( · line 1616
Quoted 1 line
fs/xfs/xfs_ioctl.c +1
-0+ flags = (eofb.eof_flags &XFS_EOF_FLAGS_SYNC ) ?SYNC_WAIT :SYNC_TRYLOCK ;Line if a bit too long. However, would it be better to place this inside
xfs_icache_free_eofblocks()?
Are you suggesting to eliminate the flags parameter to xfs_icache_free_eofblocks? The reason for the current interface is that the background scan caller doesn't require the eofb parameter, so I decided to generalize the sync/wait parameter in the caller.
If we want to push it into xfs_icache_free_eofblocks(), I think it would be better at that point to eliminate the flags param and either infer SYNC_TRYLOCK on a NULL eofb or to require an eofb and pass one with a cleared XFS_EOF_FLAGS_SYNC from the background scan. Thoughts?
Brian
Quoted 6 lines
fs/xfs/xfs_ioctl.c xfs_file_ioctl( · line 1617
Quoted 1 line
fs/xfs/xfs_ioctl.c +1
-0+ error =xfs_icache_free_eofblocks (mp, flags, &eofb);Cheers,
Dave.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 06/10] xfs: add XFS_IOC_FREE_EOFBLOCKS ioctl
Quoted 11 lines · Brian Foster
Quoted 5 lines · Dave Chinner
fs/xfs/xfs_ioctl.c xfs_file_ioctl( · line 1616
Quoted 1 line · Brian Foster
fs/xfs/xfs_ioctl.c +1
-0+ flags = (eofb.eof_flags &XFS_EOF_FLAGS_SYNC ) ?SYNC_WAIT :SYNC_TRYLOCK ;Line if a bit too long. However, would it be better to place this inside
xfs_icache_free_eofblocks()?Are you suggesting to eliminate the flags parameter to
xfs_icache_free_eofblocks? The reason for the current interface is that the background scan caller doesn't require the eofb parameter, so I decided to generalize the sync/wait parameter in the caller.
That's on possibility. I was thinking more of flags = 0, and parsing the eofb structure for meaning inside xfs_icache_free_eofblocks(). i.e. it overrides flags.
Quoted 4 lines
If we want to push it into
xfs_icache_free_eofblocks(), I think it would be better at that point to eliminate the flags param and either inferSYNC_TRYLOCKon a NULL eofb or to require an eofb and pass one with a clearedXFS_EOF_FLAGS_SYNCfrom the background scan. Thoughts?
Sounds good - a NULL eofb meaning "default background scan" works for me. If we want anything other than default scan parameters, use the eofb to be precise....
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 7/10 xfs: make xfs_quota_type() non-static
In reply to Brian FosterMake xfs_quota_type() into a non-static function. This is to support quota ID filtering in the eofblocks ioctl().
--- fs/xfs/xfs_quota.h | 1 + fs/xfs/xfs_quotaops.c | 2 +- 2 files changed, 2 insertions(+), 1 deletions(-)
fs/xfs/xfs_quota.h +1 -0
@@ -379,6 +379,7 @@ static inline int xfs_trans_reserve_quota_bydquots(struct xfs_trans *tp,extern int xfs_qm_dqcheck (struct xfs_mount *,xfs_disk_dquot_t *,xfs_dqid_t ,uint ,uint ,char *);extern int xfs_mount_reset_sbqflags (struct xfs_mount *); +int xfs_quota_type (int );#endif /* __KERNEL__ */ #endif /* __XFS_QUOTA_H__ */
fs/xfs/xfs_quotaops.c +1 -1
@@ -28,7 +28,7 @@#include <linux/quota.h> -STATIC int +int xfs_quota_type (int type) {switch (type) {
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 07/10] xfs: make xfs_quota_type() non-static
Quoted 4 lines · Brian Foster
Make
xfs_quota_type()into a non-static function. This is to support quota ID filtering in the eofblocksioctl().Signed-off-by Brian Foster <[email protected]>
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 8/10 xfs: add quota id filtering to eofblocks scan
In reply to Brian FosterSupport quota ID filtering in the eofblocks scan. The caller must set the XFS_EOF_FLAGS_QUOTA flags bit, quota ID and quota type. The associated quota type must be enabled on the mounted filesystem.
--- fs/xfs/xfs_fs.h | 3 +++ fs/xfs/xfs_icache.c | 24 ++++++++++++++++++++++++ fs/xfs/xfs_ioctl.c | 8 ++++++++ 3 files changed, 35 insertions(+), 0 deletions(-)
fs/xfs/xfs_fs.h +3 -0
@@ -345,11 +345,14 @@ typedef struct xfs_error_injection {struct xfs_eofblocks {__u32 eof_version;__u32 eof_flags; +__u32 eof_q_id; +__u32 eof_q_type;unsigned char pad[12 ]; };/* eof_flags values */ #define XFS_EOF_FLAGS_SYNC 0x01/* sync/wait mode scan */ +#define XFS_EOF_FLAGS_QUOTA 0x02/* filter by quota id */ /*
fs/xfs/xfs_icache.c +24 -0
@@ -1171,6 +1171,22 @@ xfs_reclaim_inodes_count( } STATIC int +xfs_inode_match_quota_id ( +struct xfs_inode *ip, +struct xfs_eofblocks *eofb) +{ +unsigned int type =xfs_quota_type (eofb->eof_q_type); +if (type ==XFS_DQ_USER ) +return ip->i_d.di_uid == eofb->eof_q_id; +else if (type ==XFS_DQ_GROUP ) +return ip->i_d.di_gid == eofb->eof_q_id; +else if (type ==XFS_DQ_PROJ ) +return xfs_get_projid (ip) == eofb->eof_q_id; + +return 0 ; +} + +STATIC int xfs_inode_free_eofblocks( struct xfs_inode *ip, struct xfs_perag *pag,
@@ -1178,6 +1194,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 +1211,13 @@ xfs_inode_free_eofblocks( mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY))return 0 ; +if (eofb) { +/* filter by quota id */ +if (eofb->eof_flags &XFS_EOF_FLAGS_QUOTA && + !xfs_inode_match_quota_id (ip, eofb)) +return 0 ; + } + ret =xfs_free_eofblocks (ip->i_mount, ip, true);/* don't revisit the inode if we're not waiting */
fs/xfs/xfs_ioctl.c +8 -0
@@ -1613,6 +1613,14 @@ xfs_file_ioctl(if (eofb.eof_version !=XFS_EOFBLOCKS_VERSION )return -XFS_ERROR (EINVAL ); +if (eofb.eof_flags &XFS_EOF_FLAGS_QUOTA ) { +unsigned int type =xfs_quota_type (eofb.eof_q_type); +if ((type ==XFS_DQ_USER && !XFS_IS_UQUOTA_ON (mp)) || + (type ==XFS_DQ_GROUP && !XFS_IS_GQUOTA_ON (mp)) || + (type ==XFS_DQ_PROJ && !XFS_IS_PQUOTA_ON (mp))) +return -XFS_ERROR (EINVAL ); + } + flags = (eofb.eof_flags &XFS_EOF_FLAGS_SYNC ) ?SYNC_WAIT :SYNC_TRYLOCK ; error =xfs_icache_free_eofblocks (mp, flags, &eofb);return -error;
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 08/10] xfs: add quota id filtering to eofblocks scan
Quoted 3 lines · Brian Foster
Support quota ID filtering in the eofblocks scan. The caller must set the
XFS_EOF_FLAGS_QUOTAflags bit, quota ID and quota type. The associated quota type must be enabled on the mounted filesystem.
I'm wondering if this even needs quota enabled to filter based on a uid, gid, or prid?
The quota part of it seem irrelevant to the filtering that is being executed - we are only matching against the inode uid/gid/prid, not against dquots - and I can see situations where just being able to filter on a given uid/gid might be useful in a multi-user environment regardless of whether quotas are being used.
Indeed, even testing is made much easier if we don't have to juggle quota mount options to test the filtering....
Quoted 12 lines
fs/xfs/xfs_icache.c +4
-0@@ -1171,6 +1171,22 @@ xfs_reclaim_inodes_count( } STATIC int +xfs_inode_match_quota_id ( +struct xfs_inode *ip, +struct xfs_eofblocks *eofb) +{
fs/xfs/xfs_icache.c xfs_reclaim_inodes_count( · line 1187
Quoted 10 lines
fs/xfs/xfs_icache.c +10
-0+unsigned int type =xfs_quota_type (eofb->eof_q_type); +if (type ==XFS_DQ_USER ) +return ip->i_d.di_uid == eofb->eof_q_id; +else if (type ==XFS_DQ_GROUP ) +return ip->i_d.di_gid == eofb->eof_q_id; +else if (type ==XFS_DQ_PROJ ) +return xfs_get_projid (ip) == eofb->eof_q_id; + +return 0 ; +}
Why do you need xfs_quota_type() here? why not just:
switch (type) {
case XQM_USRQUOTA:
return ip->i_d.di_uid == eofb->eof_q_id;
case XQM_GRPQUOTA:
return ip->i_d.di_gid == eofb->eof_q_id;
case XQM_PRJQUOTA:
return xfs_get_projid(ip) == eofb->eof_q_id;
default:
break;
}
return 0;Quoted 19 lines
fs/xfs/xfs_icache.c +7
-0@@ -1194,6 +1211,13 @@ xfs_inode_free_eofblocks( mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY))return 0 ; +if (eofb) { +/* filter by quota id */ +if (eofb->eof_flags &XFS_EOF_FLAGS_QUOTA && + !xfs_inode_match_quota_id (ip, eofb)) +return 0 ; + } + ret =xfs_free_eofblocks (ip->i_mount, ip, true);/* don't revisit the inode if we're not waiting */ fs/xfs/xfs_ioctl.c +0
-0
fs/xfs/xfs_ioctl.c xfs_file_ioctl( · line 1622
Quoted 10 lines
fs/xfs/xfs_ioctl.c +7
-0@@ -1613,6 +1613,14 @@ xfs_file_ioctl(if (eofb.eof_version !=XFS_EOFBLOCKS_VERSION )return -XFS_ERROR (EINVAL ); +if (eofb.eof_flags &XFS_EOF_FLAGS_QUOTA ) { +unsigned int type =xfs_quota_type (eofb.eof_q_type); +if ((type ==XFS_DQ_USER && !XFS_IS_UQUOTA_ON (mp)) || + (type ==XFS_DQ_GROUP && !XFS_IS_GQUOTA_ON (mp)) || + (type ==XFS_DQ_PROJ && !XFS_IS_PQUOTA_ON (mp))) +return -XFS_ERROR (EINVAL ); + }
Again, I don't really see the reason for needing xfs_quota_type() here, and whether the quota check is relevant at all...
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 08/10] xfs: add quota id filtering to eofblocks scan
Quoted 8 lines · Dave Chinner
Quoted 3 lines · Brian Foster
Support quota ID filtering in the eofblocks scan. The caller must set the
XFS_EOF_FLAGS_QUOTAflags bit, quota ID and quota type. The associated quota type must be enabled on the mounted filesystem.I'm wondering if this even needs quota enabled to filter based on a uid, gid, or prid?
Not really...
Quoted 6 lines
The quota part of it seem irrelevant to the filtering that is being executed - we are only matching against the inode uid/gid/prid, not against dquots - and I can see situations where just being able to filter on a given uid/gid might be useful in a multi-user environment regardless of whether quotas are being used.
This is how my rfc version was implemented (with a comment to the same effect). I added the explicit checking in response to:
http://oss.sgi.com/archives/xfs/2012-09/msg00024.html
Quoted 3 lines
Indeed, even testing is made much easier if we don't have to juggle quota mount options to test the filtering....
I agree. I suppose the check can make a bit of sense if the current group/proj mode of the mount conflicts with the eofb request, but as you've outlined above, we're checking against the inode values so I don't think it introduces a functional problem.
Regardless, could you confirm your reasoning here with regard to the previous comments before I go and make this change? ;)
Quoted 25 lines
Quoted 12 lines
fs/xfs/xfs_icache.c +4
-0@@ -1171,6 +1171,22 @@ xfs_reclaim_inodes_count( } STATIC int +xfs_inode_match_quota_id ( +struct xfs_inode *ip, +struct xfs_eofblocks *eofb) +{fs/xfs/xfs_icache.c xfs_reclaim_inodes_count( · line 1187
Quoted 10 lines
fs/xfs/xfs_icache.c +10
-0+unsigned int type =xfs_quota_type (eofb->eof_q_type); +if (type ==XFS_DQ_USER ) +return ip->i_d.di_uid == eofb->eof_q_id; +else if (type ==XFS_DQ_GROUP ) +return ip->i_d.di_gid == eofb->eof_q_id; +else if (type ==XFS_DQ_PROJ ) +return xfs_get_projid (ip) == eofb->eof_q_id; + +return 0 ; +}Why do you need
xfs_quota_type()here? why not just:
Quoted 13 lines
switch (type) {
case XQM_USRQUOTA:
return ip->i_d.di_uid == eofb->eof_q_id;
case XQM_GRPQUOTA:
return ip->i_d.di_gid == eofb->eof_q_id;
case XQM_PRJQUOTA:
return xfs_get_projid(ip) == eofb->eof_q_id;
default:
break;
}
return 0;Technically we don't really need xfs_quota_type(). I just thought it cleaner to use the same mapping we use throughout XFS (i.e., I don't see those definitions used elsewhere in XFS)...
Quoted 22 lines
Quoted 22 lines
fs/xfs/xfs_icache.c +7
-0@@ -1194,6 +1211,13 @@ xfs_inode_free_eofblocks( mapping_tagged(VFS_I(ip)->i_mapping, PAGECACHE_TAG_DIRTY))return 0 ; +if (eofb) { +/* filter by quota id */ +if (eofb->eof_flags &XFS_EOF_FLAGS_QUOTA && + !xfs_inode_match_quota_id (ip, eofb)) +return 0 ; + } + ret =xfs_free_eofblocks (ip->i_mount, ip, true);/* don't revisit the inode if we're not waiting */ fs/xfs/xfs_ioctl.c +0
-0@@ -1613,6 +1613,14 @@ xfs_file_ioctl(if (eofb.eof_version !=XFS_EOFBLOCKS_VERSION )return -XFS_ERROR (EINVAL );
Quoted 11 lines
fs/xfs/xfs_ioctl.c xfs_file_ioctl( · line 1622
Quoted 7 lines
fs/xfs/xfs_ioctl.c +7
-0+if (eofb.eof_flags &XFS_EOF_FLAGS_QUOTA ) { +unsigned int type =xfs_quota_type (eofb.eof_q_type); +if ((type ==XFS_DQ_USER && !XFS_IS_UQUOTA_ON (mp)) || + (type ==XFS_DQ_GROUP && !XFS_IS_GQUOTA_ON (mp)) || + (type ==XFS_DQ_PROJ && !XFS_IS_PQUOTA_ON (mp))) +return -XFS_ERROR (EINVAL ); + }Again, I don't really see the reason for needing
xfs_quota_type()here, and whether the quota check is relevant at all...
Same comment as above... would you prefer I just use the XQM_ definitions and lose the xfs_quota_type() patch?
Brian
Quoted 4 lines
Cheers,
Dave.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 08/10] xfs: add quota id filtering to eofblocks scan
Quoted 19 lines · Brian Foster
Quoted 8 lines · Dave Chinner
Quoted 3 lines · Brian Foster
Support quota ID filtering in the eofblocks scan. The caller must set the
XFS_EOF_FLAGS_QUOTAflags bit, quota ID and quota type. The associated quota type must be enabled on the mounted filesystem.I'm wondering if this even needs quota enabled to filter based on a uid, gid, or prid?
Not really...
Quoted 6 lines
The quota part of it seem irrelevant to the filtering that is being executed - we are only matching against the inode uid/gid/prid, not against dquots - and I can see situations where just being able to filter on a given uid/gid might be useful in a multi-user environment regardless of whether quotas are being used.
Quoted 4 lines
This is how my rfc version was implemented (with a comment to the same effect). I added the explicit checking in response to:
Ok, that was in the context of "we need to be specific about what the ID is". Now the question is "is quota ID the right ID to use?". Different question. ;)
Quoted 8 lines
Quoted 3 lines
Indeed, even testing is made much easier if we don't have to juggle quota mount options to test the filtering....
I agree. I suppose the check can make a bit of sense if the current group/proj mode of the mount conflicts with the eofb request, but as you've outlined above, we're checking against the inode values so I don't think it introduces a functional problem.
Right, and if we even get the separate project quota inode patches merged, then all three can be valid at once. Indeed, that makes me ask the question - should we be able to filter on multiple IDs in a single pass (e.g. walk Jim's files in the jasper project)?
Seeing as it is just a filter, enabling the above (even though it would be rarely used) might make sense. i.e. separate field for each id. It's not like we have to keep the size of the structure to a minimum...
Cheers,
Dave.
Quoted 13 lines
Quoted 13 lines
Why do you need
xfs_quota_type()here? why not just:switch (type) { case XQM_USRQUOTA: return ip->i_d.di_uid == eofb->eof_q_id; case XQM_GRPQUOTA: return ip->i_d.di_gid == eofb->eof_q_id; case XQM_PRJQUOTA: return xfs_get_projid(ip) == eofb->eof_q_id; default: break; }
Quoted 6 lines
Quoted 2 lines
return 0;Technically we don't really need
xfs_quota_type(). I just thought it cleaner to use the same mapping we use throughout XFS (i.e., I don't see those definitions used elsewhere in XFS)...
XQM_* are the userspace XFS quota interface definitions. They are what xfs_quota uses. They just so happen to be the same as the generic quota definitions except the generic quotas don't define project quota types (hence the need for mapping). See include/uapi/linux/dqblk_xfs.h.
I just figured that rather than mapping something unknown to something known, just using something known in the first place is much simpler...
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 08/10] xfs: add quota id filtering to eofblocks scan
Quoted 20 lines · Dave Chinner
Quoted 19 lines · Brian Foster
Quoted 8 lines · Dave Chinner
Quoted 3 lines · Brian Foster
Support quota ID filtering in the eofblocks scan. The caller must set the
XFS_EOF_FLAGS_QUOTAflags bit, quota ID and quota type. The associated quota type must be enabled on the mounted filesystem.I'm wondering if this even needs quota enabled to filter based on a uid, gid, or prid?
Not really...
Quoted 6 lines
The quota part of it seem irrelevant to the filtering that is being executed - we are only matching against the inode uid/gid/prid, not against dquots - and I can see situations where just being able to filter on a given uid/gid might be useful in a multi-user environment regardless of whether quotas are being used.
Quoted 9 lines
Quoted 4 lines
This is how my rfc version was implemented (with a comment to the same effect). I added the explicit checking in response to:
Ok, that was in the context of "we need to be specific about what the ID is". Now the question is "is quota ID the right ID to use?". Different question. ;)
Fair enough. :) I just want to make sure we're on the same page. I'll take this as an Ok to remove the quota enabled checks. The resulting behavior will now be that quota ID filtering is supported regardless of whether quotas are enabled on the targeted mount.
Quoted 9 lines
Quoted 8 lines
Quoted 3 lines
Indeed, even testing is made much easier if we don't have to juggle quota mount options to test the filtering....
I agree. I suppose the check can make a bit of sense if the current group/proj mode of the mount conflicts with the eofb request, but as you've outlined above, we're checking against the inode values so I don't think it introduces a functional problem.
Quoted 5 lines
Right, and if we even get the separate project quota inode patches merged, then all three can be valid at once. Indeed, that makes me ask the question - should we be able to filter on multiple IDs in a single pass (e.g. walk Jim's files in the jasper project)?
That sounds vaguely familiar, perhaps I've skimmed over such a patchset, but it's not immediately clear to me. Interesting idea nonetheless and I see no idea why we couldn't support such a mechanism if the id's are independent...
Quoted 5 lines
Seeing as it is just a filter, enabling the above (even though it would be rarely used) might make sense. i.e. separate field for each id. It's not like we have to keep the size of the structure to a minimum...
... but that is also starting to further complicate the filtering and testing required. I'm also not quite sure how we would currently specify a union of id's in the flags given that we migrated towards the use of the real quota type field (eof_q_type) rather than my original approach of specifying the quota id type as a flag.
Would we be sufficiently prepared for the future if we broke the id into three fields, i.e.:
struct xfs_eofblocks {
...
__u32 eof_uquota_id;
__u32 eof_gquota_id;
__u32 eof_pquota_id;
__u32 eof_q_type;
...
};... but the in kernel implementation remains as is by using the associated field based on the quota type? To be honest, even if we had a way to specify multiple id's, I think I would prefer to leave the implementation as is and do the enhanced filtering in future patches (e.g., get the data structure right, but EINVAL for now if multiple id's are flagged), if for nothing else than the testing I've already done against this implementation. But I suspect if there isn't currently a standard way to specify multiple quota types, we're fated to have to update the structure with a new version anyways..?
Perhaps I need to take a look at this project quota inode patchset you refer to...
Quoted 3 lines
Cheers,
Dave.
Heh... almost stopped reading here.. ;)
Quoted 26 lines
Quoted 13 lines
Quoted 13 lines
Why do you need
xfs_quota_type()here? why not just:switch (type) { case XQM_USRQUOTA: return ip->i_d.di_uid == eofb->eof_q_id; case XQM_GRPQUOTA: return ip->i_d.di_gid == eofb->eof_q_id; case XQM_PRJQUOTA: return xfs_get_projid(ip) == eofb->eof_q_id; default: break; }Quoted 6 lines
Quoted 2 lines
return 0;Technically we don't really need
xfs_quota_type(). I just thought it cleaner to use the same mapping we use throughout XFS (i.e., I don't see those definitions used elsewhere in XFS)...XQM_* are the userspace XFS quota interface definitions. They are what
xfs_quotauses. They just so happen to be the same as the generic quota definitions except the generic quotas don't define project quota types (hence the need for mapping). Seeinclude/uapi/linux/dqblk_xfs.h.
Quoted 4 lines
I just figured that rather than mapping something unknown to something known, just using something known in the first place is much simpler...
Right, at the time I think I dug through the various quota type definitions, saw that we provided this mapping function and got the impression we should be consistent throughout the filesystem. But I think your point here is that the expected input should be the definitions we already define for userspace whereas I was thinking the generic definitions were ubiquitous from userspace.
Now that I have a quick look, I don't see the XQM_* definitions used anywhere in xfsprogs or the kernel. I see XFS_{USER,GROUP,PROJ}_QUOTA defined and mapped to USRQUOTA/GRPQUOTA/PRJQUOTA in xfsprogs, but then the former not defined in the kernel. :/
Brian
Quoted 4 lines
Cheers,
Dave.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 08/10] xfs: add quota id filtering to eofblocks scan
Quoted 31 lines · Brian Foster
Quoted 20 lines · Dave Chinner
Quoted 19 lines · Brian Foster
Quoted 8 lines · Dave Chinner
Quoted 3 lines · Brian Foster
Support quota ID filtering in the eofblocks scan. The caller must set the
XFS_EOF_FLAGS_QUOTAflags bit, quota ID and quota type. The associated quota type must be enabled on the mounted filesystem.I'm wondering if this even needs quota enabled to filter based on a uid, gid, or prid?
Not really...
Quoted 6 lines
The quota part of it seem irrelevant to the filtering that is being executed - we are only matching against the inode uid/gid/prid, not against dquots - and I can see situations where just being able to filter on a given uid/gid might be useful in a multi-user environment regardless of whether quotas are being used.
Quoted 9 lines
Quoted 4 lines
This is how my rfc version was implemented (with a comment to the same effect). I added the explicit checking in response to:
Ok, that was in the context of "we need to be specific about what the ID is". Now the question is "is quota ID the right ID to use?". Different question. ;)
Quoted 4 lines
Fair enough. :) I just want to make sure we're on the same page. I'll take this as an Ok to remove the quota enabled checks. The resulting behavior will now be that quota ID filtering is supported regardless of whether quotas are enabled on the targeted mount.
Right, and that point it isn't a quota ID - it's a uid, gid or prid we are filtering on....
Quoted 11 lines
Quoted 5 lines
Seeing as it is just a filter, enabling the above (even though it would be rarely used) might make sense. i.e. separate field for each id. It's not like we have to keep the size of the structure to a minimum...
... but that is also starting to further complicate the filtering and testing required. I'm also not quite sure how we would currently specify a union of id's in the flags given that we migrated towards the use of the real quota type field (
eof_q_type) rather than my original approach of specifying the quota id type as a flag.
Well, quota type just goes away completely - it's irrelevant.
Quoted 10 lines
Would we be sufficiently prepared for the future if we broke the id into three fields, i.e.:
struct xfs_eofblocks { ... __u32 eof_uquota_id; __u32 eof_gquota_id; __u32 eof_pquota_id; __u32 eof_q_type; ...
I'd suggest uid, gid and prid as the types, dropping the quota type altogether. Then add specific flags to indicate each field is set rather than a flag to say "look at the q_type field for which id field to read"...
i.e. the API is indepedent of quota configurations and quota IDs, but is still capable of expressing such control when required.
Quoted 6 lines
... but the in kernel implementation remains as is by using the associated field based on the quota type? To be honest, even if we had a way to specify multiple id's, I think I would prefer to leave the implementation as is and do the enhanced filtering in future patches (e.g., get the data structure right, but EINVAL for now if multiple id's are flagged),
Sure, that's fine.
Quoted 4 lines
if for nothing else than the testing I've already done against this implementation. But I suspect if there isn't currently a standard way to specify multiple quota types, we're fated to have to update the structure with a new version anyways..?
There is a standard way of recording a *single* "quota ID" in kernel space now - see quota.h:
struct kqid { /* Type in which we store the quota identifier */
union {
kuid_t uid;
kgid_t gid;
kprojid_t projid;
};
enum quota_type type; /* USRQUOTA (uid) or GRPQUOTA (gid) or PRJQUOTA (projid) */
}and a bunch or wrappers for manipulating them. That's the sort of thing that we'd need to build internally for filtering so we end up with user namespace support. This is shiny and new, just merged in 3.7-rc1....
Quoted 11 lines
Quoted 10 lines
XQM_* are the userspace XFS quota interface definitions. They are what
xfs_quotauses. They just so happen to be the same as the generic quota definitions except the generic quotas don't define project quota types (hence the need for mapping). Seeinclude/uapi/linux/dqblk_xfs.h.I just figured that rather than mapping something unknown to something known, just using something known in the first place is much simpler...
Quoted 6 lines
Right, at the time I think I dug through the various quota type definitions, saw that we provided this mapping function and got the impression we should be consistent throughout the filesystem. But I think your point here is that the expected input should be the definitions we already define for userspace whereas I was thinking the generic definitions were ubiquitous from userspace.
Well, the generic definitions never defined project quota. If you look now in the 3.7 codebase you'll see that PRJQUOTA has been added to include/linux/quota.h, as has a kprojid_t type. Hence project quota IDs are now considered a first class quota citizen by the generic quota *kernel* code. However, include/uapi/linux/quota.h is completely unchanged, so the generic quota userspace interface still knows nothing about project IDs, which means the only actual user facing definition is still in include/uapi/linux/dqblks_xfs.h - XQM_PRJQUOTA. Hence we assume a quota ID that doesn't match anything the generic quota understands to be a project quota as that's the only way stuff works in a predictable, reliable manner...
The origin of this mess are historic as XFS brought along it's own quota implementation and API from Irix years ago because the linux quota subsystem was not robust or fully featured enough to even consider integration at the time (e.g. generic quotas didn't even support journalled quotas). So, yeah, a mess but one that is slowly getting cleaned up.
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 08/10] xfs: add quota id filtering to eofblocks scan
Quoted 4 lines · Dave Chinner
Quoted 3 lines · Brian Foster
Quoted 2 lines · Dave Chinner
Quoted 1 line · Brian Foster
On 10/22/2012 09:42 PM, Dave Chinner wrote:
...
Quoted 25 lines
Quoted 11 lines
Quoted 5 lines
Seeing as it is just a filter, enabling the above (even though it would be rarely used) might make sense. i.e. separate field for each id. It's not like we have to keep the size of the structure to a minimum...
... but that is also starting to further complicate the filtering and testing required. I'm also not quite sure how we would currently specify a union of id's in the flags given that we migrated towards the use of the real quota type field (
eof_q_type) rather than my original approach of specifying the quota id type as a flag.Well, quota type just goes away completely - it's irrelevant.
Quoted 10 lines
Would we be sufficiently prepared for the future if we broke the id into three fields, i.e.:
struct xfs_eofblocks { ... __u32 eof_uquota_id; __u32 eof_gquota_id; __u32 eof_pquota_id; __u32 eof_q_type; ...
Quoted 5 lines
I'd suggest uid, gid and prid as the types, dropping the quota type altogether. Then add specific flags to indicate each field is set rather than a flag to say "look at the
q_typefield for which id field to read"...
Ah, I see your point now. The filter parameters basically become inode-centric rather than quota-centric. This makes sense.
Quoted 29 lines
i.e. the API is indepedent of quota configurations and quota IDs, but is still capable of expressing such control when required.
Quoted 6 lines
... but the in kernel implementation remains as is by using the associated field based on the quota type? To be honest, even if we had a way to specify multiple id's, I think I would prefer to leave the implementation as is and do the enhanced filtering in future patches (e.g., get the data structure right, but EINVAL for now if multiple id's are flagged),
Sure, that's fine.
Quoted 4 lines
if for nothing else than the testing I've already done against this implementation. But I suspect if there isn't currently a standard way to specify multiple quota types, we're fated to have to update the structure with a new version anyways..?
There is a standard way of recording a *single* "quota ID" in kernel space now - see
quota.h:struct kqid { /* Type in which we store the quota identifier */
union { kuid_t uid; kgid_t gid; kprojid_t projid; }; enum quota_type type; /* USRQUOTA (uid) or GRPQUOTA (gid) or PRJQUOTA (projid) */ }
Quoted 5 lines
and a bunch or wrappers for manipulating them. That's the sort of thing that we'd need to build internally for filtering so we end up with user namespace support. This is shiny and new, just merged in 3.7-rc1....
Ok, I do remember taking a cursory look at this set. I didn't realize it was merged. Thanks for the explanation.
Brian
Quoted 37 lines
Quoted 11 lines
Quoted 10 lines
XQM_* are the userspace XFS quota interface definitions. They are what
xfs_quotauses. They just so happen to be the same as the generic quota definitions except the generic quotas don't define project quota types (hence the need for mapping). Seeinclude/uapi/linux/dqblk_xfs.h.I just figured that rather than mapping something unknown to something known, just using something known in the first place is much simpler...
Quoted 6 lines
Right, at the time I think I dug through the various quota type definitions, saw that we provided this mapping function and got the impression we should be consistent throughout the filesystem. But I think your point here is that the expected input should be the definitions we already define for userspace whereas I was thinking the generic definitions were ubiquitous from userspace.
Well, the generic definitions never defined project quota. If you look now in the 3.7 codebase you'll see that PRJQUOTA has been added to
include/linux/quota.h, as has akprojid_ttype. Hence project quota IDs are now considered a first class quota citizen by the generic quota *kernel* code. However,include/uapi/linux/quota.his completely unchanged, so the generic quota userspace interface still knows nothing about project IDs, which means the only actual user facing definition is still ininclude/uapi/linux/dqblks_xfs.h-XQM_PRJQUOTA. Hence we assume a quota ID that doesn't match anything the generic quota understands to be a project quota as that's the only way stuff works in a predictable, reliable manner...The origin of this mess are historic as XFS brought along it's own quota implementation and API from Irix years ago because the linux quota subsystem was not robust or fully featured enough to even consider integration at the time (e.g. generic quotas didn't even support journalled quotas). So, yeah, a mess but one that is slowly getting cleaned up.
Quoted 4 lines
Cheers,
Dave.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 9/10 xfs: add minimum file size filtering to eofblocks scan
In reply to Brian FosterSupport 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.
--- fs/xfs/xfs_fs.h | 2 ++ fs/xfs/xfs_icache.c | 5 +++++ 2 files changed, 7 insertions(+), 0 deletions(-)
fs/xfs/xfs_fs.h +2 -0
@@ -347,12 +347,14 @@ struct xfs_eofblocks {__u32 eof_flags;__u32 eof_q_id;__u32 eof_q_type; +__u32 eof_min_file_size;unsigned char pad[12 ]; };/* eof_flags values */ #define XFS_EOF_FLAGS_SYNC 0x01/* sync/wait mode scan */ #define XFS_EOF_FLAGS_QUOTA 0x02/* filter by quota id */ +#define XFS_EOF_FLAGS_MINFILESIZE 0x04/* filter by min file size */ /*
fs/xfs/xfs_icache.c +5 -0
@@ -1216,6 +1216,11 @@ xfs_inode_free_eofblocks(if (eofb->eof_flags &XFS_EOF_FLAGS_QUOTA && !xfs_inode_match_quota_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);
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 09/10] xfs: add minimum file size filtering to eofblocks scan
Quoted 5 lines · Brian Foster
Support minimum file size filtering in the eofblocks scan. The caller must set the
XFS_EOF_FLAGS_MINFILESIZEflags bit and minimum file size value in bytes.Signed-off-by Brian Foster <[email protected]>
Looks good.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
PATCH v5 10/10 xfs: add background scanning to clear eofblocks inodes
In reply to Brian FosterCreate 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 'background_prealloc_discard_period' tunable (default to 5m). The background scanner performs unfiltered, best effort scans (which skips inodes under lock contention or with a dirty cache mapping).
--- fs/xfs/xfs_globals.c | 1 + 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, 56 insertions(+), 0 deletions(-)
fs/xfs/xfs_globals.c +1 -0
@@ -40,4 +40,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, 7200}, };
fs/xfs/xfs_icache.c +29 -0
@@ -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,SYNC_TRYLOCK ,NULL ); +xfs_queue_eofblocks (mp); +} + int xfs_inode_ag_iterator( struct xfs_mount *mp,
@@ -1268,6 +1294,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_); }
fs/xfs/xfs_icache.h +1 -0
@@ -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 *,int ,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,
fs/xfs/xfs_linux.h +1 -0
@@ -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)
fs/xfs/xfs_mount.c +2 -0
@@ -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);
fs/xfs/xfs_mount.h +3 -0
@@ -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;/*
fs/xfs/xfs_super.c +9 -0
@@ -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 voidxfs_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);
@@ -1375,6 +1383,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;
fs/xfs/xfs_sysctl.c +9 -0
@@ -202,6 +202,15 @@ static ctl_table xfs_table[] = { .extra1 = &xfs_params.fstrm_timer.min, .extra2 = &xfs_params.fstrm_timer.max, }, + { + .procname = "background_prealloc_discard_period", + .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 {
fs/xfs/xfs_sysctl.h +1 -0
@@ -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;/*
Signature · 6 lines
1.7.7.6 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Re: [PATCH v5 10/10] xfs: add background scanning to clear eofblocks inodes
Quoted 7 lines · Brian Foster
Create a new mount workqueue and
delayed_workto 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 '
background_prealloc_discard_period' tunable (default to 5m). The
"discard" - probably a bad idea to use a word that is associated with similar but different functionality (i.e. mount -o discard).
Something like "speculative_prealloc_lifetime" might be a better way of describing what it defines. i.e. speculative prealloc won't be kept longer than this period on clean inodes. That keeps the sysctl function independent of the underlying implementation, and it also means we can use it as a catchall for any future speculative allocation functionality we decide to add....
....
fs/xfs/xfs_globals.c xfs_param_t xfs_params = { · line 43
Quoted 9 lines
fs/xfs/xfs_globals.c +1
-0@@ -40,4 +40,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, 7200},
2 hours as the maximum might be too short for some people. e.g. once a day might be all that some people will want this to happen because they have slowly growing log files - they stay in cache, will most likely trigger the "keep prealloc" heuristic, but can often go 5 minutes without being modified.
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Quoted 11 lines · Brian Foster
Hi all,
This is v3 of the speculative preallocation inode tracking patchset. This functionality tracks inodes with post-EOF speculative preallocation for the purpose of background and on-demand trimming.
Background scanning occurs on a longish interval (5 minutes by default) and in a best-effort mode (i.e., inodes are skipped due to lock contention or dirty cache). The intent is to clear up post-EOF blocks on inodes that might have allocations hanging around due to open-write-close sequences (NFS).
Quoted 7 lines
On demand scanning is provided via a new ioctl and supports various parameters such as scan mode, filtering by quota id and minimum file size. A pending use case for on demand scanning is for accurate quota accounting via the gluster scale out filesystem (i.e., to free up preallocated space when near a usage limit).
Brian
The series looks great.
I am just curious, what is the reason for the padding in the xfs_eofblocks structure?
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 26 lines · Mark Tinguely
Quoted 25 lines · Brian Foster
Hi all,
This is v3 of the speculative preallocation inode tracking patchset. This functionality tracks inodes with post-EOF speculative preallocation for the
purpose of background and on-demand trimming.Background scanning occurs on a longish interval (5 minutes by default) and in
a best-effort mode (i.e., inodes are skipped due to lock contention or dirty
cache). The intent is to clear up post-EOF blocks on inodes that might have
allocations hanging around due to open-write-close sequences (NFS).On demand scanning is provided via a new ioctl and supports various parameters
such as scan mode, filtering by quota id and minimum file size. A pending use
case for on demand scanning is for accurate quota accounting via the gluster
scale out filesystem (i.e., to free up preallocated space when near a usage
limit).
Quoted 4 lines
Quoted 1 line
Brian
The series looks great.
Hi Mark,
Thanks for the review.
Quoted 3 lines
I am just curious, what is the reason for the padding in the
xfs_eofblocksstructure?
I added the padding in response to review on an early revision of the set:
http://oss.sgi.com/archives/xfs/2012-09/msg00024.html
The purpose is to allow adding fields to the control structure down the road without breaking existing binaries.
Brian
Quoted 1 line
Reviewed-by Mark Tinguely <[email protected]>
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 40 lines · Brian Foster
Quoted 26 lines · Mark Tinguely
Quoted 25 lines · Brian Foster
Hi all,
This is v3 of the speculative preallocation inode tracking patchset. This functionality tracks inodes with post-EOF speculative preallocation for the
purpose of background and on-demand trimming.Background scanning occurs on a longish interval (5 minutes by default) and in
a best-effort mode (i.e., inodes are skipped due to lock contention or dirty
cache). The intent is to clear up post-EOF blocks on inodes that might have
allocations hanging around due to open-write-close sequences (NFS).On demand scanning is provided via a new ioctl and supports various parameters
such as scan mode, filtering by quota id and minimum file size. A pending use
case for on demand scanning is for accurate quota accounting via the gluster
scale out filesystem (i.e., to free up preallocated space when near a usage
limit).Quoted 4 lines
Quoted 1 line
Brian
The series looks great.
Hi Mark,
Thanks for the review.
Quoted 3 lines
I am just curious, what is the reason for the padding in the
xfs_eofblocksstructure?
Quoted 11 lines
I added the padding in response to review on an early revision of the set:
http://oss.sgi.com/archives/xfs/2012-09/msg00024.html
The purpose is to allow adding fields to the control structure down the road without breaking existing binaries.
Brian
Quoted 1 line
Reviewed-by Mark Tinguely<[email protected]>
Thank-you for the information.
I would think that changing the number of arguments would also involving changing the version number. The kernel should know that version 1 copies in 16 bytes, version 2 copies in 16+t bytes, version n copies in 16+n bytes...
Not at all a big deal, (16 used and 12 padding = ) 28 bytes was an odd number and it got my curiosity up. I suspected it was part a plan of yours and Pinky to take over the world. :)
Nice feature. I jury-rigged a ioctl to test and it works great. I look forwarded to seeing this in xfs_io.
--Mark.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 5 lines · Mark Tinguely
Not at all a big deal, (16 used and 12 padding = ) 28 bytes was an odd number and it got my curiosity up. I suspected it was part a plan of yours and Pinky to take over the world. :)
Ha-ha. never-mind. I am foiled again by my inability to count past 4, or stupidity of counting using diff files.
--Mark.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 10 lines · Mark Tinguely
Quoted 9 lines · Brian Foster
Quoted 3 lines · Mark Tinguely
I am just curious, what is the reason for the padding in the
xfs_eofblocksstructure?I added the padding in response to review on an early revision of the set:
Quoted 7 lines
Quoted 2 lines
The purpose is to allow adding fields to the control structure down the road without breaking existing binaries.
Thank-you for the information.
I would think that changing the number of arguments would also involving changing the version number.
Yes, it usually does.
Quoted 3 lines
The kernel should know
that version 1 copies in 16 bytes, version 2 copies in 16+t bytes, version n copies in 16+n bytes...
Gets messy, pretty quickly. Versioning and padding user facing structures makes life a lot easy when it comes to extending interfaces. 15-20 years of support for an ioctl is a long time, and that's the sort of time frame we need to think about. How to make it easy to maintain and extend over a long period of time. We should always version and pad user facing ioctl structures for this reason.
Further, assuming that userspace knows exactly the right size for a given feature is problematic. If there's only one structure type for userspace to use, then it's likely they'll get it right. If there's a different structure for every version of the ioctl, then it's likely they'll get it wrong.
And we get validation wrong in the kernel, too. The kernel must validate the size of the structure as being correct given the version number, and that gets hard to validate and easy to get wrong when you have a different structure for every version that exists.
See, for example, struct xfs_fsop_geom_t, and XFS_IOC_FSGEOMETRY_V1/ XFS_IOC_FSGEOMETRY. The originaly was an unversioned structure with no padding, and when the V2 log format came along, the structure had to be extended and a new ioctl added to support it. Internally they both used the same struture, but the copy-in/out were different and initialisation was different. The result was leaking unitialised data to userspace because we didn't get it right. (c4d0c3b "xfs:
prevent leaking uninitialized stack memory in FSGEOMETRY_V1")
At least the new xfs_fsops_geom structure has a version number in it so we don't have to add a new ioctl to extend it further. However, it still doesn't have any padding so any further extensions will have to be very careful to avoid structure size mismatches. This could have been avoided is some padding was added as the time the version number was added....
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Hey Brian,
Quoted 1 line · Brian Foster
This is v3 of the speculative preallocation inode tracking patchset.
I was going to pull this in based upon Mark's review, but it looks like Dave still has some questions related to patches 5, 8, and 10. If you can address those items we can proceed. I think at this point there is not a need to repost the entire series... just keep any updates in this thread.
Regards,
Ben
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs