From 02afcb8c26b14ae317754d8c79339f41b3dfeaae Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Thu, 18 Aug 2022 17:57:24 -0400 Subject: [PATCH] bcachefs: Fix adding a device with a label Device labels are represented as pointers in the member info section: we need to get and then set the label for it to be kept correctly. Signed-off-by: Kent Overstreet --- fs/bcachefs/disk_groups.c | 28 +++++++++++++++------------- fs/bcachefs/disk_groups.h | 1 + fs/bcachefs/super.c | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/fs/bcachefs/disk_groups.c b/fs/bcachefs/disk_groups.c index 33d2702e68493..5f405d38b3deb 100644 --- a/fs/bcachefs/disk_groups.c +++ b/fs/bcachefs/disk_groups.c @@ -384,32 +384,34 @@ inval: prt_printf(out, "invalid label %u", v); } -int bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name) +int __bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name) { struct bch_member *mi; - int v = -1; - int ret = 0; - - mutex_lock(&c->sb_lock); + int ret, v = -1; if (!strlen(name) || !strcmp(name, "none")) - goto write_sb; + return 0; v = bch2_disk_path_find_or_create(&c->disk_sb, name); - if (v < 0) { - mutex_unlock(&c->sb_lock); + if (v < 0) return v; - } ret = bch2_sb_disk_groups_to_cpu(c); if (ret) - goto unlock; -write_sb: + return ret; + mi = &bch2_sb_get_members(c->disk_sb.sb)->members[ca->dev_idx]; SET_BCH_MEMBER_GROUP(mi, v + 1); + return 0; +} - bch2_write_super(c); -unlock: +int bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name) +{ + int ret; + + mutex_lock(&c->sb_lock); + ret = __bch2_dev_group_set(c, ca, name) ?: + bch2_write_super(c); mutex_unlock(&c->sb_lock); return ret; diff --git a/fs/bcachefs/disk_groups.h b/fs/bcachefs/disk_groups.h index de915480514b1..e4470c357a66b 100644 --- a/fs/bcachefs/disk_groups.h +++ b/fs/bcachefs/disk_groups.h @@ -82,6 +82,7 @@ void bch2_opt_target_to_text(struct printbuf *, struct bch_fs *, struct bch_sb * int bch2_sb_disk_groups_to_cpu(struct bch_fs *); +int __bch2_dev_group_set(struct bch_fs *, struct bch_dev *, const char *); int bch2_dev_group_set(struct bch_fs *, struct bch_dev *, const char *); const char *bch2_sb_validate_disk_groups(struct bch_sb *, diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index fe7938e7e07b0..1c8fac6036445 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -1522,6 +1522,7 @@ int bch2_dev_add(struct bch_fs *c, const char *path) struct bch_member dev_mi; unsigned dev_idx, nr_devices, u64s; struct printbuf errbuf = PRINTBUF; + struct printbuf label = PRINTBUF; int ret; ret = bch2_read_super(path, &opts, &sb); @@ -1532,6 +1533,14 @@ int bch2_dev_add(struct bch_fs *c, const char *path) dev_mi = bch2_sb_get_members(sb.sb)->members[sb.sb->dev_idx]; + if (BCH_MEMBER_GROUP(&dev_mi)) { + bch2_disk_path_to_text(&label, sb.sb, BCH_MEMBER_GROUP(&dev_mi) - 1); + if (label.allocation_failure) { + ret = -ENOMEM; + goto err; + } + } + err = bch2_dev_may_add(sb.sb, c); if (err) { bch_err(c, "device add error: %s", err); @@ -1612,6 +1621,14 @@ have_slot: ca->disk_sb.sb->dev_idx = dev_idx; bch2_dev_attach(c, ca, dev_idx); + if (BCH_MEMBER_GROUP(&dev_mi)) { + ret = __bch2_dev_group_set(c, ca, label.buf); + if (ret) { + bch_err(c, "device add error: error setting label"); + goto err_unlock; + } + } + bch2_write_super(c); mutex_unlock(&c->sb_lock); @@ -1644,6 +1661,7 @@ err: if (ca) bch2_dev_free(ca); bch2_free_super(&sb); + printbuf_exit(&label); printbuf_exit(&errbuf); return ret; err_late: -- 2.30.2