Commit efa70be1 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Ben Myers

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: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarBen Myers <bpm@sgi.com>
Signed-off-by: default avatarBen Myers <bpm@sgi.com>
parent 309ecac8
...@@ -617,22 +617,27 @@ xfs_getbmap( ...@@ -617,22 +617,27 @@ xfs_getbmap(
return XFS_ERROR(ENOMEM); return XFS_ERROR(ENOMEM);
xfs_ilock(ip, XFS_IOLOCK_SHARED); xfs_ilock(ip, XFS_IOLOCK_SHARED);
if (whichfork == XFS_DATA_FORK && !(iflags & BMV_IF_DELALLOC)) { if (whichfork == XFS_DATA_FORK) {
if (ip->i_delayed_blks || XFS_ISIZE(ip) > ip->i_d.di_size) { if (!(iflags & BMV_IF_DELALLOC) &&
(ip->i_delayed_blks || XFS_ISIZE(ip) > ip->i_d.di_size)) {
error = -filemap_write_and_wait(VFS_I(ip)->i_mapping); error = -filemap_write_and_wait(VFS_I(ip)->i_mapping);
if (error) if (error)
goto out_unlock_iolock; goto out_unlock_iolock;
/*
* Even after flushing the inode, there can still be
* delalloc blocks on the inode beyond EOF due to
* speculative preallocation. These are not removed
* until the release function is called or the inode
* is inactivated. Hence we cannot assert here that
* ip->i_delayed_blks == 0.
*/
} }
/*
* even after flushing the inode, there can still be delalloc
* blocks on the inode beyond EOF due to speculative
* preallocation. These are not removed until the release
* function is called or the inode is inactivated. Hence we
* cannot assert here that ip->i_delayed_blks == 0.
*/
}
lock = xfs_ilock_data_map_shared(ip); lock = xfs_ilock_data_map_shared(ip);
} else {
lock = xfs_ilock_attr_map_shared(ip);
}
/* /*
* Don't let nex be bigger than the number of extents * Don't let nex be bigger than the number of extents
......
...@@ -77,17 +77,18 @@ xfs_get_extsz_hint( ...@@ -77,17 +77,18 @@ xfs_get_extsz_hint(
} }
/* /*
* This is a wrapper routine around the xfs_ilock() routine used to centralize * These two are wrapper routines around the xfs_ilock() routine used to
* some grungy code. It is used in places that wish to lock the inode solely * centralize some grungy code. They are used in places that wish to lock the
* for reading the extents. The reason these places can't just call * inode solely for reading the extents. The reason these places can't just
* xfs_ilock(SHARED) is that the inode lock also guards to bringing in of the * call xfs_ilock(ip, XFS_ILOCK_SHARED) is that the inode lock also guards to
* extents from disk for a file in b-tree format. If the inode is in b-tree * bringing in of the extents from disk for a file in b-tree format. If the
* format, then we need to lock the inode exclusively until the extents are read * inode is in b-tree format, then we need to lock the inode exclusively until
* in. Locking it exclusively all the time would limit our parallelism * the extents are read in. Locking it exclusively all the time would limit
* unnecessarily, though. What we do instead is check to see if the extents * our parallelism unnecessarily, though. What we do instead is check to see
* have been read in yet, and only lock the inode exclusively if they have not. * if the extents have been read in yet, and only lock the inode exclusively
* if they have not.
* *
* The function returns a value which should be given to the corresponding * The functions return a value which should be given to the corresponding
* xfs_iunlock() call. * xfs_iunlock() call.
*/ */
uint uint
...@@ -103,6 +104,19 @@ xfs_ilock_data_map_shared( ...@@ -103,6 +104,19 @@ xfs_ilock_data_map_shared(
return lock_mode; return lock_mode;
} }
uint
xfs_ilock_attr_map_shared(
struct xfs_inode *ip)
{
uint lock_mode = XFS_ILOCK_SHARED;
if (ip->i_d.di_aformat == XFS_DINODE_FMT_BTREE &&
(ip->i_afp->if_flags & XFS_IFEXTENTS) == 0)
lock_mode = XFS_ILOCK_EXCL;
xfs_ilock(ip, lock_mode);
return lock_mode;
}
/* /*
* The xfs inode contains 2 locks: a multi-reader lock called the * The xfs inode contains 2 locks: a multi-reader lock called the
* i_iolock and a multi-reader lock called the i_lock. This routine * i_iolock and a multi-reader lock called the i_lock. This routine
......
...@@ -338,6 +338,7 @@ void xfs_iunlock(xfs_inode_t *, uint); ...@@ -338,6 +338,7 @@ void xfs_iunlock(xfs_inode_t *, uint);
void xfs_ilock_demote(xfs_inode_t *, uint); void xfs_ilock_demote(xfs_inode_t *, uint);
int xfs_isilocked(xfs_inode_t *, uint); int xfs_isilocked(xfs_inode_t *, uint);
uint xfs_ilock_data_map_shared(struct xfs_inode *); uint xfs_ilock_data_map_shared(struct xfs_inode *);
uint xfs_ilock_attr_map_shared(struct xfs_inode *);
int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t, int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, umode_t,
xfs_nlink_t, xfs_dev_t, prid_t, int, xfs_nlink_t, xfs_dev_t, prid_t, int,
struct xfs_buf **, xfs_inode_t **); struct xfs_buf **, xfs_inode_t **);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment