aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/quota/xfs_dquot.c24
-rw-r--r--fs/xfs/quota/xfs_dquot.h10
2 files changed, 24 insertions, 10 deletions
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 591ca6602bfb..36d1bb6140d1 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -1383,6 +1383,12 @@ xfs_dqunlock_nonotify(
1383 mutex_unlock(&(dqp->q_qlock)); 1383 mutex_unlock(&(dqp->q_qlock));
1384} 1384}
1385 1385
1386/*
1387 * Lock two xfs_dquot structures.
1388 *
1389 * To avoid deadlocks we always lock the quota structure with
1390 * the lowerd id first.
1391 */
1386void 1392void
1387xfs_dqlock2( 1393xfs_dqlock2(
1388 xfs_dquot_t *d1, 1394 xfs_dquot_t *d1,
@@ -1392,18 +1398,16 @@ xfs_dqlock2(
1392 ASSERT(d1 != d2); 1398 ASSERT(d1 != d2);
1393 if (be32_to_cpu(d1->q_core.d_id) > 1399 if (be32_to_cpu(d1->q_core.d_id) >
1394 be32_to_cpu(d2->q_core.d_id)) { 1400 be32_to_cpu(d2->q_core.d_id)) {
1395 xfs_dqlock(d2); 1401 mutex_lock(&d2->q_qlock);
1396 xfs_dqlock(d1); 1402 mutex_lock_nested(&d1->q_qlock, XFS_QLOCK_NESTED);
1397 } else { 1403 } else {
1398 xfs_dqlock(d1); 1404 mutex_lock(&d1->q_qlock);
1399 xfs_dqlock(d2); 1405 mutex_lock_nested(&d2->q_qlock, XFS_QLOCK_NESTED);
1400 }
1401 } else {
1402 if (d1) {
1403 xfs_dqlock(d1);
1404 } else if (d2) {
1405 xfs_dqlock(d2);
1406 } 1406 }
1407 } else if (d1) {
1408 mutex_lock(&d1->q_qlock);
1409 } else if (d2) {
1410 mutex_lock(&d2->q_qlock);
1407 } 1411 }
1408} 1412}
1409 1413
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h
index 7e455337e2ba..d443e93b4331 100644
--- a/fs/xfs/quota/xfs_dquot.h
+++ b/fs/xfs/quota/xfs_dquot.h
@@ -97,6 +97,16 @@ typedef struct xfs_dquot {
97#define dq_hashlist q_lists.dqm_hashlist 97#define dq_hashlist q_lists.dqm_hashlist
98#define dq_flags q_lists.dqm_flags 98#define dq_flags q_lists.dqm_flags
99 99
100/*
101 * Lock hierachy for q_qlock:
102 * XFS_QLOCK_NORMAL is the implicit default,
103 * XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2
104 */
105enum {
106 XFS_QLOCK_NORMAL = 0,
107 XFS_QLOCK_NESTED,
108};
109
100#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++) 110#define XFS_DQHOLD(dqp) ((dqp)->q_nrefs++)
101 111
102#ifdef DEBUG 112#ifdef DEBUG