summaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/super.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2010-05-13 22:14:53 +0200
committerJan Kara <jack@suse.cz>2010-05-21 19:30:48 +0200
commitc06bcbfa1ed8daaeb2a262f372b411207891e229 (patch)
treedb734e409643108ea4b5df28bf18bcfac654eaca /fs/ocfs2/super.c
parentocfs2: Use __dquot_transfer to avoid lock inversion (diff)
downloadlinux-c06bcbfa1ed8daaeb2a262f372b411207891e229.tar.xz
linux-c06bcbfa1ed8daaeb2a262f372b411207891e229.zip
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>
Diffstat (limited to '')
-rw-r--r--fs/ocfs2/super.c4
1 files changed, 4 insertions, 0 deletions
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)
int type;
struct inode *inode;
struct super_block *sb = osb->sb;
+ struct ocfs2_mem_dqinfo *oinfo;
/* We mostly ignore errors in this function because there's not much
* we can do when we see them */
for (type = 0; type < MAXQUOTAS; type++) {
if (!sb_has_quota_loaded(sb, type))
continue;
+ /* Cancel periodic syncing before we grab dqonoff_mutex */
+ oinfo = sb_dqinfo(sb, type)->dqi_priv;
+ cancel_delayed_work_sync(&oinfo->dqi_sync_work);
inode = igrab(sb->s_dquot.files[type]);
/* Turn off quotas. This will remove all dquot structures from
* memory and so they will be automatically synced to global