Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d34843d0 authored by Bob Peterson's avatar Bob Peterson Committed by Steven Whitehouse
Browse files

GFS2: Add "-o errors=panic|withdraw" mount options



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).

Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent cd012075
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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 */
};

+1 −0
Original line number Diff line number Diff line
@@ -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) {
+36 −0
Original line number Diff line number Diff line
@@ -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;
}

+27 −14
Original line number Diff line number Diff line
@@ -38,13 +38,15 @@ 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);

	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);

@@ -56,6 +58,10 @@ int gfs2_lm_withdraw(struct gfs2_sbd *sdp, char *fmt, ...)
		}
		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,6 +99,7 @@ int gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion,
			gfs2_tune_get(sdp, gt_complain_secs) * HZ))
		return -2;

	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",
@@ -104,6 +111,12 @@ int gfs2_assert_warn_i(struct gfs2_sbd *sdp, char *assertion,
	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;