diff options
Diffstat (limited to 'fs/gfs2/super.c')
| -rw-r--r-- | fs/gfs2/super.c | 110 |
1 files changed, 95 insertions, 15 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 0ec3ec672de1..c282ad41f3d1 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
| @@ -70,6 +70,11 @@ 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, | ||
| 76 | Opt_barrier, | ||
| 77 | Opt_nobarrier, | ||
| 73 | Opt_error, | 78 | Opt_error, |
| 74 | }; | 79 | }; |
| 75 | 80 | ||
| @@ -101,18 +106,23 @@ static const match_table_t tokens = { | |||
| 101 | {Opt_commit, "commit=%d"}, | 106 | {Opt_commit, "commit=%d"}, |
| 102 | {Opt_err_withdraw, "errors=withdraw"}, | 107 | {Opt_err_withdraw, "errors=withdraw"}, |
| 103 | {Opt_err_panic, "errors=panic"}, | 108 | {Opt_err_panic, "errors=panic"}, |
| 109 | {Opt_statfs_quantum, "statfs_quantum=%d"}, | ||
| 110 | {Opt_statfs_percent, "statfs_percent=%d"}, | ||
| 111 | {Opt_quota_quantum, "quota_quantum=%d"}, | ||
| 112 | {Opt_barrier, "barrier"}, | ||
| 113 | {Opt_nobarrier, "nobarrier"}, | ||
| 104 | {Opt_error, NULL} | 114 | {Opt_error, NULL} |
| 105 | }; | 115 | }; |
| 106 | 116 | ||
| 107 | /** | 117 | /** |
| 108 | * gfs2_mount_args - Parse mount options | 118 | * gfs2_mount_args - Parse mount options |
| 109 | * @sdp: | 119 | * @args: The structure into which the parsed options will be written |
| 110 | * @data: | 120 | * @options: The options to parse |
| 111 | * | 121 | * |
| 112 | * Return: errno | 122 | * Return: errno |
| 113 | */ | 123 | */ |
| 114 | 124 | ||
| 115 | int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options) | 125 | int gfs2_mount_args(struct gfs2_args *args, char *options) |
| 116 | { | 126 | { |
| 117 | char *o; | 127 | char *o; |
| 118 | int token; | 128 | int token; |
| @@ -157,7 +167,7 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options) | |||
| 157 | break; | 167 | break; |
| 158 | case Opt_debug: | 168 | case Opt_debug: |
| 159 | if (args->ar_errors == GFS2_ERRORS_PANIC) { | 169 | if (args->ar_errors == GFS2_ERRORS_PANIC) { |
| 160 | fs_info(sdp, "-o debug and -o errors=panic " | 170 | printk(KERN_WARNING "GFS2: -o debug and -o errors=panic " |
| 161 | "are mutually exclusive.\n"); | 171 | "are mutually exclusive.\n"); |
| 162 | return -EINVAL; | 172 | return -EINVAL; |
| 163 | } | 173 | } |
| @@ -210,7 +220,29 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options) | |||
| 210 | case Opt_commit: | 220 | case Opt_commit: |
| 211 | rv = match_int(&tmp[0], &args->ar_commit); | 221 | rv = match_int(&tmp[0], &args->ar_commit); |
| 212 | if (rv || args->ar_commit <= 0) { | 222 | if (rv || args->ar_commit <= 0) { |
| 213 | fs_info(sdp, "commit mount option requires a positive numeric argument\n"); | 223 | printk(KERN_WARNING "GFS2: commit mount option requires a positive numeric argument\n"); |
| 224 | return rv ? rv : -EINVAL; | ||
| 225 | } | ||
| 226 | break; | ||
| 227 | case Opt_statfs_quantum: | ||
| 228 | rv = match_int(&tmp[0], &args->ar_statfs_quantum); | ||
| 229 | if (rv || args->ar_statfs_quantum < 0) { | ||
| 230 | printk(KERN_WARNING "GFS2: statfs_quantum mount option requires a non-negative numeric argument\n"); | ||
| 231 | return rv ? rv : -EINVAL; | ||
| 232 | } | ||
| 233 | break; | ||
| 234 | case Opt_quota_quantum: | ||
| 235 | rv = match_int(&tmp[0], &args->ar_quota_quantum); | ||
| 236 | if (rv || args->ar_quota_quantum <= 0) { | ||
| 237 | printk(KERN_WARNING "GFS2: quota_quantum mount option requires a positive numeric argument\n"); | ||
| 238 | return rv ? rv : -EINVAL; | ||
| 239 | } | ||
| 240 | break; | ||
| 241 | case Opt_statfs_percent: | ||
| 242 | rv = match_int(&tmp[0], &args->ar_statfs_percent); | ||
| 243 | if (rv || args->ar_statfs_percent < 0 || | ||
| 244 | args->ar_statfs_percent > 100) { | ||
| 245 | printk(KERN_WARNING "statfs_percent mount option requires a numeric argument between 0 and 100\n"); | ||
| 214 | return rv ? rv : -EINVAL; | 246 | return rv ? rv : -EINVAL; |
| 215 | } | 247 | } |
| 216 | break; | 248 | break; |
| @@ -219,15 +251,21 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options) | |||
| 219 | break; | 251 | break; |
| 220 | case Opt_err_panic: | 252 | case Opt_err_panic: |
| 221 | if (args->ar_debug) { | 253 | if (args->ar_debug) { |
| 222 | fs_info(sdp, "-o debug and -o errors=panic " | 254 | printk(KERN_WARNING "GFS2: -o debug and -o errors=panic " |
| 223 | "are mutually exclusive.\n"); | 255 | "are mutually exclusive.\n"); |
| 224 | return -EINVAL; | 256 | return -EINVAL; |
| 225 | } | 257 | } |
| 226 | args->ar_errors = GFS2_ERRORS_PANIC; | 258 | args->ar_errors = GFS2_ERRORS_PANIC; |
| 227 | break; | 259 | break; |
| 260 | case Opt_barrier: | ||
| 261 | args->ar_nobarrier = 0; | ||
| 262 | break; | ||
| 263 | case Opt_nobarrier: | ||
| 264 | args->ar_nobarrier = 1; | ||
| 265 | break; | ||
| 228 | case Opt_error: | 266 | case Opt_error: |
| 229 | default: | 267 | default: |
| 230 | fs_info(sdp, "invalid mount option: %s\n", o); | 268 | printk(KERN_WARNING "GFS2: invalid mount option: %s\n", o); |
| 231 | return -EINVAL; | 269 | return -EINVAL; |
| 232 | } | 270 | } |
| 233 | } | 271 | } |
| @@ -442,7 +480,10 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, | |||
| 442 | { | 480 | { |
| 443 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 481 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
| 444 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; | 482 | struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local; |
| 483 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | ||
| 445 | struct buffer_head *l_bh; | 484 | struct buffer_head *l_bh; |
| 485 | s64 x, y; | ||
| 486 | int need_sync = 0; | ||
| 446 | int error; | 487 | int error; |
| 447 | 488 | ||
| 448 | error = gfs2_meta_inode_buffer(l_ip, &l_bh); | 489 | error = gfs2_meta_inode_buffer(l_ip, &l_bh); |
| @@ -456,9 +497,17 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, | |||
| 456 | l_sc->sc_free += free; | 497 | l_sc->sc_free += free; |
| 457 | l_sc->sc_dinodes += dinodes; | 498 | l_sc->sc_dinodes += dinodes; |
| 458 | gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode)); | 499 | gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode)); |
| 500 | if (sdp->sd_args.ar_statfs_percent) { | ||
| 501 | x = 100 * l_sc->sc_free; | ||
| 502 | y = m_sc->sc_free * sdp->sd_args.ar_statfs_percent; | ||
| 503 | if (x >= y || x <= -y) | ||
| 504 | need_sync = 1; | ||
| 505 | } | ||
| 459 | spin_unlock(&sdp->sd_statfs_spin); | 506 | spin_unlock(&sdp->sd_statfs_spin); |
| 460 | 507 | ||
| 461 | brelse(l_bh); | 508 | brelse(l_bh); |
| 509 | if (need_sync) | ||
| 510 | gfs2_wake_up_statfs(sdp); | ||
| 462 | } | 511 | } |
| 463 | 512 | ||
| 464 | void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, | 513 | void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, |
| @@ -484,8 +533,9 @@ void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh, | |||
| 484 | gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode)); | 533 | gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode)); |
| 485 | } | 534 | } |
| 486 | 535 | ||
| 487 | int gfs2_statfs_sync(struct gfs2_sbd *sdp) | 536 | int gfs2_statfs_sync(struct super_block *sb, int type) |
| 488 | { | 537 | { |
| 538 | struct gfs2_sbd *sdp = sb->s_fs_info; | ||
| 489 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); | 539 | struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); |
| 490 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); | 540 | struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode); |
| 491 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; | 541 | struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master; |
| @@ -521,6 +571,7 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp) | |||
| 521 | goto out_bh2; | 571 | goto out_bh2; |
| 522 | 572 | ||
| 523 | update_statfs(sdp, m_bh, l_bh); | 573 | update_statfs(sdp, m_bh, l_bh); |
| 574 | sdp->sd_statfs_force_sync = 0; | ||
| 524 | 575 | ||
| 525 | gfs2_trans_end(sdp); | 576 | gfs2_trans_end(sdp); |
| 526 | 577 | ||
| @@ -712,8 +763,8 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) | |||
| 712 | int error; | 763 | int error; |
| 713 | 764 | ||
| 714 | flush_workqueue(gfs2_delete_workqueue); | 765 | flush_workqueue(gfs2_delete_workqueue); |
| 715 | gfs2_quota_sync(sdp); | 766 | gfs2_quota_sync(sdp->sd_vfs, 0); |
| 716 | gfs2_statfs_sync(sdp); | 767 | gfs2_statfs_sync(sdp->sd_vfs, 0); |
| 717 | 768 | ||
| 718 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, | 769 | error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, GL_NOCACHE, |
| 719 | &t_gh); | 770 | &t_gh); |
| @@ -1061,8 +1112,13 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | |||
| 1061 | 1112 | ||
| 1062 | spin_lock(>->gt_spin); | 1113 | spin_lock(>->gt_spin); |
| 1063 | args.ar_commit = gt->gt_log_flush_secs; | 1114 | args.ar_commit = gt->gt_log_flush_secs; |
| 1115 | args.ar_quota_quantum = gt->gt_quota_quantum; | ||
| 1116 | if (gt->gt_statfs_slow) | ||
| 1117 | args.ar_statfs_quantum = 0; | ||
| 1118 | else | ||
| 1119 | args.ar_statfs_quantum = gt->gt_statfs_quantum; | ||
| 1064 | spin_unlock(>->gt_spin); | 1120 | spin_unlock(>->gt_spin); |
| 1065 | error = gfs2_mount_args(sdp, &args, data); | 1121 | error = gfs2_mount_args(&args, data); |
| 1066 | if (error) | 1122 | if (error) |
| 1067 | return error; | 1123 | return error; |
| 1068 | 1124 | ||
| @@ -1097,8 +1153,21 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data) | |||
| 1097 | sb->s_flags |= MS_POSIXACL; | 1153 | sb->s_flags |= MS_POSIXACL; |
| 1098 | else | 1154 | else |
| 1099 | sb->s_flags &= ~MS_POSIXACL; | 1155 | sb->s_flags &= ~MS_POSIXACL; |
| 1156 | if (sdp->sd_args.ar_nobarrier) | ||
| 1157 | set_bit(SDF_NOBARRIERS, &sdp->sd_flags); | ||
| 1158 | else | ||
| 1159 | clear_bit(SDF_NOBARRIERS, &sdp->sd_flags); | ||
| 1100 | spin_lock(>->gt_spin); | 1160 | spin_lock(>->gt_spin); |
| 1101 | gt->gt_log_flush_secs = args.ar_commit; | 1161 | gt->gt_log_flush_secs = args.ar_commit; |
| 1162 | gt->gt_quota_quantum = args.ar_quota_quantum; | ||
| 1163 | if (args.ar_statfs_quantum) { | ||
| 1164 | gt->gt_statfs_slow = 0; | ||
| 1165 | gt->gt_statfs_quantum = args.ar_statfs_quantum; | ||
| 1166 | } | ||
| 1167 | else { | ||
| 1168 | gt->gt_statfs_slow = 1; | ||
| 1169 | gt->gt_statfs_quantum = 30; | ||
| 1170 | } | ||
| 1102 | spin_unlock(>->gt_spin); | 1171 | spin_unlock(>->gt_spin); |
| 1103 | 1172 | ||
| 1104 | gfs2_online_uevent(sdp); | 1173 | gfs2_online_uevent(sdp); |
| @@ -1179,7 +1248,7 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
| 1179 | { | 1248 | { |
| 1180 | struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info; | 1249 | struct gfs2_sbd *sdp = mnt->mnt_sb->s_fs_info; |
| 1181 | struct gfs2_args *args = &sdp->sd_args; | 1250 | struct gfs2_args *args = &sdp->sd_args; |
| 1182 | int lfsecs; | 1251 | int val; |
| 1183 | 1252 | ||
| 1184 | if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir)) | 1253 | if (is_ancestor(mnt->mnt_root, sdp->sd_master_dir)) |
| 1185 | seq_printf(s, ",meta"); | 1254 | seq_printf(s, ",meta"); |
| @@ -1240,9 +1309,17 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
| 1240 | } | 1309 | } |
| 1241 | if (args->ar_discard) | 1310 | if (args->ar_discard) |
| 1242 | seq_printf(s, ",discard"); | 1311 | seq_printf(s, ",discard"); |
| 1243 | lfsecs = sdp->sd_tune.gt_log_flush_secs; | 1312 | val = sdp->sd_tune.gt_log_flush_secs; |
| 1244 | if (lfsecs != 60) | 1313 | if (val != 60) |
| 1245 | seq_printf(s, ",commit=%d", lfsecs); | 1314 | seq_printf(s, ",commit=%d", val); |
| 1315 | val = sdp->sd_tune.gt_statfs_quantum; | ||
| 1316 | if (val != 30) | ||
| 1317 | seq_printf(s, ",statfs_quantum=%d", val); | ||
| 1318 | val = sdp->sd_tune.gt_quota_quantum; | ||
| 1319 | if (val != 60) | ||
| 1320 | seq_printf(s, ",quota_quantum=%d", val); | ||
| 1321 | if (args->ar_statfs_percent) | ||
| 1322 | seq_printf(s, ",statfs_percent=%d", args->ar_statfs_percent); | ||
| 1246 | if (args->ar_errors != GFS2_ERRORS_DEFAULT) { | 1323 | if (args->ar_errors != GFS2_ERRORS_DEFAULT) { |
| 1247 | const char *state; | 1324 | const char *state; |
| 1248 | 1325 | ||
| @@ -1259,6 +1336,9 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) | |||
| 1259 | } | 1336 | } |
| 1260 | seq_printf(s, ",errors=%s", state); | 1337 | seq_printf(s, ",errors=%s", state); |
| 1261 | } | 1338 | } |
| 1339 | if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) | ||
| 1340 | seq_printf(s, ",nobarrier"); | ||
| 1341 | |||
| 1262 | return 0; | 1342 | return 0; |
| 1263 | } | 1343 | } |
| 1264 | 1344 | ||
