]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bcachefs: Device options now use standard sysfs code
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 11 Mar 2025 22:44:25 +0000 (18:44 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 24 Mar 2025 13:50:35 +0000 (09:50 -0400)
Device options now use the common code for sysfs, and can superblock
fields (in a struct bch_member).

This replaces BCH_DEV_OPT_SETTERS(), which was weird and easy to miss.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/opts.c
fs/bcachefs/opts.h
fs/bcachefs/super.c
fs/bcachefs/sysfs.c
fs/bcachefs/sysfs.h
fs/bcachefs/xattr.c

index ae47345f93c130590fa57d599cfddfef7093dfe6..de24af773224334090d0064315a8e3f42a789030 100644 (file)
@@ -480,7 +480,7 @@ void bch2_opts_to_text(struct printbuf *out,
        }
 }
 
-int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v)
+int bch2_opt_check_may_set(struct bch_fs *c, struct bch_dev *ca, int id, u64 v)
 {
        int ret = 0;
 
@@ -501,7 +501,7 @@ int bch2_opt_check_may_set(struct bch_fs *c, int id, u64 v)
 int bch2_opts_check_may_set(struct bch_fs *c)
 {
        for (unsigned i = 0; i < bch2_opts_nr; i++) {
-               int ret = bch2_opt_check_may_set(c, i, bch2_opt_get_by_id(&c->opts, i));
+               int ret = bch2_opt_check_may_set(c, NULL, i, bch2_opt_get_by_id(&c->opts, i));
                if (ret)
                        return ret;
        }
index c0adfd5b4f1c35dff1835b3fb808d08d2abe3a27..19fcc0e51c0bd7e585c4c89c6b1e66d67c812df6 100644 (file)
@@ -635,7 +635,7 @@ void bch2_opts_to_text(struct printbuf *,
                       struct bch_fs *, struct bch_sb *,
                       unsigned, unsigned, unsigned);
 
-int bch2_opt_check_may_set(struct bch_fs *, int, u64);
+int bch2_opt_check_may_set(struct bch_fs *, struct bch_dev *, int, u64);
 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 *);
index 8e928b3d8ef4a0b8671da35033d86637ca6ece0e..d662adfbdbcc60d2fc64d6fd3b6212683a093868 100644 (file)
@@ -715,7 +715,7 @@ static int bch2_fs_online(struct bch_fs *c)
            kobject_add(&c->time_stats, &c->kobj, "time_stats") ?:
 #endif
            kobject_add(&c->counters_kobj, &c->kobj, "counters") ?:
-           bch2_opts_create_sysfs_files(&c->opts_dir);
+           bch2_opts_create_sysfs_files(&c->opts_dir, OPT_FS);
        if (ret) {
                bch_err(c, "error creating sysfs objects");
                return ret;
@@ -1297,8 +1297,8 @@ static int bch2_dev_sysfs_online(struct bch_fs *c, struct bch_dev *ca)
                return 0;
 
        if (!ca->kobj.state_in_sysfs) {
-               ret = kobject_add(&ca->kobj, &c->kobj,
-                                 "dev-%u", ca->dev_idx);
+               ret =   kobject_add(&ca->kobj, &c->kobj, "dev-%u", ca->dev_idx) ?:
+                       bch2_opts_create_sysfs_files(&ca->kobj, OPT_DEVICE);
                if (ret)
                        return ret;
        }
index 2ed3f755eadd7b3f912d2e08ecb71964ddc1b0fc..4c5b585041bea1ccbff06277e2da1faf131c2508 100644 (file)
@@ -152,10 +152,8 @@ read_attribute(gc_gens_pos);
 read_attribute(uuid);
 read_attribute(minor);
 read_attribute(flags);
-read_attribute(bucket_size);
 read_attribute(first_bucket);
 read_attribute(nbuckets);
-rw_attribute(durability);
 read_attribute(io_done);
 read_attribute(io_errors);
 write_attribute(io_errors_reset);
@@ -208,8 +206,6 @@ read_attribute(usage_base);
 BCH_PERSISTENT_COUNTERS()
 #undef x
 
-rw_attribute(discard);
-read_attribute(state);
 rw_attribute(label);
 
 read_attribute(copy_gc_wait);
@@ -599,26 +595,34 @@ struct attribute *bch2_fs_internal_files[] = {
 
 /* options */
 
-SHOW(bch2_fs_opts_dir)
+static ssize_t sysfs_opt_show(struct bch_fs *c,
+                             struct bch_dev *ca,
+                             enum bch_opt_id id,
+                             struct printbuf *out)
 {
-       struct bch_fs *c = container_of(kobj, struct bch_fs, opts_dir);
-       const struct bch_option *opt = container_of(attr, struct bch_option, attr);
-       int id = opt - bch2_opt_table;
-       u64 v = bch2_opt_get_by_id(&c->opts, id);
+       const struct bch_option *opt = bch2_opt_table + id;
+       u64 v;
+
+       if (opt->flags & OPT_FS) {
+               v = bch2_opt_get_by_id(&c->opts, id);
+       } else if ((opt->flags & OPT_DEVICE) && opt->get_member)  {
+               v = bch2_opt_from_sb(c->disk_sb.sb, id, ca->dev_idx);
+       } else {
+               return -EINVAL;
+       }
 
        bch2_opt_to_text(out, c, c->disk_sb.sb, opt, v, OPT_SHOW_FULL_LIST);
        prt_char(out, '\n');
-
        return 0;
 }
 
-STORE(bch2_fs_opts_dir)
+static ssize_t sysfs_opt_store(struct bch_fs *c,
+                              struct bch_dev *ca,
+                              enum bch_opt_id id,
+                              const char *buf, size_t size)
 {
-       struct bch_fs *c = container_of(kobj, struct bch_fs, opts_dir);
-       const struct bch_option *opt = container_of(attr, struct bch_option, attr);
-       int ret, id = opt - bch2_opt_table;
-       char *tmp;
-       u64 v;
+       const struct bch_option *opt = bch2_opt_table + id;
+       int ret = 0;
 
        /*
         * We don't need to take c->writes for correctness, but it eliminates an
@@ -627,23 +631,21 @@ STORE(bch2_fs_opts_dir)
        if (unlikely(!bch2_write_ref_tryget(c, BCH_WRITE_REF_sysfs)))
                return -EROFS;
 
-       tmp = kstrdup(buf, GFP_KERNEL);
+       char *tmp = kstrdup(buf, GFP_KERNEL);
        if (!tmp) {
                ret = -ENOMEM;
                goto err;
        }
 
-       ret = bch2_opt_parse(c, opt, strim(tmp), &v, NULL);
+       u64 v;
+       ret =   bch2_opt_parse(c, opt, strim(tmp), &v, NULL) ?:
+               bch2_opt_check_may_set(c, ca, id, v);
        kfree(tmp);
 
        if (ret < 0)
                goto err;
 
-       ret = bch2_opt_check_may_set(c, id, v);
-       if (ret < 0)
-               goto err;
-
-       bch2_opt_set_sb(c, NULL, opt, v);
+       bch2_opt_set_sb(c, ca, opt, v);
        bch2_opt_set_by_id(&c->opts, id, v);
 
        if (v &&
@@ -664,22 +666,41 @@ err:
        bch2_write_ref_put(c, BCH_WRITE_REF_sysfs);
        return ret;
 }
+
+SHOW(bch2_fs_opts_dir)
+{
+       struct bch_fs *c = container_of(kobj, struct bch_fs, opts_dir);
+       int id = bch2_opt_lookup(attr->name);
+       if (id < 0)
+               return 0;
+
+       return sysfs_opt_show(c, NULL, id, out);
+}
+
+STORE(bch2_fs_opts_dir)
+{
+       struct bch_fs *c = container_of(kobj, struct bch_fs, opts_dir);
+       int id = bch2_opt_lookup(attr->name);
+       if (id < 0)
+               return 0;
+
+       return sysfs_opt_store(c, NULL, id, buf, size);
+}
 SYSFS_OPS(bch2_fs_opts_dir);
 
 struct attribute *bch2_fs_opts_dir_files[] = { NULL };
 
-int bch2_opts_create_sysfs_files(struct kobject *kobj)
+int bch2_opts_create_sysfs_files(struct kobject *kobj, unsigned type)
 {
-       const struct bch_option *i;
-       int ret;
-
-       for (i = bch2_opt_table;
+       for (const struct bch_option *i = bch2_opt_table;
             i < bch2_opt_table + bch2_opts_nr;
             i++) {
-               if (!(i->flags & OPT_FS))
+               if (i->flags & OPT_HIDDEN)
+                       continue;
+               if (!(i->flags & type))
                        continue;
 
-               ret = sysfs_create_file(kobj, &i->attr);
+               int ret = sysfs_create_file(kobj, &i->attr);
                if (ret)
                        return ret;
        }
@@ -750,11 +771,8 @@ SHOW(bch2_dev)
 
        sysfs_printf(uuid,              "%pU\n", ca->uuid.b);
 
-       sysfs_print(bucket_size,        bucket_bytes(ca));
        sysfs_print(first_bucket,       ca->mi.first_bucket);
        sysfs_print(nbuckets,           ca->mi.nbuckets);
-       sysfs_print(durability,         ca->mi.durability);
-       sysfs_print(discard,            ca->mi.discard);
 
        if (attr == &sysfs_label) {
                if (ca->mi.group)
@@ -767,11 +785,6 @@ SHOW(bch2_dev)
                prt_char(out, '\n');
        }
 
-       if (attr == &sysfs_state) {
-               prt_string_option(out, bch2_member_states, ca->mi.state);
-               prt_char(out, '\n');
-       }
-
        if (attr == &sysfs_io_done)
                dev_io_done_to_text(out, ca);
 
@@ -797,6 +810,10 @@ SHOW(bch2_dev)
        if (attr == &sysfs_open_buckets)
                bch2_open_buckets_to_text(out, c, ca);
 
+       int opt_id = bch2_opt_lookup(attr->name);
+       if (opt_id >= 0)
+               return sysfs_opt_show(c, ca, opt_id, out);
+
        return 0;
 }
 
@@ -805,18 +822,6 @@ STORE(bch2_dev)
        struct bch_dev *ca = container_of(kobj, struct bch_dev, kobj);
        struct bch_fs *c = ca->fs;
 
-       if (attr == &sysfs_discard) {
-               bool v = strtoul_or_return(buf);
-
-               bch2_opt_set_sb(c, ca, bch2_opt_table + Opt_discard, v);
-       }
-
-       if (attr == &sysfs_durability) {
-               u64 v = strtoul_or_return(buf);
-
-               bch2_opt_set_sb(c, ca, bch2_opt_table + Opt_durability, v);
-       }
-
        if (attr == &sysfs_label) {
                char *tmp;
                int ret;
@@ -834,20 +839,20 @@ STORE(bch2_dev)
        if (attr == &sysfs_io_errors_reset)
                bch2_dev_errors_reset(ca);
 
+       int opt_id = bch2_opt_lookup(attr->name);
+       if (opt_id >= 0)
+               return sysfs_opt_store(c, ca, opt_id, buf, size);
+
        return size;
 }
 SYSFS_OPS(bch2_dev);
 
 struct attribute *bch2_dev_files[] = {
        &sysfs_uuid,
-       &sysfs_bucket_size,
        &sysfs_first_bucket,
        &sysfs_nbuckets,
-       &sysfs_durability,
 
        /* settings: */
-       &sysfs_discard,
-       &sysfs_state,
        &sysfs_label,
 
        &sysfs_has_data,
index 222cd5062702cdd6a54335dcd058b95320867f8f..303e0433c702c667dd7701c2976fc6bb014289de 100644 (file)
@@ -23,7 +23,7 @@ extern const struct sysfs_ops bch2_fs_opts_dir_sysfs_ops;
 extern const struct sysfs_ops bch2_fs_time_stats_sysfs_ops;
 extern const struct sysfs_ops bch2_dev_sysfs_ops;
 
-int bch2_opts_create_sysfs_files(struct kobject *);
+int bch2_opts_create_sysfs_files(struct kobject *, unsigned);
 
 #else
 
@@ -41,7 +41,8 @@ static const struct sysfs_ops bch2_fs_opts_dir_sysfs_ops;
 static const struct sysfs_ops bch2_fs_time_stats_sysfs_ops;
 static const struct sysfs_ops bch2_dev_sysfs_ops;
 
-static inline int bch2_opts_create_sysfs_files(struct kobject *kobj) { return 0; }
+static inline int bch2_opts_create_sysfs_files(struct kobject *kobj, unsigned type)
+{ return 0; }
 
 #endif /* NO_BCACHEFS_SYSFS */
 
index aed7c69841734a0d85ef8e2adf68f21ec15fa9e4..f9667b944c0d800bdb7f081917ea3a794d49e750 100644 (file)
@@ -523,7 +523,7 @@ static int bch2_xattr_bcachefs_set(const struct xattr_handler *handler,
                if (ret < 0)
                        goto err_class_exit;
 
-               ret = bch2_opt_check_may_set(c, opt_id, v);
+               ret = bch2_opt_check_may_set(c, NULL, opt_id, v);
                if (ret < 0)
                        goto err_class_exit;