aboutsummaryrefslogtreecommitdiffstats
path: root/fs/quota/quota.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2010-02-16 03:44:52 -0500
committerJan Kara <jack@suse.cz>2010-03-04 18:20:24 -0500
commit5fb324ad24febe57a8a2e62903dcb7bad546ea71 (patch)
treef49d1b8b7fe9feffbdd1afba18047001f5d7228f /fs/quota/quota.c
parent8c4e4acd660a09e571a71583b5bbe1eee700c9ad (diff)
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 <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/quota/quota.c')
-rw-r--r--fs/quota/quota.c46
1 files changed, 5 insertions, 41 deletions
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 3d31228082ea..0593b229656c 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -48,44 +48,6 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
48 return security_quotactl(cmd, type, id, sb); 48 return security_quotactl(cmd, type, id, sb);
49} 49}
50 50
51#ifdef CONFIG_QUOTA
52void sync_quota_sb(struct super_block *sb, int type)
53{
54 int cnt;
55
56 if (!sb->s_qcop || !sb->s_qcop->quota_sync)
57 return;
58
59 sb->s_qcop->quota_sync(sb, type);
60
61 if (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)
62 return;
63 /* This is not very clever (and fast) but currently I don't know about
64 * any other simple way of getting quota data to disk and we must get
65 * them there for userspace to be visible... */
66 if (sb->s_op->sync_fs)
67 sb->s_op->sync_fs(sb, 1);
68 sync_blockdev(sb->s_bdev);
69
70 /*
71 * Now when everything is written we can discard the pagecache so
72 * that userspace sees the changes.
73 */
74 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
75 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
76 if (type != -1 && cnt != type)
77 continue;
78 if (!sb_has_quota_active(sb, cnt))
79 continue;
80 mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex,
81 I_MUTEX_QUOTA);
82 truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0);
83 mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex);
84 }
85 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
86}
87#endif
88
89static int quota_sync_all(int type) 51static int quota_sync_all(int type)
90{ 52{
91 struct super_block *sb; 53 struct super_block *sb;
@@ -101,6 +63,9 @@ static int quota_sync_all(int type)
101 spin_lock(&sb_lock); 63 spin_lock(&sb_lock);
102restart: 64restart:
103 list_for_each_entry(sb, &super_blocks, s_list) { 65 list_for_each_entry(sb, &super_blocks, s_list) {
66 if (!sb->s_qcop || !sb->s_qcop->quota_sync)
67 continue;
68
104 /* This test just improves performance so it needn't be 69 /* This test just improves performance so it needn't be
105 * reliable... */ 70 * reliable... */
106 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 71 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@@ -119,7 +84,7 @@ restart:
119 spin_unlock(&sb_lock); 84 spin_unlock(&sb_lock);
120 down_read(&sb->s_umount); 85 down_read(&sb->s_umount);
121 if (sb->s_root) 86 if (sb->s_root)
122 sync_quota_sb(sb, type); 87 sb->s_qcop->quota_sync(sb, type, 1);
123 up_read(&sb->s_umount); 88 up_read(&sb->s_umount);
124 spin_lock(&sb_lock); 89 spin_lock(&sb_lock);
125 if (__put_super_and_need_restart(sb)) 90 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,
306 case Q_SYNC: 271 case Q_SYNC:
307 if (!sb->s_qcop->quota_sync) 272 if (!sb->s_qcop->quota_sync)
308 return -ENOSYS; 273 return -ENOSYS;
309 sync_quota_sb(sb, type); 274 return sb->s_qcop->quota_sync(sb, type, 1);
310 return 0;
311 case Q_XQUOTAON: 275 case Q_XQUOTAON:
312 case Q_XQUOTAOFF: 276 case Q_XQUOTAOFF:
313 case Q_XQUOTARM: 277 case Q_XQUOTARM: