Commit a7cdf227 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Add an "ignore unknown" option to bch2_parse_mount_opts()



To be used by the mount helper in userspace, where we still have options
to be parsed by other layers.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent daa77133
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -2179,7 +2179,7 @@ static int bch2_fs_get_tree(struct fs_context *fc)

	/* Some options can't be parsed until after the fs is started: */
	opts = bch2_opts_empty();
	ret = bch2_parse_mount_opts(c, &opts, NULL, opts_parse->parse_later.buf);
	ret = bch2_parse_mount_opts(c, &opts, NULL, opts_parse->parse_later.buf, false);
	if (ret)
		goto err_stop_fs;

@@ -2334,6 +2334,8 @@ static int bch2_fs_parse_param(struct fs_context *fc,
	int ret = bch2_parse_one_mount_opt(c, &opts->opts,
					   &opts->parse_later, param->key,
					   param->string);
	if (ret)
		pr_err("Error parsing option %s: %s", param->key, bch2_err_str(ret));

	return bch2_err_class(ret);
}
+2 −2
Original line number Diff line number Diff line
@@ -3021,7 +3021,7 @@ long bch2_ioctl_fsck_offline(struct bch_ioctl_fsck_offline __user *user_arg)
	if (arg.opts) {
		char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16);
		ret =   PTR_ERR_OR_ZERO(optstr) ?:
			bch2_parse_mount_opts(NULL, &thr->opts, NULL, optstr);
			bch2_parse_mount_opts(NULL, &thr->opts, NULL, optstr, false);
		if (!IS_ERR(optstr))
			kfree(optstr);

@@ -3129,7 +3129,7 @@ long bch2_ioctl_fsck_online(struct bch_fs *c, struct bch_ioctl_fsck_online arg)
		char *optstr = strndup_user((char __user *)(unsigned long) arg.opts, 1 << 16);

		ret =   PTR_ERR_OR_ZERO(optstr) ?:
			bch2_parse_mount_opts(c, &thr->opts, NULL, optstr);
			bch2_parse_mount_opts(c, &thr->opts, NULL, optstr, false);
		if (!IS_ERR(optstr))
			kfree(optstr);

+20 −23
Original line number Diff line number Diff line
@@ -549,14 +549,15 @@ int bch2_parse_one_mount_opt(struct bch_fs *c, struct bch_opts *opts,
		goto bad_opt;

	ret = bch2_opt_parse(c, &bch2_opt_table[id], val, &v, &err);
	if (ret == -BCH_ERR_option_needs_open_fs && parse_later) {
	if (ret == -BCH_ERR_option_needs_open_fs) {
		ret = 0;

		if (parse_later) {
			prt_printf(parse_later, "%s=%s,", name, val);
		if (parse_later->allocation_failure) {
			if (parse_later->allocation_failure)
				ret = -ENOMEM;
			goto out;
		}

		ret = 0;
		goto out;
	}

@@ -567,28 +568,24 @@ int bch2_parse_one_mount_opt(struct bch_fs *c, struct bch_opts *opts,
		bch2_opt_set_by_id(opts, id, v);

	ret = 0;
	goto out;

out:
	printbuf_exit(&err);
	return ret;
bad_opt:
	pr_err("Bad mount option %s", name);
	ret = -BCH_ERR_option_name;
	goto out;

bad_val:
	pr_err("Invalid mount option %s", err.buf);
	ret = -BCH_ERR_option_value;

out:
	printbuf_exit(&err);
	return ret;
	goto out;
}

int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
			  struct printbuf *parse_later, char *options)
			  struct printbuf *parse_later, char *options,
			  bool ignore_unknown)
{
	char *copied_opts, *copied_opts_start;
	char *opt, *name, *val;
	int ret;
	int ret = 0;

	if (!options)
		return 0;
@@ -613,14 +610,14 @@ int bch2_parse_mount_opts(struct bch_fs *c, struct bch_opts *opts,
		val	= opt;

		ret = bch2_parse_one_mount_opt(c, opts, parse_later, name, val);
		if (ret < 0)
			goto out;
	}

		if (ret == -BCH_ERR_option_name && ignore_unknown)
			ret = 0;
	goto out;
		if (ret) {
			pr_err("Error parsing option %s: %s", name, bch2_err_str(ret));
			break;
		}
	}

out:
	kfree(copied_opts_start);
	return ret;
}
+1 −1
Original line number Diff line number Diff line
@@ -636,7 +636,7 @@ int bch2_opts_check_may_set(struct bch_fs *);
int bch2_parse_one_mount_opt(struct bch_fs *, struct bch_opts *,
			     struct printbuf *, const char *, const char *);
int bch2_parse_mount_opts(struct bch_fs *, struct bch_opts *, struct printbuf *,
			  char *);
			  char *, bool);

/* inode opts: */