xfs: lockdep annotations for xfs_dqlock2
xfs_dqlock2 locks two xfs_dquots, which is fine as it always locks the dquot with the lower id first. Use mutex_lock_nested to tell lockdep about this fact. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
080dda7f5e
commit
4f2d4ac6e5
2 changed files with 24 additions and 10 deletions
|
@ -1383,6 +1383,12 @@ xfs_dqunlock_nonotify(
|
|||
mutex_unlock(&(dqp->q_qlock));
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock two xfs_dquot structures.
|
||||
*
|
||||
* To avoid deadlocks we always lock the quota structure with
|
||||
* the lowerd id first.
|
||||
*/
|
||||
void
|
||||
xfs_dqlock2(
|
||||
xfs_dquot_t *d1,
|
||||
|
@ -1392,18 +1398,16 @@ xfs_dqlock2(
|
|||
ASSERT(d1 != d2);
|
||||
if (be32_to_cpu(d1->q_core.d_id) >
|
||||
be32_to_cpu(d2->q_core.d_id)) {
|
||||
xfs_dqlock(d2);
|
||||
xfs_dqlock(d1);
|
||||
mutex_lock(&d2->q_qlock);
|
||||
mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED);
|
||||
} else {
|
||||
xfs_dqlock(d1);
|
||||
xfs_dqlock(d2);
|
||||
}
|
||||
} else {
|
||||
if (d1) {
|
||||
xfs_dqlock(d1);
|
||||
} else if (d2) {
|
||||
xfs_dqlock(d2);
|
||||
mutex_lock(&d1->q_qlock);
|
||||
mutex_lock_nested(&d2->q_qlock, XFS_QLOCK_NESTED);
|
||||
}
|
||||
} else if (d1) {
|
||||
mutex_lock(&d1->q_qlock);
|
||||
} else if (d2) {
|
||||
mutex_lock(&d2->q_qlock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -97,6 +97,16 @@ typedef struct xfs_dquot {
|
|||
#define dq_hashlist q_lists.dqm_hashlist
|
||||
#define dq_flags q_lists.dqm_flags
|
||||
|
||||
/*
|
||||
* Lock hierachy for q_qlock:
|
||||
* XFS_QLOCK_NORMAL is the implicit default,
|
||||
* XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2
|
||||
*/
|
||||
enum {
|
||||
XFS_QLOCK_NORMAL = 0,
|
||||
XFS_QLOCK_NESTED,
|
||||
};
|
||||
|
||||
#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++)
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
Loading…
Reference in a new issue