aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2010-12-22 19:57:13 -0500
committerDave Chinner <david@fromorbit.com>2010-12-22 19:57:13 -0500
commitdcfcf20512cb517ac18b9433b676183fa1257911 (patch)
treefd5551251e63f47dbb804e36cfd4cb3f15f5c322
parent489a150f6454e2cd93d9e0ee6d7c5a361844f62a (diff)
xfs: provide a inode iolock lockdep class
The XFS iolock needs to be re-initialised to a new lock class before it enters reclaim to prevent lockdep false positives. Unfortunately, this is not sufficient protection as inodes in the XFS_IRECLAIMABLE state can be recycled and not re-initialised before being reused. We need to re-initialise the lock state when transfering out of XFS_IRECLAIMABLE state to XFS_INEW, but we need to keep the same class as if the inode was just allocated. Hence we need a specific lockdep class variable for the iolock so that both initialisations use the same class. While there, add a specific class for inodes in the reclaim state so that it is easy to tell from lockdep reports what state the inode was in that generated the report. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c2
-rw-r--r--fs/xfs/xfs_iget.c19
-rw-r--r--fs/xfs/xfs_inode.h2
3 files changed, 23 insertions, 0 deletions
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 064f964d4f3c..c45b3233d486 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1118,6 +1118,8 @@ xfs_fs_evict_inode(
1118 */ 1118 */
1119 ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); 1119 ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
1120 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); 1120 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
1121 lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
1122 &xfs_iolock_reclaimable, "xfs_iolock_reclaimable");
1121 1123
1122 xfs_inactive(ip); 1124 xfs_inactive(ip);
1123} 1125}
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 0cdd26932d8e..cdb1c2505fc6 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -43,6 +43,17 @@
43 43
44 44
45/* 45/*
46 * Define xfs inode iolock lockdep classes. We need to ensure that all active
47 * inodes are considered the same for lockdep purposes, including inodes that
48 * are recycled through the XFS_IRECLAIMABLE state. This is the the only way to
49 * guarantee the locks are considered the same when there are multiple lock
50 * initialisation siteѕ. Also, define a reclaimable inode class so it is
51 * obvious in lockdep reports which class the report is against.
52 */
53static struct lock_class_key xfs_iolock_active;
54struct lock_class_key xfs_iolock_reclaimable;
55
56/*
46 * Allocate and initialise an xfs_inode. 57 * Allocate and initialise an xfs_inode.
47 */ 58 */
48STATIC struct xfs_inode * 59STATIC struct xfs_inode *
@@ -71,6 +82,8 @@ xfs_inode_alloc(
71 ASSERT(completion_done(&ip->i_flush)); 82 ASSERT(completion_done(&ip->i_flush));
72 83
73 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); 84 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
85 lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
86 &xfs_iolock_active, "xfs_iolock_active");
74 87
75 /* initialise the xfs inode */ 88 /* initialise the xfs inode */
76 ip->i_ino = ino; 89 ip->i_ino = ino;
@@ -218,6 +231,12 @@ xfs_iget_cache_hit(
218 ip->i_flags |= XFS_INEW; 231 ip->i_flags |= XFS_INEW;
219 __xfs_inode_clear_reclaim_tag(mp, pag, ip); 232 __xfs_inode_clear_reclaim_tag(mp, pag, ip);
220 inode->i_state = I_NEW; 233 inode->i_state = I_NEW;
234
235 ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
236 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
237 lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
238 &xfs_iolock_active, "xfs_iolock_active");
239
221 spin_unlock(&ip->i_flags_lock); 240 spin_unlock(&ip->i_flags_lock);
222 write_unlock(&pag->pag_ici_lock); 241 write_unlock(&pag->pag_ici_lock);
223 } else { 242 } else {
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index fb2ca2e4cdc9..1c6514d73dc8 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -438,6 +438,8 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
438#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT) 438#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT)
439#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT) 439#define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
440 440
441extern struct lock_class_key xfs_iolock_reclaimable;
442
441/* 443/*
442 * Flags for xfs_itruncate_start(). 444 * Flags for xfs_itruncate_start().
443 */ 445 */