diff options
author | Benjamin Marzinski <bmarzins@redhat.com> | 2009-10-20 03:39:44 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2009-12-03 06:55:17 -0500 |
commit | 3d3c10f2ce80d2a19e5e02023c2b7ab7086c36d5 (patch) | |
tree | 56b62b064457596caf66700323ff5aac2320ae93 /fs/gfs2/super.c | |
parent | 2ec4650526c5a94d96bb760001fe0685b15988de (diff) |
GFS2: Improve statfs and quota usability
GFS2 now has three new mount options, statfs_quantum, quota_quantum and
statfs_percent. statfs_quantum and quota_quantum simply allow you to
set the tunables of the same name. Setting setting statfs_quantum to 0
will also turn on the statfs_slow tunable. statfs_percent accepts an
integer between 0 and 100. Numbers between 1 and 100 will cause GFS2 to
do any early sync when the local number of blocks free changes by at
least statfs_percent from the totoal number of blocks free. Setting
statfs_percent to 0 disables this.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r-- | fs/gfs2/super.c | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index e7b24d59d4f..3fee2fd3ae4 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -70,6 +70,9 @@ enum { | |||
70 | Opt_commit, | 70 | Opt_commit, |
71 | Opt_err_withdraw, | 71 | Opt_err_withdraw, |
72 | Opt_err_panic, | 72 | Opt_err_panic, |
73 | Opt_statfs_quantum, | ||
74 | Opt_statfs_percent, | ||
75 | Opt_quota_quantum, | ||
73 | Opt_error, | 76 | Opt_error, |
74 | }; | 77 | }; |
75 | 78 | ||
@@ -101,6 +104,9 @@ static const match_table_t tokens = { | |||
101 | {Opt_commit, "commit=%d"}, | 104 | {Opt_commit, "commit=%d"}, |
102 | {Opt_err_withdraw, "errors=withdraw"}, | 105 | {Opt_err_withdraw, "errors=withdraw"}, |
103 | {Opt_err_panic, "errors=panic"}, | 106 | {Opt_err_panic, "errors=panic"}, |
107 | {Opt_statfs_quantum, "statfs_quantum=%d"}, | ||
108 | {Opt_statfs_percent, "statfs_percent=%d"}, | ||
109 | {Opt_quota_quantum, "quota_quantum=%d"}, | ||
104 | {Opt_error, NULL} | 110 | {Opt_error, NULL} |
105 | }; | 111 | }; |
106 | 112 | ||
@@ -214,6 +220,28 @@ int gfs2_mount_args(struct gfs2_args *args, char *options) | |||
214 | return rv ? rv : -EINVAL; | 220 | return rv ? rv : -EINVAL; |
215 | } | 221 | } |
216 | break; | 222 | break; |
223 | case Opt_statfs_quantum: | ||
224 | rv = match_int(&tmp[0], &args->ar_statfs_quantum); | ||
225 | if (rv || args->ar_statfs_quantum < 0) { | ||
226 | printk(KERN_WARNING "GFS2: statfs_quantum mount option requires a non-negative numeric argument\n"); | ||
227 | return rv ? rv : -EINVAL; | ||
228 | } | ||
229 | break; | ||
230 | case Opt_quota_quantum: | ||
231 | rv = match_int(&tmp[0], &args->ar_quota_quantum); | ||
232 | if (rv || args->ar_quota_quantum <= 0) { | ||
233 | printk(KERN_WARNING "GFS2: quota_quantum mount option requires a positive numeric argument\n"); | ||
234 | return rv ? rv : -EINVAL; | ||
235 | } | ||
236 | break; | ||
237 | case Opt_statfs_percent: | ||
238 | rv = match_int(&tmp[0], &args->ar_statfs_percent); | ||
239 | if (rv || args->ar_statfs_percent < 0 || | ||
240 | args->ar_statfs_percent > 100) { | ||
241 | printk(KERN_WARNING "statfs_percent mount option requires a numeric argument between 0 and 100\n"); | ||
242 | return rv ? rv : -EINVAL; | ||
243 | } | ||
244 | break; | ||
217 | case Opt_err_withdraw: | 245 | case Opt_err_withdraw: |
218 | args->ar_errors = GFS2_ERRORS_WITHDRAW; | 246 | args->ar_errors = GFS2_ERRORS_WITHDRAW; |
219 | break; | 247 | break; |
@@ -442,7 +470,9 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, | |||
442 | { | 470 | { |
443 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 471 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
444 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | 472 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
473 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | ||
445 | struct buffer_head *l_bh; | 474 | struct buffer_head *l_bh; |
475 | int percent, sync_percent; | ||
446 | int error; | 476 | int error; |
447 | 477 | ||
448 | error = gfs2_meta_inode_buffer(l_ip, &l_bh); | 478 | error = gfs2_meta_inode_buffer(l_ip, &l_bh); |
@@ -456,9 +486,17 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, | |||
456 | l_sc->sc_free += free; | 486 | l_sc->sc_free += free; |
457 | l_sc->sc_dinodes += dinodes; | 487 | l_sc->sc_dinodes += dinodes; |
458 | gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode)); | 488 | gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode)); |
489 | if (m_sc->sc_free) | ||
490 | percent = (100 * l_sc->sc_free) / m_sc->sc_free; | ||
491 | else | ||
492 | percent = 100; | ||
459 | spin_unlock(&sdp->sd_statfs_spin); | 493 | spin_unlock(&sdp->sd_statfs_spin); |
460 | 494 | ||
461 | brelse(l_bh); | 495 | brelse(l_bh); |
496 | sync_percent = sdp->sd_args.ar_statfs_percent; | ||
497 | if (sync_percent && (percent >= sync_percent || | ||
498 | percent <= -sync_percent)) | ||
499 | gfs2_wake_up_statfs(sdp); | ||
462 | } | 500 | } |
463 | 501 | ||
464 | void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, | 502 | void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, |
@@ -522,6 +560,7 @@ int gfs2_statfs_sync(struct super_block *sb, int type) | |||
522 | goto out_bh2; | 560 | goto out_bh2; |
523 | 561 | ||
524 | update_statfs(sdp, m_bh, l_bh); | 562 | update_statfs(sdp, m_bh, l_bh); |
563 | sdp->sd_statfs_force_sync = 0; | ||
525 | 564 | ||
526 | gfs2_trans_end(sdp); | 565 | gfs2_trans_end(sdp); |
527 | 566 | ||
@@ -1062,6 +1101,11 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | |||
1062 | 1101 | ||
1063 | spin_lock(>->gt_spin); | 1102 | spin_lock(>->gt_spin); |
1064 | args.ar_commit = gt->gt_log_flush_secs; | 1103 | args.ar_commit = gt->gt_log_flush_secs; |
1104 | args.ar_quota_quantum = gt->gt_quota_quantum; | ||
1105 | if (gt->gt_statfs_slow) | ||
1106 | args.ar_statfs_quantum = 0; | ||
1107 | else | ||
1108 | args.ar_statfs_quantum = gt->gt_statfs_quantum; | ||
1065 | spin_unlock(>->gt_spin); | 1109 | spin_unlock(>->gt_spin); |
1066 | error = gfs2_mount_args(&args, data); | 1110 | error = gfs2_mount_args(&args, data); |
1067 | if (error) | 1111 | if (error) |
@@ -1100,6 +1144,15 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | |||
1100 | sb->s_flags &= ~MS_POSIXACL; | 1144 | sb->s_flags &= ~MS_POSIXACL; |
1101 | spin_lock(>->gt_spin); | 1145 | spin_lock(>->gt_spin); |
1102 | gt->gt_log_flush_secs = args.ar_commit; | 1146 | gt->gt_log_flush_secs = args.ar_commit; |
1147 | gt->gt_quota_quantum = args.ar_quota_quantum; | ||
1148 | if (args.ar_statfs_quantum) { | ||
1149 | gt->gt_statfs_slow = 0; | ||
1150 | gt->gt_statfs_quantum = args.ar_statfs_quantum; | ||
1151 | } | ||
1152 | else { | ||
1153 | gt->gt_statfs_slow = 1; | ||
1154 | gt->gt_statfs_quantum = 30; | ||
1155 | } | ||
1103 | spin_unlock(>->gt_spin); | 1156 | spin_unlock(>->gt_spin); |
1104 | 1157 | ||
1105 | gfs2_online_uevent(sdp); | 1158 | gfs2_online_uevent(sdp); |
@@ -1180,7 +1233,7 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1180 | { | 1233 | { |
1181 | struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info; | 1234 | struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info; |
1182 | struct gfs2_args *args = &sdp->sd_args; | 1235 | struct gfs2_args *args = &sdp->sd_args; |
1183 | int lfsecs; | 1236 | int val; |
1184 | 1237 | ||
1185 | if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir)) | 1238 | if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir)) |
1186 | seq_printf(s, ",meta"); | 1239 | seq_printf(s, ",meta"); |
@@ -1241,9 +1294,17 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
1241 | } | 1294 | } |
1242 | if (args->ar_discard) | 1295 | if (args->ar_discard) |
1243 | seq_printf(s, ",discard"); | 1296 | seq_printf(s, ",discard"); |
1244 | lfsecs = sdp->sd_tune.gt_log_flush_secs; | 1297 | val = sdp->sd_tune.gt_log_flush_secs; |
1245 | if (lfsecs != 60) | 1298 | if (val != 60) |
1246 | seq_printf(s, ",commit=%d", lfsecs); | 1299 | seq_printf(s, ",commit=%d", val); |
1300 | val = sdp->sd_tune.gt_statfs_quantum; | ||
1301 | if (val != 30) | ||
1302 | seq_printf(s, ",statfs_quantum=%d", val); | ||
1303 | val = sdp->sd_tune.gt_quota_quantum; | ||
1304 | if (val != 60) | ||
1305 | seq_printf(s, ",quota_quantum=%d", val); | ||
1306 | if (args->ar_statfs_percent) | ||
1307 | seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent); | ||
1247 | if (args->ar_errors != GFS2_ERRORS_DEFAULT) { | 1308 | if (args->ar_errors != GFS2_ERRORS_DEFAULT) { |
1248 | const char *state; | 1309 | const char *state; |
1249 | 1310 | ||