]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
xfs: xfs_iflush_cluster has range issues
authorDave Chinner <dchinner@redhat.com>
Wed, 18 May 2016 04:09:13 +0000 (14:09 +1000)
committerDave Chinner <david@fromorbit.com>
Wed, 18 May 2016 04:09:13 +0000 (14:09 +1000)
xfs_iflush_cluster() does a gang lookup on the radix tree, meaning
it can find inodes beyond the current cluster if there is sparse
cache population. gang lookups return results in ascending index
order, so stop trying to cluster inodes once the first inode outside
the cluster mask is detected.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <david@fromorbit.com>
fs/xfs/xfs_inode.c

index e3b27982b3b26f5b6c52acf5e315bf5613833486..6c746d79925ee3882b45bd31aa5af306ebf7220c 100644 (file)
@@ -3207,11 +3207,20 @@ xfs_iflush_cluster(
                 */
                spin_lock(&iq->i_flags_lock);
                if (!iq->i_ino ||
-                   __xfs_iflags_test(iq, XFS_ISTALE) ||
-                   (XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) {
+                   __xfs_iflags_test(iq, XFS_ISTALE)) {
                        spin_unlock(&iq->i_flags_lock);
                        continue;
                }
+
+               /*
+                * Once we fall off the end of the cluster, no point checking
+                * any more inodes in the list because they will also all be
+                * outside the cluster.
+                */
+               if ((XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) {
+                       spin_unlock(&iq->i_flags_lock);
+                       break;
+               }
                spin_unlock(&iq->i_flags_lock);
 
                /*