aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2013-12-18 05:14:39 -0500
committerBen Myers <bpm@sgi.com>2013-12-18 16:48:44 -0500
commitefa70be165497826f674846f681e6e2364af906c (patch)
tree484e876ef92c632e062ccac613f9a066f4b714db
parent309ecac8e7c937c5811ef8f0efc14b3d1bd18775 (diff)
xfs: add xfs_ilock_attr_map_shared
Equivalent to xfs_ilock_data_map_shared, except for the attribute fork. Make xfs_getbmap use it if called for the attribute fork instead of xfs_ilock_data_map_shared. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Ben Myers <bpm@sgi.com> Signed-off-by: Ben Myers <bpm@sgi.com>
-rw-r--r--fs/xfs/xfs_bmap_util.c27
-rw-r--r--fs/xfs/xfs_inode.c34
-rw-r--r--fs/xfs/xfs_inode.h1
3 files changed, 41 insertions, 21 deletions
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 460aeb87c04e..374ba050942f 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -617,22 +617,27 @@ xfs_getbmap(
617 return XFS_ERROR(ENOMEM); 617 return XFS_ERROR(ENOMEM);
618 618
619 xfs_ilock(ip, XFS_IOLOCK_SHARED); 619 xfs_ilock(ip, XFS_IOLOCK_SHARED);
620 if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) { 620 if (whichfork == XFS_DATA_FORK) {
621 if (ip->i_delayed_blks || XFS_ISIZE(ip) > ip->i_d.di_size) { 621 if (!(iflags & BMV_IF_DELALLOC) &&
622 (ip->i_delayed_blks || XFS_ISIZE(ip) > ip->i_d.di_size)) {
622 error = -filemap_write_and_wait(VFS_I(ip)->i_mapping); 623 error = -filemap_write_and_wait(VFS_I(ip)->i_mapping);
623 if (error) 624 if (error)
624 goto out_unlock_iolock; 625 goto out_unlock_iolock;
626
627 /*
628 * Even after flushing the inode, there can still be
629 * delalloc blocks on the inode beyond EOF due to
630 * speculative preallocation. These are not removed
631 * until the release function is called or the inode
632 * is inactivated. Hence we cannot assert here that
633 * ip->i_delayed_blks == 0.
634 */
625 } 635 }
626 /*
627 * even after flushing the inode, there can still be delalloc
628 * blocks on the inode beyond EOF due to speculative
629 * preallocation. These are not removed until the release
630 * function is called or the inode is inactivated. Hence we
631 * cannot assert here that ip->i_delayed_blks == 0.
632 */
633 }
634 636
635 lock = xfs_ilock_data_map_shared(ip); 637 lock = xfs_ilock_data_map_shared(ip);
638 } else {
639 lock = xfs_ilock_attr_map_shared(ip);
640 }
636 641
637 /* 642 /*
638 * Don't let nex be bigger than the number of extents 643 * Don't let nex be bigger than the number of extents
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index fdd483783365..e655bb07e8bb 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -77,17 +77,18 @@ xfs_get_extsz_hint(
77} 77}
78 78
79/* 79/*
80 * This is a wrapper routine around the xfs_ilock() routine used to centralize 80 * These two are wrapper routines around the xfs_ilock() routine used to
81 * some grungy code. It is used in places that wish to lock the inode solely 81 * centralize some grungy code. They are used in places that wish to lock the
82 * for reading the extents. The reason these places can't just call 82 * inode solely for reading the extents. The reason these places can't just
83 * xfs_ilock(SHARED) is that the inode lock also guards to bringing in of the 83 * call xfs_ilock(ip, XFS_ILOCK_SHARED) is that the inode lock also guards to
84 * extents from disk for a file in b-tree format. If the inode is in b-tree 84 * bringing in of the extents from disk for a file in b-tree format. If the
85 * format, then we need to lock the inode exclusively until the extents are read 85 * inode is in b-tree format, then we need to lock the inode exclusively until
86 * in. Locking it exclusively all the time would limit our parallelism 86 * the extents are read in. Locking it exclusively all the time would limit
87 * unnecessarily, though. What we do instead is check to see if the extents 87 * our parallelism unnecessarily, though. What we do instead is check to see
88 * have been read in yet, and only lock the inode exclusively if they have not. 88 * if the extents have been read in yet, and only lock the inode exclusively
89 * if they have not.
89 * 90 *
90 * The function returns a value which should be given to the corresponding 91 * The functions return a value which should be given to the corresponding
91 * xfs_iunlock() call. 92 * xfs_iunlock() call.
92 */ 93 */
93uint 94uint
@@ -103,6 +104,19 @@ xfs_ilock_data_map_shared(
103 return lock_mode; 104 return lock_mode;
104} 105}
105 106
107uint
108xfs_ilock_attr_map_shared(
109 struct xfs_inode *ip)
110{
111 uint lock_mode = XFS_ILOCK_SHARED;
112
113 if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE &&
114 (ip->i_afp->if_flags & XFS_IFEXTENTS) == 0)
115 lock_mode = XFS_ILOCK_EXCL;
116 xfs_ilock(ip, lock_mode);
117 return lock_mode;
118}
119
106/* 120/*
107 * The xfs inode contains 2 locks: a multi-reader lock called the 121 * The xfs inode contains 2 locks: a multi-reader lock called the
108 * i_iolock and a multi-reader lock called the i_lock. This routine 122 * i_iolock and a multi-reader lock called the i_lock. This routine
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index fde368624ea7..65e2350f449c 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -338,6 +338,7 @@ void xfs_iunlock(xfs_inode_t *, uint);
338void xfs_ilock_demote(xfs_inode_t *, uint); 338void xfs_ilock_demote(xfs_inode_t *, uint);
339int xfs_isilocked(xfs_inode_t *, uint); 339int xfs_isilocked(xfs_inode_t *, uint);
340uint xfs_ilock_data_map_shared(struct xfs_inode *); 340uint xfs_ilock_data_map_shared(struct xfs_inode *);
341uint xfs_ilock_attr_map_shared(struct xfs_inode *);
341int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t, 342int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t,
342 xfs_nlink_t, xfs_dev_t, prid_t, int, 343 xfs_nlink_t, xfs_dev_t, prid_t, int,
343 struct xfs_buf **, xfs_inode_t **); 344 struct xfs_buf **, xfs_inode_t **);