summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2016-05-18 14:09:13 +1000
committerDave Chinner <david@fromorbit.com>2016-05-18 14:09:13 +1000
commit5a90e53e8124d3ebe4b2a6309fa3c3225c23a62a (patch)
tree8f7e49a8ade7b8837c8625f765ef2aaaa450a48e /fs
parent8a17d7ddedb4d9031f046ae0e97c40b46aa69db5 (diff)
downloadlinux-5a90e53e8124d3ebe4b2a6309fa3c3225c23a62a.tar.gz
linux-5a90e53e8124d3ebe4b2a6309fa3c3225c23a62a.tar.xz
xfs: xfs_iflush_cluster has range issues
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_inode.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index e3b27982b3b2..6c746d79925e 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -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);
/*