]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
bcachefs: bch2_opt_set_sb() can now set (some) device options
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 15 Jul 2024 23:26:46 +0000 (19:26 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 9 Sep 2024 13:41:47 +0000 (09:41 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/opts.c
fs/bcachefs/opts.h
fs/bcachefs/sysfs.c

index 8e2fd064b50f0a1b3126bd191a63490d8aaae880..2e6e58360789750403944cfe378fef80c5898918 100644 (file)
@@ -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);
 
-       opt->set_sb(sb, v);
+       if (opt->flags & OPT_FS) {
+               if (opt->set_sb != SET_BCH2_NO_SB_OPT)
+                       opt->set_sb(sb, v);
+       }
+
+       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, const struct bch_option *opt, u64 v)
+void bch2_opt_set_sb(struct bch_fs *c, struct bch_dev *ca,
+                    const struct bch_option *opt, u64 v)
 {
-       if (opt->set_sb == SET_BCH2_NO_SB_OPT)
-               return;
-
        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);
 }
index 1c7b68b25bb7599c7616102f9ee511ca46fb47fd..32f895dfb330f3baa2588e0195e11a41b20d1796 100644 (file)
@@ -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 *);
index abaf9510fd96b13effa2c33e6e39f554590ef2af..d97ac9444592be574af1965155a5f27e9b8f0783 100644 (file)
@@ -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) {