From f2cbab2c844e57725a6807ef7123da0f1ac4838f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 19 Jan 2009 02:03:19 +0100 Subject: [PATCH] --- yaml --- r: 129935 b: refs/heads/master c: 4f2d4ac6e5eb7d72e8df7f3fbf67a78dab8b91cf h: refs/heads/master i: 129933: 74ad21a20e7d387840a6bcfc000c2982f027ac65 129931: 118b2fc5aaf75fda6d4364c3683cc8d973f313a9 129927: 706f236348f2ab72c1a5f26b6dab4e17b2596ead 129919: 5f575e7c7d7c2e2da0c2eb93c4d3240f9c38f5f8 v: v3 --- [refs] | 2 +- trunk/fs/xfs/quota/xfs_dquot.c | 24 ++++++++++++++---------- trunk/fs/xfs/quota/xfs_dquot.h | 10 ++++++++++ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/[refs] b/[refs] index 35a551821a2e..a6ba13344626 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 080dda7f5e8e8df95bcd17a5345c276e365a2054 +refs/heads/master: 4f2d4ac6e5eb7d72e8df7f3fbf67a78dab8b91cf diff --git a/trunk/fs/xfs/quota/xfs_dquot.c b/trunk/fs/xfs/quota/xfs_dquot.c index 591ca6602bfb..36d1bb6140d1 100644 --- a/trunk/fs/xfs/quota/xfs_dquot.c +++ b/trunk/fs/xfs/quota/xfs_dquot.c @@ -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); } } diff --git a/trunk/fs/xfs/quota/xfs_dquot.h b/trunk/fs/xfs/quota/xfs_dquot.h index 7e455337e2ba..d443e93b4331 100644 --- a/trunk/fs/xfs/quota/xfs_dquot.h +++ b/trunk/fs/xfs/quota/xfs_dquot.h @@ -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