bcachefs: bch2_disk_path_to_text() no longer takes sb_lock
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 15:12:14 +0000 (11:12 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Tue, 31 Oct 2023 16:18:37 +0000 (12:18 -0400)
We're going to be using bch2_target_to_text() ->
bch2_disk_path_to_text() from bch2_bkey_ptrs_to_text() and
bch2_bkey_ptrs_invalid(), which can be called in any context.

This patch adds the actual label to bch_disk_group_cpu so that it can be
used by bch2_disk_path_to_text, and splits out bch2_disk_path_to_text()
into two variants - like the previous patch, one for when we have a
running filesystem and another for when we only have a superblock.

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

index 67a04fbbbbee484e33eafc067ef6902f2f5a89b5..d613695abf9f67c2e9f2ab4ce91d863bdfd743c7 100644 (file)
@@ -175,6 +175,7 @@ int bch2_sb_disk_groups_to_cpu(struct bch_fs *c)
 
                dst->deleted    = BCH_GROUP_DELETED(src);
                dst->parent     = BCH_GROUP_PARENT(src);
+               memcpy(dst->label, src->label, sizeof(dst->label));
        }
 
        for (i = 0; i < c->disk_sb.sb->nr_devices; i++) {
@@ -382,7 +383,57 @@ int bch2_disk_path_find_or_create(struct bch_sb_handle *sb, const char *name)
        return v;
 }
 
-void bch2_disk_path_to_text(struct printbuf *out, struct bch_sb *sb, unsigned v)
+void bch2_disk_path_to_text(struct printbuf *out, struct bch_fs *c, unsigned v)
+{
+       struct bch_disk_groups_cpu *groups;
+       struct bch_disk_group_cpu *g;
+       unsigned nr = 0;
+       u16 path[32];
+
+       out->atomic++;
+       rcu_read_lock();
+       groups = rcu_dereference(c->disk_groups);
+       if (!groups)
+               goto invalid;
+
+       while (1) {
+               if (nr == ARRAY_SIZE(path))
+                       goto invalid;
+
+               if (v >= groups->nr)
+                       goto invalid;
+
+               g = groups->entries + v;
+
+               if (g->deleted)
+                       goto invalid;
+
+               path[nr++] = v;
+
+               if (!g->parent)
+                       break;
+
+               v = g->parent - 1;
+       }
+
+       while (nr) {
+               v = path[--nr];
+               g = groups->entries + v;
+
+               prt_printf(out, "%.*s", (int) sizeof(g->label), g->label);
+               if (nr)
+                       prt_printf(out, ".");
+       }
+out:
+       rcu_read_unlock();
+       out->atomic--;
+       return;
+invalid:
+       prt_printf(out, "invalid label %u", v);
+       goto out;
+}
+
+void bch2_disk_path_to_text_sb(struct printbuf *out, struct bch_sb *sb, unsigned v)
 {
        struct bch_sb_field_disk_groups *groups =
                bch2_sb_field_get(sb, disk_groups);
@@ -522,9 +573,7 @@ void bch2_target_to_text(struct printbuf *out, struct bch_fs *c, unsigned v)
                break;
        }
        case TARGET_GROUP:
-               mutex_lock(&c->sb_lock);
-               bch2_disk_path_to_text(out, c->disk_sb.sb, t.group);
-               mutex_unlock(&c->sb_lock);
+               bch2_disk_path_to_text(out, c, t.group);
                break;
        default:
                BUG();
@@ -552,7 +601,7 @@ void bch2_target_to_text_sb(struct printbuf *out, struct bch_sb *sb, unsigned v)
                break;
        }
        case TARGET_GROUP:
-               bch2_disk_path_to_text(out, sb, t.group);
+               bch2_disk_path_to_text_sb(out, sb, t.group);
                break;
        default:
                BUG();
index e03ccc7f13da3f136f4409ebd2e47c40485ba1d7..441826fff224369b79698442e6b314cf5331c02c 100644 (file)
@@ -85,7 +85,9 @@ int bch2_disk_path_find(struct bch_sb_handle *, const char *);
 /* Exported for userspace bcachefs-tools: */
 int bch2_disk_path_find_or_create(struct bch_sb_handle *, const char *);
 
-void bch2_disk_path_to_text(struct printbuf *, struct bch_sb *, unsigned);
+void bch2_disk_path_to_text(struct printbuf *, struct bch_fs *, unsigned);
+void bch2_disk_path_to_text_sb(struct printbuf *, struct bch_sb *, unsigned);
+
 void bch2_target_to_text(struct printbuf *out, struct bch_fs *, unsigned);
 
 int bch2_opt_target_parse(struct bch_fs *, const char *, u64 *, struct printbuf *);
index 55a67a4dca767637e976ae538947c744c406c05f..a54ef085b13d469828bfd5ea60e6686d745a7d73 100644 (file)
@@ -5,6 +5,7 @@
 struct bch_disk_group_cpu {
        bool                            deleted;
        u16                             parent;
+       u8                              label[BCH_SB_LABEL_SIZE];
        struct bch_devs_mask            devs;
 };
 
index 9d59d6246ed6aa0d70471782db5bb4b4a5af6d10..ce59018b27acc92d70b75ba68ba6e2b1c4db643a 100644 (file)
@@ -1582,7 +1582,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
        dev_mi = bch2_sb_member_get(sb.sb, sb.sb->dev_idx);
 
        if (BCH_MEMBER_GROUP(&dev_mi)) {
-               bch2_disk_path_to_text(&label, sb.sb, BCH_MEMBER_GROUP(&dev_mi) - 1);
+               bch2_disk_path_to_text_sb(&label, sb.sb, BCH_MEMBER_GROUP(&dev_mi) - 1);
                if (label.allocation_failure) {
                        ret = -ENOMEM;
                        goto err;
index 5b079369af95aec3632a287463a1193b18b1f3d5..3ac6634020d15e66cabe871581d2d8da522ec180 100644 (file)
@@ -910,13 +910,8 @@ SHOW(bch2_dev)
        sysfs_print(discard,            ca->mi.discard);
 
        if (attr == &sysfs_label) {
-               if (ca->mi.group) {
-                       mutex_lock(&c->sb_lock);
-                       bch2_disk_path_to_text(out, c->disk_sb.sb,
-                                              ca->mi.group - 1);
-                       mutex_unlock(&c->sb_lock);
-               }
-
+               if (ca->mi.group)
+                       bch2_disk_path_to_text(out, c, ca->mi.group - 1);
                prt_char(out, '\n');
        }