[XFS] Add lockdep support for XFS
SGI-PV: 963965 SGI-Modid: xfs-linux-melb:xfs-kern:28485a Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: David Chinner <dgc@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com>
This commit is contained in:
committed by
Tim Shimmin
parent
71dfd5a396
commit
f7c66ce3f7
@@ -43,6 +43,18 @@ static inline void mrupdate(mrlock_t *mrp)
|
|||||||
mrp->mr_writer = 1;
|
mrp->mr_writer = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void mraccess_nested(mrlock_t *mrp, int subclass)
|
||||||
|
{
|
||||||
|
down_read_nested(&mrp->mr_lock, subclass);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void mrupdate_nested(mrlock_t *mrp, int subclass)
|
||||||
|
{
|
||||||
|
down_write_nested(&mrp->mr_lock, subclass);
|
||||||
|
mrp->mr_writer = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline int mrtryaccess(mrlock_t *mrp)
|
static inline int mrtryaccess(mrlock_t *mrp)
|
||||||
{
|
{
|
||||||
return down_read_trylock(&mrp->mr_lock);
|
return down_read_trylock(&mrp->mr_lock);
|
||||||
|
@@ -879,17 +879,17 @@ xfs_ilock(xfs_inode_t *ip,
|
|||||||
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
|
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
|
||||||
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
|
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
|
||||||
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
|
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
|
||||||
ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0);
|
ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
|
||||||
|
|
||||||
if (lock_flags & XFS_IOLOCK_EXCL) {
|
if (lock_flags & XFS_IOLOCK_EXCL) {
|
||||||
mrupdate(&ip->i_iolock);
|
mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
|
||||||
} else if (lock_flags & XFS_IOLOCK_SHARED) {
|
} else if (lock_flags & XFS_IOLOCK_SHARED) {
|
||||||
mraccess(&ip->i_iolock);
|
mraccess_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
|
||||||
}
|
}
|
||||||
if (lock_flags & XFS_ILOCK_EXCL) {
|
if (lock_flags & XFS_ILOCK_EXCL) {
|
||||||
mrupdate(&ip->i_lock);
|
mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
|
||||||
} else if (lock_flags & XFS_ILOCK_SHARED) {
|
} else if (lock_flags & XFS_ILOCK_SHARED) {
|
||||||
mraccess(&ip->i_lock);
|
mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
|
||||||
}
|
}
|
||||||
xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address);
|
xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address);
|
||||||
}
|
}
|
||||||
@@ -923,7 +923,7 @@ xfs_ilock_nowait(xfs_inode_t *ip,
|
|||||||
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
|
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
|
||||||
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
|
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
|
||||||
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
|
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
|
||||||
ASSERT((lock_flags & ~XFS_LOCK_MASK) == 0);
|
ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_DEP_MASK)) == 0);
|
||||||
|
|
||||||
iolocked = 0;
|
iolocked = 0;
|
||||||
if (lock_flags & XFS_IOLOCK_EXCL) {
|
if (lock_flags & XFS_IOLOCK_EXCL) {
|
||||||
@@ -983,7 +983,8 @@ xfs_iunlock(xfs_inode_t *ip,
|
|||||||
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
|
(XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
|
||||||
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
|
ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) !=
|
||||||
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
|
(XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
|
||||||
ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY)) == 0);
|
ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_IUNLOCK_NONOTIFY |
|
||||||
|
XFS_LOCK_DEP_MASK)) == 0);
|
||||||
ASSERT(lock_flags != 0);
|
ASSERT(lock_flags != 0);
|
||||||
|
|
||||||
if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {
|
if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {
|
||||||
|
@@ -382,26 +382,58 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags for inode locking.
|
* Flags for inode locking.
|
||||||
|
* Bit ranges: 1<<1 - 1<<16-1 -- iolock/ilock modes (bitfield)
|
||||||
|
* 1<<16 - 1<<32-1 -- lockdep annotation (integers)
|
||||||
*/
|
*/
|
||||||
#define XFS_IOLOCK_EXCL 0x001
|
#define XFS_IOLOCK_EXCL (1<<0)
|
||||||
#define XFS_IOLOCK_SHARED 0x002
|
#define XFS_IOLOCK_SHARED (1<<1)
|
||||||
#define XFS_ILOCK_EXCL 0x004
|
#define XFS_ILOCK_EXCL (1<<2)
|
||||||
#define XFS_ILOCK_SHARED 0x008
|
#define XFS_ILOCK_SHARED (1<<3)
|
||||||
#define XFS_IUNLOCK_NONOTIFY 0x010
|
#define XFS_IUNLOCK_NONOTIFY (1<<4)
|
||||||
/* XFS_IOLOCK_NESTED 0x020 */
|
/* #define XFS_IOLOCK_NESTED (1<<5) */
|
||||||
#define XFS_EXTENT_TOKEN_RD 0x040
|
#define XFS_EXTENT_TOKEN_RD (1<<6)
|
||||||
#define XFS_SIZE_TOKEN_RD 0x080
|
#define XFS_SIZE_TOKEN_RD (1<<7)
|
||||||
#define XFS_EXTSIZE_RD (XFS_EXTENT_TOKEN_RD|XFS_SIZE_TOKEN_RD)
|
#define XFS_EXTSIZE_RD (XFS_EXTENT_TOKEN_RD|XFS_SIZE_TOKEN_RD)
|
||||||
#define XFS_WILLLEND 0x100 /* Always acquire tokens for lending */
|
#define XFS_WILLLEND (1<<8) /* Always acquire tokens for lending */
|
||||||
#define XFS_EXTENT_TOKEN_WR (XFS_EXTENT_TOKEN_RD | XFS_WILLLEND)
|
#define XFS_EXTENT_TOKEN_WR (XFS_EXTENT_TOKEN_RD | XFS_WILLLEND)
|
||||||
#define XFS_SIZE_TOKEN_WR (XFS_SIZE_TOKEN_RD | XFS_WILLLEND)
|
#define XFS_SIZE_TOKEN_WR (XFS_SIZE_TOKEN_RD | XFS_WILLLEND)
|
||||||
#define XFS_EXTSIZE_WR (XFS_EXTSIZE_RD | XFS_WILLLEND)
|
#define XFS_EXTSIZE_WR (XFS_EXTSIZE_RD | XFS_WILLLEND)
|
||||||
/* XFS_SIZE_TOKEN_WANT 0x200 */
|
/* TODO:XFS_SIZE_TOKEN_WANT (1<<9) */
|
||||||
|
|
||||||
#define XFS_LOCK_MASK \
|
#define XFS_LOCK_MASK (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \
|
||||||
(XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL | \
|
| XFS_ILOCK_EXCL | XFS_ILOCK_SHARED \
|
||||||
XFS_ILOCK_SHARED | XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD | \
|
| XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD \
|
||||||
XFS_WILLLEND)
|
| XFS_WILLLEND)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags for lockdep annotations.
|
||||||
|
*
|
||||||
|
* XFS_I[O]LOCK_PARENT - for operations that require locking two inodes
|
||||||
|
* (ie directory operations that require locking a directory inode and
|
||||||
|
* an entry inode). The first inode gets locked with this flag so it
|
||||||
|
* gets a lockdep subclass of 1 and the second lock will have a lockdep
|
||||||
|
* subclass of 0.
|
||||||
|
*
|
||||||
|
* XFS_I[O]LOCK_INUMORDER - for locking several inodes at the some time
|
||||||
|
* with xfs_lock_inodes(). This flag is used as the starting subclass
|
||||||
|
* and each subsequent lock acquired will increment the subclass by one.
|
||||||
|
* So the first lock acquired will have a lockdep subclass of 2, the
|
||||||
|
* second lock will have a lockdep subclass of 3, and so on.
|
||||||
|
*/
|
||||||
|
#define XFS_IOLOCK_SHIFT 16
|
||||||
|
#define XFS_IOLOCK_PARENT (1 << XFS_IOLOCK_SHIFT)
|
||||||
|
#define XFS_IOLOCK_INUMORDER (2 << XFS_IOLOCK_SHIFT)
|
||||||
|
|
||||||
|
#define XFS_ILOCK_SHIFT 24
|
||||||
|
#define XFS_ILOCK_PARENT (1 << XFS_ILOCK_SHIFT)
|
||||||
|
#define XFS_ILOCK_INUMORDER (2 << XFS_ILOCK_SHIFT)
|
||||||
|
|
||||||
|
#define XFS_IOLOCK_DEP_MASK 0x00ff0000
|
||||||
|
#define XFS_ILOCK_DEP_MASK 0xff000000
|
||||||
|
#define XFS_LOCK_DEP_MASK (XFS_IOLOCK_DEP_MASK | XFS_ILOCK_DEP_MASK)
|
||||||
|
|
||||||
|
#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT)
|
||||||
|
#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags for xfs_iflush()
|
* Flags for xfs_iflush()
|
||||||
|
@@ -696,7 +696,7 @@ xfs_unmount_flush(
|
|||||||
bhv_vnode_t *rvp = XFS_ITOV(rip);
|
bhv_vnode_t *rvp = XFS_ITOV(rip);
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
xfs_ilock(rip, XFS_ILOCK_EXCL);
|
xfs_ilock(rip, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
||||||
xfs_iflock(rip);
|
xfs_iflock(rip);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1947,7 +1947,7 @@ xfs_create(
|
|||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfs_ilock(dp, XFS_ILOCK_EXCL);
|
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
||||||
|
|
||||||
XFS_BMAP_INIT(&free_list, &first_block);
|
XFS_BMAP_INIT(&free_list, &first_block);
|
||||||
|
|
||||||
@@ -2141,7 +2141,7 @@ xfs_lock_dir_and_entry(
|
|||||||
attempts = 0;
|
attempts = 0;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
xfs_ilock(dp, XFS_ILOCK_EXCL);
|
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
||||||
|
|
||||||
e_inum = ip->i_ino;
|
e_inum = ip->i_ino;
|
||||||
|
|
||||||
@@ -2209,6 +2209,21 @@ int xfs_lots_retries;
|
|||||||
int xfs_lock_delays;
|
int xfs_lock_delays;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bump the subclass so xfs_lock_inodes() acquires each lock with
|
||||||
|
* a different value
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
xfs_lock_inumorder(int lock_mode, int subclass)
|
||||||
|
{
|
||||||
|
if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))
|
||||||
|
lock_mode |= (subclass + XFS_IOLOCK_INUMORDER) << XFS_IOLOCK_SHIFT;
|
||||||
|
if (lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL))
|
||||||
|
lock_mode |= (subclass + XFS_ILOCK_INUMORDER) << XFS_ILOCK_SHIFT;
|
||||||
|
|
||||||
|
return lock_mode;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following routine will lock n inodes in exclusive mode.
|
* The following routine will lock n inodes in exclusive mode.
|
||||||
* We assume the caller calls us with the inodes in i_ino order.
|
* We assume the caller calls us with the inodes in i_ino order.
|
||||||
@@ -2276,7 +2291,7 @@ again:
|
|||||||
* that is in the AIL.
|
* that is in the AIL.
|
||||||
*/
|
*/
|
||||||
ASSERT(i != 0);
|
ASSERT(i != 0);
|
||||||
if (!xfs_ilock_nowait(ips[i], lock_mode)) {
|
if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) {
|
||||||
attempts++;
|
attempts++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2311,7 +2326,7 @@ again:
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
xfs_ilock(ips[i], lock_mode);
|
xfs_ilock(ips[i], xfs_lock_inumorder(lock_mode, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2845,7 +2860,7 @@ xfs_mkdir(
|
|||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfs_ilock(dp, XFS_ILOCK_EXCL);
|
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for directory link count overflow.
|
* Check for directory link count overflow.
|
||||||
@@ -3399,7 +3414,7 @@ xfs_symlink(
|
|||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfs_ilock(dp, XFS_ILOCK_EXCL);
|
xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether the directory allows new symlinks or not.
|
* Check whether the directory allows new symlinks or not.
|
||||||
|
Reference in New Issue
Block a user