From: Darrick J. Wong <djwong@xxxxxxxxxx> Perform background block preallocation gc scans more efficiently by walking the incore inode tree once. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- fs/xfs/xfs_icache.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 92fcec349054..4f68375cf873 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -31,6 +31,9 @@ */ #define XFS_INODE_WALK_INEW_WAIT 0x1 /* wait on new inodes */ +STATIC int xfs_inode_free_eofblocks(struct xfs_inode *ip, void *args); +STATIC int xfs_inode_free_cowblocks(struct xfs_inode *ip, void *args); + /* * Allocate and initialise an xfs_inode. */ @@ -950,19 +953,29 @@ xfs_queue_blockgc( rcu_read_unlock(); } +/* Scan one incore inode for block preallocations that we can remove. */ +static int +xfs_blockgc_scan_inode( + struct xfs_inode *ip, + void *args) +{ + int error; + + error = xfs_inode_free_eofblocks(ip, args); + if (error && error != -EAGAIN) + return error; + + return xfs_inode_free_cowblocks(ip, args); +} + /* Scan all incore inodes for block preallocations that we can remove. */ static inline int xfs_blockgc_scan( struct xfs_mount *mp, struct xfs_eofblocks *eofb) { - int error; - - error = xfs_icache_free_eofblocks(mp, eofb); - if (error && error != -EAGAIN) - return error; - - return xfs_icache_free_cowblocks(mp, eofb); + return __xfs_inode_walk(mp, 0, xfs_blockgc_scan_inode, eofb, + XFS_ICI_BLOCK_GC_TAG); } /* Background worker that trims preallocated space. */