aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2014-07-24 05:40:22 -0400
committerDave Chinner <david@fromorbit.com>2014-07-24 05:40:22 -0400
commit5400da7dc0862d73523691038c044535f518a57f (patch)
tree574a664859a18888f8d3d6cf2b108c8c61d76736 /fs/xfs
parent2451337dd043901b5270b7586942abe564443e3d (diff)
xfs: add scan owner field to xfs_eofblocks
From: Brian Foster <bfoster@redhat.com> The scan owner field represents an optional inode number that is responsible for the current scan. The purpose is to identify that an inode is under iolock and as such, the iolock shouldn't be attempted when trimming eofblocks. This is an internal only field. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_icache.c13
-rw-r--r--fs/xfs/xfs_icache.h2
2 files changed, 14 insertions, 1 deletions
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 08ba4c6e1359..6e522ff5a006 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -1211,6 +1211,9 @@ xfs_inode_free_eofblocks(
1211{ 1211{
1212 int ret; 1212 int ret;
1213 struct xfs_eofblocks *eofb = args; 1213 struct xfs_eofblocks *eofb = args;
1214 bool need_iolock = true;
1215
1216 ASSERT(!eofb || (eofb && eofb->eof_scan_owner != 0));
1214 1217
1215 if (!xfs_can_free_eofblocks(ip, false)) { 1218 if (!xfs_can_free_eofblocks(ip, false)) {
1216 /* inode could be preallocated or append-only */ 1219 /* inode could be preallocated or append-only */
@@ -1235,9 +1238,17 @@ xfs_inode_free_eofblocks(
1235 if (eofb->eof_flags & XFS_EOF_FLAGS_MINFILESIZE && 1238 if (eofb->eof_flags & XFS_EOF_FLAGS_MINFILESIZE &&
1236 XFS_ISIZE(ip) < eofb->eof_min_file_size) 1239 XFS_ISIZE(ip) < eofb->eof_min_file_size)
1237 return 0; 1240 return 0;
1241
1242 /*
1243 * A scan owner implies we already hold the iolock. Skip it in
1244 * xfs_free_eofblocks() to avoid deadlock. This also eliminates
1245 * the possibility of EAGAIN being returned.
1246 */
1247 if (eofb->eof_scan_owner == ip->i_ino)
1248 need_iolock = false;
1238 } 1249 }
1239 1250
1240 ret = xfs_free_eofblocks(ip->i_mount, ip, true); 1251 ret = xfs_free_eofblocks(ip->i_mount, ip, need_iolock);
1241 1252
1242 /* don't revisit the inode if we're not waiting */ 1253 /* don't revisit the inode if we're not waiting */
1243 if (ret == -EAGAIN && !(flags & SYNC_WAIT)) 1254 if (ret == -EAGAIN && !(flags & SYNC_WAIT))
diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
index 6250430d609c..98687af6a99d 100644
--- a/fs/xfs/xfs_icache.h
+++ b/fs/xfs/xfs_icache.h
@@ -27,6 +27,7 @@ struct xfs_eofblocks {
27 kgid_t eof_gid; 27 kgid_t eof_gid;
28 prid_t eof_prid; 28 prid_t eof_prid;
29 __u64 eof_min_file_size; 29 __u64 eof_min_file_size;
30 xfs_ino_t eof_scan_owner;
30}; 31};
31 32
32#define SYNC_WAIT 0x0001 /* wait for i/o to complete */ 33#define SYNC_WAIT 0x0001 /* wait for i/o to complete */
@@ -84,6 +85,7 @@ xfs_fs_eofblocks_from_user(
84 dst->eof_flags = src->eof_flags; 85 dst->eof_flags = src->eof_flags;
85 dst->eof_prid = src->eof_prid; 86 dst->eof_prid = src->eof_prid;
86 dst->eof_min_file_size = src->eof_min_file_size; 87 dst->eof_min_file_size = src->eof_min_file_size;
88 dst->eof_scan_owner = NULLFSINO;
87 89
88 dst->eof_uid = INVALID_UID; 90 dst->eof_uid = INVALID_UID;
89 if (src->eof_flags & XFS_EOF_FLAGS_UID) { 91 if (src->eof_flags & XFS_EOF_FLAGS_UID) {