summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2009-06-02 14:23:59 +0200
committerJoel Becker <joel.becker@oracle.com>2009-06-03 19:14:28 -0700
commit4e8a301929bfa017e6ffe11e3cf78ccaf8492801 (patch)
tree5532a7eeb2c1f7d9a52aa663fb6b53677ef0f2b2
parent2b53bc7bff17341d8b5ac12115f5c2363638e628 (diff)
downloadlinux-4e8a301929bfa017e6ffe11e3cf78ccaf8492801.tar.bz2
ocfs2: Fix possible deadlock in ocfs2_global_read_dquot()
It is not possible to get a read lock and then try to get the same write lock in one thread as that can block on downconvert being requested by other node leading to deadlock. So first drop the quota lock for reading and only after that get it for writing. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Joel Becker <joel.becker@oracle.com>
-rw-r--r--fs/ocfs2/quota_global.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index 1ed0f7c86869..edfa60cd155c 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -421,6 +421,7 @@ int ocfs2_global_read_dquot(struct dquot *dquot)
OCFS2_DQUOT(dquot)->dq_originodes = dquot->dq_dqb.dqb_curinodes;
if (!dquot->dq_off) { /* No real quota entry? */
/* Upgrade to exclusive lock for allocation */
+ ocfs2_qinfo_unlock(info, 0);
err = ocfs2_qinfo_lock(info, 1);
if (err < 0)
goto out_qlock;
@@ -435,7 +436,8 @@ int ocfs2_global_read_dquot(struct dquot *dquot)
out_qlock:
if (ex)
ocfs2_qinfo_unlock(info, 1);
- ocfs2_qinfo_unlock(info, 0);
+ else
+ ocfs2_qinfo_unlock(info, 0);
out:
if (err < 0)
mlog_errno(err);