xfs: Avoid inodes in reclaim when flushing from inode cache
authorDave Chinner <david@fromorbit.com>
Thu, 11 Mar 2010 22:42:09 +0000 (09:42 +1100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 26 Apr 2010 14:41:15 +0000 (07:41 -0700)
commit 018027be90a6946e8cf3f9b17b5582384f7ed117 upstream

The reclaim code will handle flushing of dirty inodes before reclaim
occurs, so avoid them when determining whether an inode is a
candidate for flushing to disk when walking the radix trees.  This
is based on a test patch from Christoph Hellwig.

Signed-off-by: Dave Chinner <david@fromorbit.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Alex Elder <aelder@sgi.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/xfs/linux-2.6/xfs_sync.c

index 63c585e68e771c2d46e7b2f017d3799e0bd570fc..a80371e4af2efd9e9e9326deb29ef10c2731a813 100644 (file)
@@ -179,26 +179,31 @@ xfs_sync_inode_valid(
        struct xfs_perag        *pag)
 {
        struct inode            *inode = VFS_I(ip);
+       int                     error = EFSCORRUPTED;
 
        /* nothing to sync during shutdown */
-       if (XFS_FORCED_SHUTDOWN(ip->i_mount)) {
-               read_unlock(&pag->pag_ici_lock);
-               return EFSCORRUPTED;
-       }
+       if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+               goto out_unlock;
 
-       /* If we can't get a reference on the inode, it must be in reclaim. */
-       if (!igrab(inode)) {
-               read_unlock(&pag->pag_ici_lock);
-               return ENOENT;
-       }
-       read_unlock(&pag->pag_ici_lock);
+       /* avoid new or reclaimable inodes. Leave for reclaim code to flush */
+       error = ENOENT;
+       if (xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIMABLE | XFS_IRECLAIM))
+               goto out_unlock;
 
-       if (is_bad_inode(inode) || xfs_iflags_test(ip, XFS_INEW)) {
+       /* If we can't grab the inode, it must on it's way to reclaim. */
+       if (!igrab(inode))
+               goto out_unlock;
+
+       if (is_bad_inode(inode)) {
                IRELE(ip);
-               return ENOENT;
+               goto out_unlock;
        }
 
-       return 0;
+       /* inode is valid */
+       error = 0;
+out_unlock:
+       read_unlock(&pag->pag_ici_lock);
+       return error;
 }
 
 STATIC int