mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
quota: move code from sync_quota_sb into vfs_quota_sync
Currenly sync_quota_sb does a lot of sync and truncate action that only applies to "VFS" style quotas and is actively harmful for the sync performance in XFS. Move it into vfs_quota_sync and add a wait parameter to ->quota_sync to tell if we need it or not. My audit of the GFS2 code says it's also not needed given the way GFS2 implements quotas, but I'd be happy if this can get a detailed review. Signed-off-by: Christoph Hellwig <[email protected]> Signed-off-by: Jan Kara <[email protected]>
This commit is contained in:
parent
8c4e4acd66
commit
5fb324ad24
9 changed files with 52 additions and 71 deletions
|
|
@ -570,7 +570,7 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL(dquot_scan_active);
|
||||
|
||||
int vfs_quota_sync(struct super_block *sb, int type)
|
||||
int vfs_quota_sync(struct super_block *sb, int type, int wait)
|
||||
{
|
||||
struct list_head *dirty;
|
||||
struct dquot *dquot;
|
||||
|
|
@ -615,6 +615,33 @@ int vfs_quota_sync(struct super_block *sb, int type)
|
|||
spin_unlock(&dq_list_lock);
|
||||
mutex_unlock(&dqopt->dqonoff_mutex);
|
||||
|
||||
if (!wait || (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE))
|
||||
return 0;
|
||||
|
||||
/* This is not very clever (and fast) but currently I don't know about
|
||||
* any other simple way of getting quota data to disk and we must get
|
||||
* them there for userspace to be visible... */
|
||||
if (sb->s_op->sync_fs)
|
||||
sb->s_op->sync_fs(sb, 1);
|
||||
sync_blockdev(sb->s_bdev);
|
||||
|
||||
/*
|
||||
* Now when everything is written we can discard the pagecache so
|
||||
* that userspace sees the changes.
|
||||
*/
|
||||
mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
|
||||
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
|
||||
if (type != -1 && cnt != type)
|
||||
continue;
|
||||
if (!sb_has_quota_active(sb, cnt))
|
||||
continue;
|
||||
mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex,
|
||||
I_MUTEX_QUOTA);
|
||||
truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0);
|
||||
mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex);
|
||||
}
|
||||
mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_quota_sync);
|
||||
|
|
|
|||
|
|
@ -48,44 +48,6 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
|
|||
return security_quotactl(cmd, type, id, sb);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QUOTA
|
||||
void sync_quota_sb(struct super_block *sb, int type)
|
||||
{
|
||||
int cnt;
|
||||
|
||||
if (!sb->s_qcop || !sb->s_qcop->quota_sync)
|
||||
return;
|
||||
|
||||
sb->s_qcop->quota_sync(sb, type);
|
||||
|
||||
if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)
|
||||
return;
|
||||
/* This is not very clever (and fast) but currently I don't know about
|
||||
* any other simple way of getting quota data to disk and we must get
|
||||
* them there for userspace to be visible... */
|
||||
if (sb->s_op->sync_fs)
|
||||
sb->s_op->sync_fs(sb, 1);
|
||||
sync_blockdev(sb->s_bdev);
|
||||
|
||||
/*
|
||||
* Now when everything is written we can discard the pagecache so
|
||||
* that userspace sees the changes.
|
||||
*/
|
||||
mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
|
||||
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
|
||||
if (type != -1 && cnt != type)
|
||||
continue;
|
||||
if (!sb_has_quota_active(sb, cnt))
|
||||
continue;
|
||||
mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex,
|
||||
I_MUTEX_QUOTA);
|
||||
truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0);
|
||||
mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex);
|
||||
}
|
||||
mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int quota_sync_all(int type)
|
||||
{
|
||||
struct super_block *sb;
|
||||
|
|
@ -101,6 +63,9 @@ static int quota_sync_all(int type)
|
|||
spin_lock(&sb_lock);
|
||||
restart:
|
||||
list_for_each_entry(sb, &super_blocks, s_list) {
|
||||
if (!sb->s_qcop || !sb->s_qcop->quota_sync)
|
||||
continue;
|
||||
|
||||
/* This test just improves performance so it needn't be
|
||||
* reliable... */
|
||||
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
|
||||
|
|
@ -119,7 +84,7 @@ restart:
|
|||
spin_unlock(&sb_lock);
|
||||
down_read(&sb->s_umount);
|
||||
if (sb->s_root)
|
||||
sync_quota_sb(sb, type);
|
||||
sb->s_qcop->quota_sync(sb, type, 1);
|
||||
up_read(&sb->s_umount);
|
||||
spin_lock(&sb_lock);
|
||||
if (__put_super_and_need_restart(sb))
|
||||
|
|
@ -306,8 +271,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
|
|||
case Q_SYNC:
|
||||
if (!sb->s_qcop->quota_sync)
|
||||
return -ENOSYS;
|
||||
sync_quota_sb(sb, type);
|
||||
return 0;
|
||||
return sb->s_qcop->quota_sync(sb, type, 1);
|
||||
case Q_XQUOTAON:
|
||||
case Q_XQUOTAOFF:
|
||||
case Q_XQUOTARM:
|
||||
|
|
|
|||
Loading…
Reference in a new issue