From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steven Whitehouse Date: Mon, 24 Aug 2009 09:54:31 +0100 Subject: [Cluster-devel] Re: [GFS2 patch] Add "-o errors=panic|withdraw" mount options In-Reply-To: <789942392.18381250778599446.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> References: <789942392.18381250778599446.JavaMail.root@zmail06.collab.prod.int.phx2.redhat.com> Message-ID: <1251104071.3406.0.camel@localhost.localdomain> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi, Now in the -nmw git tree. Thanks, Steve. On Thu, 2009-08-20 at 10:29 -0400, Bob Peterson wrote: > Hi, > > This patch adds "-o errors=panic" and "-o errors=withdraw" to the > gfs2 mount options. The "errors=withdraw" option is today's > current behaviour, meaning to withdraw from the file system if a > non-serious gfs2 error occurs. The new "errors=panic" option > tells gfs2 to force a kernel panic if a non-serious gfs2 file > system error occurs. This may be useful, for example, where > fabric-level fencing is used that has no way to reboot (such as > fence_scsi). > > Regards, > > Bob Peterson > Red Hat GFS > > Signed-off-by: Bob Peterson > -- > fs/gfs2/incore.h | 7 +++++++ > fs/gfs2/ops_fstype.c | 1 + > fs/gfs2/super.c | 36 ++++++++++++++++++++++++++++++++++++ > fs/gfs2/util.c | 41 +++++++++++++++++++++++++++-------------- > 4 files changed, 71 insertions(+), 14 deletions(-) > > diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h > index 61801ad..1d11e6e 100644 > --- a/fs/gfs2/incore.h > +++ b/fs/gfs2/incore.h > @@ -406,6 +406,12 @@ struct gfs2_statfs_change_host { > #define GFS2_DATA_WRITEBACK 1 > #define GFS2_DATA_ORDERED 2 > > +#define GFS2_ERRORS_DEFAULT GFS2_ERRORS_WITHDRAW > +#define GFS2_ERRORS_WITHDRAW 0 > +#define GFS2_ERRORS_CONTINUE 1 /* place holder for future feature */ > +#define GFS2_ERRORS_RO 2 /* place holder for future feature */ > +#define GFS2_ERRORS_PANIC 3 > + > struct gfs2_args { > char ar_lockproto[GFS2_LOCKNAME_LEN]; /* Name of the Lock Protocol */ > char ar_locktable[GFS2_LOCKNAME_LEN]; /* Name of the Lock Table */ > @@ -422,6 +428,7 @@ struct gfs2_args { > unsigned int ar_data:2; /* ordered/writeback */ > unsigned int ar_meta:1; /* mount metafs */ > unsigned int ar_discard:1; /* discard requests */ > + unsigned int ar_errors:2; /* errors=withdraw | panic */ > int ar_commit; /* Commit interval */ > }; > > diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c > index 39021c0..165518a 100644 > --- a/fs/gfs2/ops_fstype.c > +++ b/fs/gfs2/ops_fstype.c > @@ -1168,6 +1168,7 @@ static int fill_super(struct super_block *sb, void *data, int silent) > sdp->sd_args.ar_quota = GFS2_QUOTA_DEFAULT; > sdp->sd_args.ar_data = GFS2_DATA_DEFAULT; > sdp->sd_args.ar_commit = 60; > + sdp->sd_args.ar_errors = GFS2_ERRORS_DEFAULT; > > error = gfs2_mount_args(sdp, &sdp->sd_args, data); > if (error) { > diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c > index 85bd2bc..7a5c128 100644 > --- a/fs/gfs2/super.c > +++ b/fs/gfs2/super.c > @@ -68,6 +68,8 @@ enum { > Opt_discard, > Opt_nodiscard, > Opt_commit, > + Opt_err_withdraw, > + Opt_err_panic, > Opt_error, > }; > > @@ -97,6 +99,8 @@ static const match_table_t tokens = { > {Opt_discard, "discard"}, > {Opt_nodiscard, "nodiscard"}, > {Opt_commit, "commit=%d"}, > + {Opt_err_withdraw, "errors=withdraw"}, > + {Opt_err_panic, "errors=panic"}, > {Opt_error, NULL} > }; > > @@ -152,6 +156,11 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options) > args->ar_localcaching = 1; > break; > case Opt_debug: > + if (args->ar_errors == GFS2_ERRORS_PANIC) { > + fs_info(sdp, "-o debug and -o errors=panic " > + "are mutually exclusive.\n"); > + return -EINVAL; > + } > args->ar_debug = 1; > break; > case Opt_nodebug: > @@ -205,6 +214,17 @@ int gfs2_mount_args(struct gfs2_sbd *sdp, struct gfs2_args *args, char *options) > return rv ? rv : -EINVAL; > } > break; > + case Opt_err_withdraw: > + args->ar_errors = GFS2_ERRORS_WITHDRAW; > + break; > + case Opt_err_panic: > + if (args->ar_debug) { > + fs_info(sdp, "-o debug and -o errors=panic " > + "are mutually exclusive.\n"); > + return -EINVAL; > + } > + args->ar_errors = GFS2_ERRORS_PANIC; > + break; > case Opt_error: > default: > fs_info(sdp, "invalid mount option: %s\n", o); > @@ -1226,6 +1246,22 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) > lfsecs = sdp->sd_tune.gt_log_flush_secs; > if (lfsecs != 60) > seq_printf(s, ",commit=%d", lfsecs); > + if (args->ar_errors != GFS2_ERRORS_DEFAULT) { > + const char *state; > + > + switch (args->ar_errors) { > + case GFS2_ERRORS_WITHDRAW: > + state = "withdraw"; > + break; > + case GFS2_ERRORS_PANIC: > + state = "panic"; > + break; > + default: > + state = "unknown"; > + break; > + } > + seq_printf(s, ",errors=%s", state); > + } > return 0; > } > > diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c > index 9d12b11..f6a7efa 100644 > --- a/fs/gfs2/util.c > +++ b/fs/gfs2/util.c > @@ -38,24 +38,30 @@ int gfs2_lm_withdraw(struct gfs2_sbd *sdp, char *fmt, ...) > const struct lm_lockops *lm = ls->ls_ops; > va_list args; > > - if (test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags)) > + if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW && > + test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags)) > return 0; > > va_start(args, fmt); > vprintk(fmt, args); > va_end(args); > > - fs_err(sdp, "about to withdraw this file system\n"); > - BUG_ON(sdp->sd_args.ar_debug); > + if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) { > + fs_err(sdp, "about to withdraw this file system\n"); > + BUG_ON(sdp->sd_args.ar_debug); > > - kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE); > + kobject_uevent(&sdp->sd_kobj, KOBJ_OFFLINE); > > - if (lm->lm_unmount) { > - fs_err(sdp, "telling LM to unmount\n"); > - lm->lm_unmount(sdp); > + if (lm->lm_unmount) { > + fs_err(sdp, "telling LM to unmount\n"); > + lm->lm_unmount(sdp); > + } > + fs_err(sdp, "withdrawn\n"); > + dump_stack(); > } > - fs_err(sdp, "withdrawn\n"); > - dump_stack(); > + > + if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC) > + panic("GFS2: fsid=%s: panic requested.\n", sdp->sd_fsname); > > return -1; > } > @@ -93,17 +99,24 @@ int gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion, > gfs2_tune_get(sdp, gt_complain_secs) * HZ)) > return -2; > > - printk(KERN_WARNING > - "GFS2: fsid=%s: warning: assertion \"%s\" failed\n" > - "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", > - sdp->sd_fsname, assertion, > - sdp->sd_fsname, function, file, line); > + if (sdp->sd_args.ar_errors == GFS2_ERRORS_WITHDRAW) > + printk(KERN_WARNING > + "GFS2: fsid=%s: warning: assertion \"%s\" failed\n" > + "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", > + sdp->sd_fsname, assertion, > + sdp->sd_fsname, function, file, line); > > if (sdp->sd_args.ar_debug) > BUG(); > else > dump_stack(); > > + if (sdp->sd_args.ar_errors == GFS2_ERRORS_PANIC) > + panic("GFS2: fsid=%s: warning: assertion \"%s\" failed\n" > + "GFS2: fsid=%s: function = %s, file = %s, line = %u\n", > + sdp->sd_fsname, assertion, > + sdp->sd_fsname, function, file, line); > + > sdp->sd_last_warning = jiffies; > > return -1;