aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/super.c')
-rw-r--r--fs/gfs2/super.c86
1 files changed, 68 insertions, 18 deletions
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 0a6801336470..0ec3ec672de1 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -38,7 +38,7 @@
38#include "trans.h" 38#include "trans.h"
39#include "util.h" 39#include "util.h"
40#include "sys.h" 40#include "sys.h"
41#include "eattr.h" 41#include "xattr.h"
42 42
43#define args_neq(a1, a2, x) ((a1)->ar_##x != (a2)->ar_##x) 43#define args_neq(a1, a2, x) ((a1)->ar_##x != (a2)->ar_##x)
44 44
@@ -68,6 +68,8 @@ enum {
68 Opt_discard, 68 Opt_discard,
69 Opt_nodiscard, 69 Opt_nodiscard,
70 Opt_commit, 70 Opt_commit,
71 Opt_err_withdraw,
72 Opt_err_panic,
71 Opt_error, 73 Opt_error,
72}; 74};
73 75
@@ -97,6 +99,8 @@ static const match_table_t tokens = {
97 {Opt_discard, "discard"}, 99 {Opt_discard, "discard"},
98 {Opt_nodiscard, "nodiscard"}, 100 {Opt_nodiscard, "nodiscard"},
99 {Opt_commit, "commit=%d"}, 101 {Opt_commit, "commit=%d"},
102 {Opt_err_withdraw, "errors=withdraw"},
103 {Opt_err_panic, "errors=panic"},
100 {Opt_error, NULL} 104 {Opt_error, NULL}
101}; 105};
102 106
@@ -152,6 +156,11 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
152 args->ar_localcaching = 1; 156 args->ar_localcaching = 1;
153 break; 157 break;
154 case Opt_debug: 158 case Opt_debug:
159 if (args->ar_errors == GFS2_ERRORS_PANIC) {
160 fs_info(sdp, "-o debug and -o errors=panic "
161 "are mutually exclusive.\n");
162 return -EINVAL;
163 }
155 args->ar_debug = 1; 164 args->ar_debug = 1;
156 break; 165 break;
157 case Opt_nodebug: 166 case Opt_nodebug:
@@ -205,6 +214,17 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options)
205 return rv ? rv : -EINVAL; 214 return rv ? rv : -EINVAL;
206 } 215 }
207 break; 216 break;
217 case Opt_err_withdraw:
218 args->ar_errors = GFS2_ERRORS_WITHDRAW;
219 break;
220 case Opt_err_panic:
221 if (args->ar_debug) {
222 fs_info(sdp, "-o debug and -o errors=panic "
223 "are mutually exclusive.\n");
224 return -EINVAL;
225 }
226 args->ar_errors = GFS2_ERRORS_PANIC;
227 break;
208 case Opt_error: 228 case Opt_error:
209 default: 229 default:
210 fs_info(sdp, "invalid mount option: %s\n", o); 230 fs_info(sdp, "invalid mount option: %s\n", o);
@@ -353,7 +373,7 @@ fail:
353 return error; 373 return error;
354} 374}
355 375
356static void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf) 376void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc, const void *buf)
357{ 377{
358 const struct gfs2_statfs_change *str = buf; 378 const struct gfs2_statfs_change *str = buf;
359 379
@@ -441,6 +461,29 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
441 brelse(l_bh); 461 brelse(l_bh);
442} 462}
443 463
464void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
465 struct buffer_head *l_bh)
466{
467 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
468 struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
469 struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
470 struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
471
472 gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1);
473
474 spin_lock(&sdp->sd_statfs_spin);
475 m_sc->sc_total += l_sc->sc_total;
476 m_sc->sc_free += l_sc->sc_free;
477 m_sc->sc_dinodes += l_sc->sc_dinodes;
478 memset(l_sc, 0, sizeof(struct gfs2_statfs_change));
479 memset(l_bh->b_data + sizeof(struct gfs2_dinode),
480 0, sizeof(struct gfs2_statfs_change));
481 spin_unlock(&sdp->sd_statfs_spin);
482
483 gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1);
484 gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode));
485}
486
444int gfs2_statfs_sync(struct gfs2_sbd *sdp) 487int gfs2_statfs_sync(struct gfs2_sbd *sdp)
445{ 488{
446 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode); 489 struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
@@ -477,19 +520,7 @@ int gfs2_statfs_sync(struct gfs2_sbd *sdp)
477 if (error) 520 if (error)
478 goto out_bh2; 521 goto out_bh2;
479 522
480 gfs2_trans_add_bh(l_ip->i_gl, l_bh, 1); 523 update_statfs(sdp, m_bh, l_bh);
481
482 spin_lock(&sdp->sd_statfs_spin);
483 m_sc->sc_total += l_sc->sc_total;
484 m_sc->sc_free += l_sc->sc_free;
485 m_sc->sc_dinodes += l_sc->sc_dinodes;
486 memset(l_sc, 0, sizeof(struct gfs2_statfs_change));
487 memset(l_bh->b_data + sizeof(struct gfs2_dinode),
488 0, sizeof(struct gfs2_statfs_change));
489 spin_unlock(&sdp->sd_statfs_spin);
490
491 gfs2_trans_add_bh(m_ip->i_gl, m_bh, 1);
492 gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode));
493 524
494 gfs2_trans_end(sdp); 525 gfs2_trans_end(sdp);
495 526
@@ -680,6 +711,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
680 struct gfs2_holder t_gh; 711 struct gfs2_holder t_gh;
681 int error; 712 int error;
682 713
714 flush_workqueue(gfs2_delete_workqueue);
683 gfs2_quota_sync(sdp); 715 gfs2_quota_sync(sdp);
684 gfs2_statfs_sync(sdp); 716 gfs2_statfs_sync(sdp);
685 717
@@ -756,7 +788,6 @@ restart:
756 /* Release stuff */ 788 /* Release stuff */
757 789
758 iput(sdp->sd_jindex); 790 iput(sdp->sd_jindex);
759 iput(sdp->sd_inum_inode);
760 iput(sdp->sd_statfs_inode); 791 iput(sdp->sd_statfs_inode);
761 iput(sdp->sd_rindex); 792 iput(sdp->sd_rindex);
762 iput(sdp->sd_quota_inode); 793 iput(sdp->sd_quota_inode);
@@ -767,10 +798,8 @@ restart:
767 if (!sdp->sd_args.ar_spectator) { 798 if (!sdp->sd_args.ar_spectator) {
768 gfs2_glock_dq_uninit(&sdp->sd_journal_gh); 799 gfs2_glock_dq_uninit(&sdp->sd_journal_gh);
769 gfs2_glock_dq_uninit(&sdp->sd_jinode_gh); 800 gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);
770 gfs2_glock_dq_uninit(&sdp->sd_ir_gh);
771 gfs2_glock_dq_uninit(&sdp->sd_sc_gh); 801 gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
772 gfs2_glock_dq_uninit(&sdp->sd_qc_gh); 802 gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
773 iput(sdp->sd_ir_inode);
774 iput(sdp->sd_sc_inode); 803 iput(sdp->sd_sc_inode);
775 iput(sdp->sd_qc_inode); 804 iput(sdp->sd_qc_inode);
776 } 805 }
@@ -1072,6 +1101,7 @@ static int gfs2_remount_fs(struct super_block *sb, int *flags, char *data)
1072 gt->gt_log_flush_secs = args.ar_commit; 1101 gt->gt_log_flush_secs = args.ar_commit;
1073 spin_unlock(&gt->gt_spin); 1102 spin_unlock(&gt->gt_spin);
1074 1103
1104 gfs2_online_uevent(sdp);
1075 return 0; 1105 return 0;
1076} 1106}
1077 1107
@@ -1213,6 +1243,22 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
1213 lfsecs = sdp->sd_tune.gt_log_flush_secs; 1243 lfsecs = sdp->sd_tune.gt_log_flush_secs;
1214 if (lfsecs != 60) 1244 if (lfsecs != 60)
1215 seq_printf(s, ",commit=%d", lfsecs); 1245 seq_printf(s, ",commit=%d", lfsecs);
1246 if (args->ar_errors != GFS2_ERRORS_DEFAULT) {
1247 const char *state;
1248
1249 switch (args->ar_errors) {
1250 case GFS2_ERRORS_WITHDRAW:
1251 state = "withdraw";
1252 break;
1253 case GFS2_ERRORS_PANIC:
1254 state = "panic";
1255 break;
1256 default:
1257 state = "unknown";
1258 break;
1259 }
1260 seq_printf(s, ",errors=%s", state);
1261 }
1216 return 0; 1262 return 0;
1217} 1263}
1218 1264
@@ -1240,6 +1286,10 @@ static void gfs2_delete_inode(struct inode *inode)
1240 goto out; 1286 goto out;
1241 } 1287 }
1242 1288
1289 error = gfs2_check_blk_type(sdp, ip->i_no_addr, GFS2_BLKST_UNLINKED);
1290 if (error)
1291 goto out_truncate;
1292
1243 gfs2_glock_dq_wait(&ip->i_iopen_gh); 1293 gfs2_glock_dq_wait(&ip->i_iopen_gh);
1244 gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); 1294 gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh);
1245 error = gfs2_glock_nq(&ip->i_iopen_gh); 1295 error = gfs2_glock_nq(&ip->i_iopen_gh);