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>
This commit is contained in:
parent
309ecac8e7
commit
efa70be165
|
@ -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.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
lock = xfs_ilock_data_map_shared(ip);
|
/*
|
||||||
|
* 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);
|
||||||
|
} 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(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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(
|
||||||
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);
|
||||||
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 **);
|
||||||
|
|
Loading…
Reference in New Issue