aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2010-05-13 16:14:53 -0400
committerJan Kara <jack@suse.cz>2010-05-21 13:30:48 -0400
commitc06bcbfa1ed8daaeb2a262f372b411207891e229 (patch)
treedb734e409643108ea4b5df28bf18bcfac654eaca
parent52a9ee281cfb26fffce1d6c409fb4b1f4aa8a766 (diff)
ocfs2: Fix lock inversion in quotas during umount
We cannot cancel delayed work from ocfs2_local_free_info because that is called with dqonoff_mutex held and the work it cancels requires dqonoff_mutex to finish. Cancel the work before acquiring dqonoff_mutex. Acked-by: Joel Becker <Joel.Becker@oracle.com> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/ocfs2/quota_local.c4
-rw-r--r--fs/ocfs2/super.c4
2 files changed, 4 insertions, 4 deletions
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 551a6bff9f2c..8bd70d4d184d 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -816,10 +816,6 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
816 int mark_clean = 1, len; 816 int mark_clean = 1, len;
817 int status; 817 int status;
818 818
819 /* At this point we know there are no more dquots and thus
820 * even if there's some sync in the pdflush queue, it won't
821 * find any dquots and return without doing anything */
822 cancel_delayed_work_sync(&oinfo->dqi_sync_work);
823 iput(oinfo->dqi_gqinode); 819 iput(oinfo->dqi_gqinode);
824 ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock); 820 ocfs2_simple_drop_lockres(OCFS2_SB(sb), &oinfo->dqi_gqlock);
825 ocfs2_lock_res_free(&oinfo->dqi_gqlock); 821 ocfs2_lock_res_free(&oinfo->dqi_gqlock);
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 1c2c39f6f0b6..2c26ce251cb3 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -938,12 +938,16 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb)
938 int type; 938 int type;
939 struct inode *inode; 939 struct inode *inode;
940 struct super_block *sb = osb->sb; 940 struct super_block *sb = osb->sb;
941 struct ocfs2_mem_dqinfo *oinfo;
941 942
942 /* We mostly ignore errors in this function because there's not much 943 /* We mostly ignore errors in this function because there's not much
943 * we can do when we see them */ 944 * we can do when we see them */
944 for (type = 0; type < MAXQUOTAS; type++) { 945 for (type = 0; type < MAXQUOTAS; type++) {
945 if (!sb_has_quota_loaded(sb, type)) 946 if (!sb_has_quota_loaded(sb, type))
946 continue; 947 continue;
948 /* Cancel periodic syncing before we grab dqonoff_mutex */
949 oinfo = sb_dqinfo(sb, type)->dqi_priv;
950 cancel_delayed_work_sync(&oinfo->dqi_sync_work);
947 inode = igrab(sb->s_dquot.files[type]); 951 inode = igrab(sb->s_dquot.files[type]);
948 /* Turn off quotas. This will remove all dquot structures from 952 /* Turn off quotas. This will remove all dquot structures from
949 * memory and so they will be automatically synced to global 953 * memory and so they will be automatically synced to global