Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f7c66ce3 authored by Lachlan McIlroy's avatar Lachlan McIlroy Committed by Tim Shimmin
Browse files

[XFS] Add lockdep support for XFS



SGI-PV: 963965
SGI-Modid: xfs-linux-melb:xfs-kern:28485a

Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
Signed-off-by: default avatarDavid Chinner <dgc@sgi.com>
Signed-off-by: default avatarTim Shimmin <tes@sgi.com>
parent 71dfd5a3
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -43,6 +43,18 @@ static inline void mrupdate(mrlock_t *mrp)
	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)
{
	return down_read_trylock(&mrp->mr_lock);
+8 −7
Original line number Diff line number Diff line
@@ -879,17 +879,17 @@ xfs_ilock(xfs_inode_t *ip,
	       (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
	ASSERT((lock_flags & (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) {
		mrupdate(&ip->i_iolock);
		mrupdate_nested(&ip->i_iolock, XFS_IOLOCK_DEP(lock_flags));
	} 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) {
		mrupdate(&ip->i_lock);
		mrupdate_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
	} 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);
}
@@ -923,7 +923,7 @@ xfs_ilock_nowait(xfs_inode_t *ip,
	       (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
	ASSERT((lock_flags & (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;
	if (lock_flags & XFS_IOLOCK_EXCL) {
@@ -983,7 +983,8 @@ xfs_iunlock(xfs_inode_t *ip,
	       (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL));
	ASSERT((lock_flags & (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);

	if (lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) {
+46 −14
Original line number Diff line number Diff line
@@ -382,26 +382,58 @@ xfs_iflags_test(xfs_inode_t *ip, unsigned short flags)

/*
 * 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_SHARED	0x002
#define	XFS_ILOCK_EXCL		0x004
#define	XFS_ILOCK_SHARED	0x008
#define	XFS_IUNLOCK_NONOTIFY	0x010
/*	XFS_IOLOCK_NESTED	0x020 */
#define XFS_EXTENT_TOKEN_RD	0x040
#define XFS_SIZE_TOKEN_RD	0x080
#define	XFS_IOLOCK_EXCL		(1<<0)
#define	XFS_IOLOCK_SHARED	(1<<1)
#define	XFS_ILOCK_EXCL		(1<<2)
#define	XFS_ILOCK_SHARED	(1<<3)
#define	XFS_IUNLOCK_NONOTIFY	(1<<4)
/*	#define XFS_IOLOCK_NESTED	(1<<5)	*/
#define XFS_EXTENT_TOKEN_RD	(1<<6)
#define XFS_SIZE_TOKEN_RD	(1<<7)
#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_SIZE_TOKEN_WR       (XFS_SIZE_TOKEN_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	\
	(XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED | XFS_ILOCK_EXCL | \
	 XFS_ILOCK_SHARED | XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD | \
	 XFS_WILLLEND)
#define XFS_LOCK_MASK		(XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED \
				| XFS_ILOCK_EXCL | XFS_ILOCK_SHARED \
				| XFS_EXTENT_TOKEN_RD | XFS_SIZE_TOKEN_RD \
				| 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()
+1 −1
Original line number Diff line number Diff line
@@ -696,7 +696,7 @@ xfs_unmount_flush(
	bhv_vnode_t	*rvp = XFS_ITOV(rip);
	int		error;

	xfs_ilock(rip, XFS_ILOCK_EXCL);
	xfs_ilock(rip, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);
	xfs_iflock(rip);

	/*
+21 −6
Original line number Diff line number Diff line
@@ -1947,7 +1947,7 @@ xfs_create(
		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);

@@ -2141,7 +2141,7 @@ xfs_lock_dir_and_entry(
	attempts = 0;

again:
	xfs_ilock(dp, XFS_ILOCK_EXCL);
	xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);

	e_inum = ip->i_ino;

@@ -2209,6 +2209,21 @@ int xfs_lots_retries;
int xfs_lock_delays;
#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.
 * We assume the caller calls us with the inodes in i_ino order.
@@ -2276,7 +2291,7 @@ xfs_lock_inodes(
			 * that is in the AIL.
			 */
			ASSERT(i != 0);
			if (!xfs_ilock_nowait(ips[i], lock_mode)) {
			if (!xfs_ilock_nowait(ips[i], xfs_lock_inumorder(lock_mode, i))) {
				attempts++;

				/*
@@ -2311,7 +2326,7 @@ xfs_lock_inodes(
				goto again;
			}
		} 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;
	}

	xfs_ilock(dp, XFS_ILOCK_EXCL);
	xfs_ilock(dp, XFS_ILOCK_EXCL | XFS_ILOCK_PARENT);

	/*
	 * Check for directory link count overflow.
@@ -3399,7 +3414,7 @@ xfs_symlink(
		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.