Commit 4aedeac5 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: bch2_opt_set_sb() can now set (some) device options

parent afefc986
Loading
Loading
Loading
Loading
+33 −9
Original line number Diff line number Diff line
@@ -617,10 +617,20 @@ int bch2_opts_from_sb(struct bch_opts *opts, struct bch_sb *sb)
	return 0;
}

void __bch2_opt_set_sb(struct bch_sb *sb, const struct bch_option *opt, u64 v)
struct bch_dev_sb_opt_set {
	void			(*set_sb)(struct bch_member *, u64);
};

static const struct bch_dev_sb_opt_set bch2_dev_sb_opt_setters [] = {
#define x(n, set)	[Opt_##n] = { .set_sb = SET_##set },
	BCH_DEV_OPTS()
#undef x
};

void __bch2_opt_set_sb(struct bch_sb *sb, int dev_idx,
		       const struct bch_option *opt, u64 v)
{
	if (opt->set_sb == SET_BCH2_NO_SB_OPT)
		return;
	enum bch_opt_id id = opt - bch2_opt_table;

	if (opt->flags & OPT_SB_FIELD_SECTORS)
		v >>= 9;
@@ -628,16 +638,30 @@ void __bch2_opt_set_sb(struct bch_sb *sb, const struct bch_option *opt, u64 v)
	if (opt->flags & OPT_SB_FIELD_ILOG2)
		v = ilog2(v);

	if (opt->flags & OPT_FS) {
		if (opt->set_sb != SET_BCH2_NO_SB_OPT)
			opt->set_sb(sb, v);
	}

void bch2_opt_set_sb(struct bch_fs *c, const struct bch_option *opt, u64 v)
{
	if (opt->set_sb == SET_BCH2_NO_SB_OPT)
	if ((opt->flags & OPT_DEVICE) && dev_idx >= 0) {
		if (WARN(!bch2_member_exists(sb, dev_idx),
			 "tried to set device option %s on nonexistent device %i",
			 opt->attr.name, dev_idx))
			return;

		struct bch_member *m = bch2_members_v2_get_mut(sb, dev_idx);

		const struct bch_dev_sb_opt_set *set = bch2_dev_sb_opt_setters + id;
		if (set->set_sb)
			set->set_sb(m, v);
	}
}

void bch2_opt_set_sb(struct bch_fs *c, struct bch_dev *ca,
		     const struct bch_option *opt, u64 v)
{
	mutex_lock(&c->sb_lock);
	__bch2_opt_set_sb(c->disk_sb.sb, opt, v);
	__bch2_opt_set_sb(c->disk_sb.sb, ca ? ca->dev_idx : -1, opt, v);
	bch2_write_super(c);
	mutex_unlock(&c->sb_lock);
}
+8 −2
Original line number Diff line number Diff line
@@ -490,6 +490,10 @@ enum fsck_err_opts {
	  NULL,		"BTREE_ITER_prefetch casuse btree nodes to be\n"\
	  " prefetched sequentially")

#define BCH_DEV_OPTS()							\
	x(discard,		BCH_MEMBER_DISCARD)			\
	x(data_allowed,		BCH_MEMBER_DATA_ALLOWED)

struct bch_opts {
#define x(_name, _bits, ...)	unsigned _name##_defined:1;
	BCH_OPTS()
@@ -569,8 +573,10 @@ void bch2_opt_set_by_id(struct bch_opts *, enum bch_opt_id, u64);

u64 bch2_opt_from_sb(struct bch_sb *, enum bch_opt_id);
int bch2_opts_from_sb(struct bch_opts *, struct bch_sb *);
void __bch2_opt_set_sb(struct bch_sb *, const struct bch_option *, u64);
void bch2_opt_set_sb(struct bch_fs *, const struct bch_option *, u64);
void __bch2_opt_set_sb(struct bch_sb *, int, const struct bch_option *, u64);

struct bch_dev;
void bch2_opt_set_sb(struct bch_fs *, struct bch_dev *, const struct bch_option *, u64);

int bch2_opt_lookup(const char *);
int bch2_opt_validate(const struct bch_option *, u64, struct printbuf *);
+2 −9
Original line number Diff line number Diff line
@@ -674,7 +674,7 @@ STORE(bch2_fs_opts_dir)
	if (ret < 0)
		goto err;

	bch2_opt_set_sb(c, opt, v);
	bch2_opt_set_sb(c, NULL, opt, v);
	bch2_opt_set_by_id(&c->opts, id, v);

	if (v &&
@@ -826,14 +826,7 @@ STORE(bch2_dev)
	if (attr == &sysfs_discard) {
		bool v = strtoul_or_return(buf);

		mutex_lock(&c->sb_lock);
		mi = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx);

		if (v != BCH_MEMBER_DISCARD(mi)) {
			SET_BCH_MEMBER_DISCARD(mi, v);
			bch2_write_super(c);
		}
		mutex_unlock(&c->sb_lock);
		bch2_opt_set_sb(c, ca, bch2_opt_table + Opt_discard, v);
	}

	if (attr == &sysfs_durability) {