bcachefs: Opt_durability can now be set via bch2_opt_set_sb()
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 15 Jul 2024 23:54:51 +0000 (19:54 -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 2e6e583..0770aeb 100644 (file)
@@ -623,7 +623,7 @@ struct bch_dev_sb_opt_set {
 
 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()
+       BCH_DEV_OPT_SETTERS()
 #undef x
 };
 
@@ -638,6 +638,9 @@ void __bch2_opt_set_sb(struct bch_sb *sb, int dev_idx,
        if (opt->flags & OPT_SB_FIELD_ILOG2)
                v = ilog2(v);
 
+       if (opt->flags & OPT_SB_FIELD_ONE_BIAS)
+               v++;
+
        if (opt->flags & OPT_FS) {
                if (opt->set_sb != SET_BCH2_NO_SB_OPT)
                        opt->set_sb(sb, v);
@@ -654,6 +657,8 @@ void __bch2_opt_set_sb(struct bch_sb *sb, int 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);
+               else
+                       pr_err("option %s cannot be set via opt_set_sb()", opt->attr.name);
        }
 }
 
index 32f895d..0138717 100644 (file)
@@ -53,17 +53,18 @@ void SET_BCH2_NO_SB_OPT(struct bch_sb *, u64);
 
 /* When can be set: */
 enum opt_flags {
-       OPT_FS          = (1 << 0),     /* Filesystem option */
-       OPT_DEVICE      = (1 << 1),     /* Device option */
-       OPT_INODE       = (1 << 2),     /* Inode option */
-       OPT_FORMAT      = (1 << 3),     /* May be specified at format time */
-       OPT_MOUNT       = (1 << 4),     /* May be specified at mount time */
-       OPT_RUNTIME     = (1 << 5),     /* May be specified at runtime */
-       OPT_HUMAN_READABLE = (1 << 6),
-       OPT_MUST_BE_POW_2 = (1 << 7),   /* Must be power of 2 */
-       OPT_SB_FIELD_SECTORS = (1 << 8),/* Superblock field is >> 9 of actual value */
-       OPT_SB_FIELD_ILOG2 = (1 << 9),  /* Superblock field is ilog2 of actual value */
-       OPT_HIDDEN      = (1 << 10),
+       OPT_FS                  = BIT(0),       /* Filesystem option */
+       OPT_DEVICE              = BIT(1),       /* Device option */
+       OPT_INODE               = BIT(2),       /* Inode option */
+       OPT_FORMAT              = BIT(3),       /* May be specified at format time */
+       OPT_MOUNT               = BIT(4),       /* May be specified at mount time */
+       OPT_RUNTIME             = BIT(5),       /* May be specified at runtime */
+       OPT_HUMAN_READABLE      = BIT(6),
+       OPT_MUST_BE_POW_2       = BIT(7),       /* Must be power of 2 */
+       OPT_SB_FIELD_SECTORS    = BIT(8),       /* Superblock field is >> 9 of actual value */
+       OPT_SB_FIELD_ILOG2      = BIT(9),       /* Superblock field is ilog2 of actual value */
+       OPT_SB_FIELD_ONE_BIAS   = BIT(10),      /* 0 means default value */
+       OPT_HIDDEN              = BIT(11),
 };
 
 enum opt_type {
@@ -473,7 +474,7 @@ enum fsck_err_opts {
          BCH2_NO_SB_OPT,               0,                              \
          "size",       "Size of filesystem on device")                 \
        x(durability,                   u8,                             \
-         OPT_DEVICE,                                                   \
+         OPT_DEVICE|OPT_SB_FIELD_ONE_BIAS,                             \
          OPT_UINT(0, BCH_REPLICAS_MAX),                                \
          BCH2_NO_SB_OPT,               1,                              \
          "n",          "Data written to this device will be considered\n"\
@@ -490,8 +491,9 @@ enum fsck_err_opts {
          NULL,         "BTREE_ITER_prefetch casuse btree nodes to be\n"\
          " prefetched sequentially")
 
-#define BCH_DEV_OPTS()                                                 \
+#define BCH_DEV_OPT_SETTERS()                                          \
        x(discard,              BCH_MEMBER_DISCARD)                     \
+       x(durability,           BCH_MEMBER_DURABILITY)                  \
        x(data_allowed,         BCH_MEMBER_DATA_ALLOWED)
 
 struct bch_opts {
index d97ac94..89da532 100644 (file)
@@ -821,7 +821,6 @@ STORE(bch2_dev)
 {
        struct bch_dev *ca = container_of(kobj, struct bch_dev, kobj);
        struct bch_fs *c = ca->fs;
-       struct bch_member *mi;
 
        if (attr == &sysfs_discard) {
                bool v = strtoul_or_return(buf);
@@ -832,14 +831,7 @@ STORE(bch2_dev)
        if (attr == &sysfs_durability) {
                u64 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 + 1 != BCH_MEMBER_DURABILITY(mi)) {
-                       SET_BCH_MEMBER_DURABILITY(mi, v + 1);
-                       bch2_write_super(c);
-               }
-               mutex_unlock(&c->sb_lock);
+               bch2_opt_set_sb(c, ca, bch2_opt_table + Opt_durability, v);
        }
 
        if (attr == &sysfs_label) {