提交 dcfcf205 编写于 作者: D Dave Chinner 提交者: Dave Chinner

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: NDave Chinner <dchinner@redhat.com>
Reviewed-by: NChristoph Hellwig <hch@lst.de>
上级 489a150f
...@@ -1118,6 +1118,8 @@ xfs_fs_evict_inode( ...@@ -1118,6 +1118,8 @@ xfs_fs_evict_inode(
*/ */
ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
&xfs_iolock_reclaimable, "xfs_iolock_reclaimable");
xfs_inactive(ip); xfs_inactive(ip);
} }
......
...@@ -42,6 +42,17 @@ ...@@ -42,6 +42,17 @@
#include "xfs_trace.h" #include "xfs_trace.h"
/*
* Define xfs inode iolock lockdep classes. We need to ensure that all active
* inodes are considered the same for lockdep purposes, including inodes that
* are recycled through the XFS_IRECLAIMABLE state. This is the the only way to
* guarantee the locks are considered the same when there are multiple lock
* initialisation siteѕ. Also, define a reclaimable inode class so it is
* obvious in lockdep reports which class the report is against.
*/
static struct lock_class_key xfs_iolock_active;
struct lock_class_key xfs_iolock_reclaimable;
/* /*
* Allocate and initialise an xfs_inode. * Allocate and initialise an xfs_inode.
*/ */
...@@ -71,6 +82,8 @@ xfs_inode_alloc( ...@@ -71,6 +82,8 @@ xfs_inode_alloc(
ASSERT(completion_done(&ip->i_flush)); ASSERT(completion_done(&ip->i_flush));
mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
&xfs_iolock_active, "xfs_iolock_active");
/* initialise the xfs inode */ /* initialise the xfs inode */
ip->i_ino = ino; ip->i_ino = ino;
...@@ -218,6 +231,12 @@ xfs_iget_cache_hit( ...@@ -218,6 +231,12 @@ xfs_iget_cache_hit(
ip->i_flags |= XFS_INEW; ip->i_flags |= XFS_INEW;
__xfs_inode_clear_reclaim_tag(mp, pag, ip); __xfs_inode_clear_reclaim_tag(mp, pag, ip);
inode->i_state = I_NEW; inode->i_state = I_NEW;
ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
lockdep_set_class_and_name(&ip->i_iolock.mr_lock,
&xfs_iolock_active, "xfs_iolock_active");
spin_unlock(&ip->i_flags_lock); spin_unlock(&ip->i_flags_lock);
write_unlock(&pag->pag_ici_lock); write_unlock(&pag->pag_ici_lock);
} else { } else {
......
...@@ -438,6 +438,8 @@ static inline void xfs_ifunlock(xfs_inode_t *ip) ...@@ -438,6 +438,8 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
#define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT) #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) #define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT)
extern struct lock_class_key xfs_iolock_reclaimable;
/* /*
* Flags for xfs_itruncate_start(). * Flags for xfs_itruncate_start().
*/ */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册