diff options
| author | Jan Kara <jack@suse.cz> | 2010-05-13 16:14:53 -0400 |
|---|---|---|
| committer | Jan Kara <jack@suse.cz> | 2010-05-21 13:30:48 -0400 |
| commit | c06bcbfa1ed8daaeb2a262f372b411207891e229 (patch) | |
| tree | db734e409643108ea4b5df28bf18bcfac654eaca | |
| parent | 52a9ee281cfb26fffce1d6c409fb4b1f4aa8a766 (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.c | 4 | ||||
| -rw-r--r-- | fs/ocfs2/super.c | 4 |
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 |
