Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull quota, fsnotify and ext2 updates from Jan Kara: "Changes to locking of some quota operations from dedicated quota mutex to s_umount semaphore, a fsnotify fix and a simple ext2 fix" * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: quota: Fix bogus warning in dquot_disable() fsnotify: Fix possible use-after-free in inode iteration on umount ext2: reject inodes with negative size quota: Remove dqonoff_mutex ocfs2: Use s_umount for quota recovery protection quota: Remove dqonoff_mutex from dquot_scan_active() ocfs2: Protect periodic quota syncing with s_umount semaphore quota: Use s_umount protection for quota operations quota: Hold s_umount in exclusive mode when enabling / disabling quotas fs: Provide function to get superblock with exclusive s_umount
This commit is contained in:
@@ -634,7 +634,15 @@ static void qsync_work_fn(struct work_struct *work)
|
||||
dqi_sync_work.work);
|
||||
struct super_block *sb = oinfo->dqi_gqinode->i_sb;
|
||||
|
||||
dquot_scan_active(sb, ocfs2_sync_dquot_helper, oinfo->dqi_type);
|
||||
/*
|
||||
* We have to be careful here not to deadlock on s_umount as umount
|
||||
* disabling quotas may be in progress and it waits for this work to
|
||||
* complete. If trylock fails, we'll do the sync next time...
|
||||
*/
|
||||
if (down_read_trylock(&sb->s_umount)) {
|
||||
dquot_scan_active(sb, ocfs2_sync_dquot_helper, oinfo->dqi_type);
|
||||
up_read(&sb->s_umount);
|
||||
}
|
||||
schedule_delayed_work(&oinfo->dqi_sync_work,
|
||||
msecs_to_jiffies(oinfo->dqi_syncms));
|
||||
}
|
||||
|
@@ -454,7 +454,7 @@ out:
|
||||
/* Sync changes in local quota file into global quota file and
|
||||
* reinitialize local quota file.
|
||||
* The function expects local quota file to be already locked and
|
||||
* dqonoff_mutex locked. */
|
||||
* s_umount locked in shared mode. */
|
||||
static int ocfs2_recover_local_quota_file(struct inode *lqinode,
|
||||
int type,
|
||||
struct ocfs2_quota_recovery *rec)
|
||||
@@ -597,7 +597,7 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
|
||||
printk(KERN_NOTICE "ocfs2: Finishing quota recovery on device (%s) for "
|
||||
"slot %u\n", osb->dev_str, slot_num);
|
||||
|
||||
mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
|
||||
down_read(&sb->s_umount);
|
||||
for (type = 0; type < OCFS2_MAXQUOTAS; type++) {
|
||||
if (list_empty(&(rec->r_list[type])))
|
||||
continue;
|
||||
@@ -674,7 +674,7 @@ out_put:
|
||||
break;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
|
||||
up_read(&sb->s_umount);
|
||||
kfree(rec);
|
||||
return status;
|
||||
}
|
||||
@@ -840,7 +840,10 @@ static int ocfs2_local_free_info(struct super_block *sb, int type)
|
||||
}
|
||||
ocfs2_release_local_quota_bitmaps(&oinfo->dqi_chunk);
|
||||
|
||||
/* dqonoff_mutex protects us against racing with recovery thread... */
|
||||
/*
|
||||
* s_umount held in exclusive mode protects us against racing with
|
||||
* recovery thread...
|
||||
*/
|
||||
if (oinfo->dqi_rec) {
|
||||
ocfs2_free_quota_recovery(oinfo->dqi_rec);
|
||||
mark_clean = 0;
|
||||
|
@@ -985,7 +985,6 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb)
|
||||
for (type = 0; type < OCFS2_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]);
|
||||
|
Reference in New Issue
Block a user