]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
bcachefs: BCH_SB_MEMBER_DELETED_UUID
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 4 May 2025 01:55:26 +0000 (21:55 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 22 May 2025 00:14:49 +0000 (20:14 -0400)
Add a sentinal value for devices that have been removed, but don't want
to reuse their index until a fsck has completed.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_gc.c
fs/bcachefs/sb-members.c
fs/bcachefs/sb-members.h
fs/bcachefs/sb-members_format.h

index 92ae31737a24500553b457ed0a1507e9cecc7d89..dd08ec080313f203c562b66113887bdd3679da9e 100644 (file)
@@ -1079,6 +1079,10 @@ out:
         * allocator thread - issue wakeup in case they blocked on gc_lock:
         */
        closure_wake_up(&c->freelist_wait);
+
+       if (!ret && !test_bit(BCH_FS_errors_not_fixed, &c->flags))
+               bch2_sb_members_clean_deleted(c);
+
        bch_err_fn(c, ret);
        return ret;
 }
index f6a0b3de6bcab5e347b85abbd26797e5588850b8..b9568a68fbf64caed7fa4aefee9aa3b84b8738c9 100644 (file)
@@ -525,6 +525,7 @@ int bch2_sb_member_alloc(struct bch_fs *c)
        unsigned u64s;
        int best = -1;
        u64 best_last_mount = 0;
+       unsigned nr_deleted = 0;
 
        if (dev_idx < BCH_SB_MEMBERS_MAX)
                goto have_slot;
@@ -535,7 +536,10 @@ int bch2_sb_member_alloc(struct bch_fs *c)
                        continue;
 
                struct bch_member m = bch2_sb_member_get(c->disk_sb.sb, dev_idx);
-               if (bch2_member_alive(&m))
+
+               nr_deleted += uuid_equal(&m.uuid, &BCH_SB_MEMBER_DELETED_UUID);
+
+               if (!bch2_is_zero(&m.uuid, sizeof(m.uuid)))
                        continue;
 
                u64 last_mount = le64_to_cpu(m.last_mount);
@@ -549,6 +553,10 @@ int bch2_sb_member_alloc(struct bch_fs *c)
                goto have_slot;
        }
 
+       if (nr_deleted)
+               bch_err(c, "unable to allocate new member, but have %u deleted: run fsck",
+                       nr_deleted);
+
        return -BCH_ERR_ENOSPC_sb_members;
 have_slot:
        nr_devices = max_t(unsigned, dev_idx + 1, c->sb.nr_devices);
@@ -564,3 +572,22 @@ have_slot:
        c->disk_sb.sb->nr_devices = nr_devices;
        return dev_idx;
 }
+
+void bch2_sb_members_clean_deleted(struct bch_fs *c)
+{
+       mutex_lock(&c->sb_lock);
+       bool write_sb = false;
+
+       for (unsigned i = 0; i < c->sb.nr_devices; i++) {
+               struct bch_member *m = bch2_members_v2_get_mut(c->disk_sb.sb, i);
+
+               if (uuid_equal(&m->uuid, &BCH_SB_MEMBER_DELETED_UUID)) {
+                       memset(&m->uuid, 0, sizeof(m->uuid));
+                       write_sb = true;
+               }
+       }
+
+       if (write_sb)
+               bch2_write_super(c);
+       mutex_unlock(&c->sb_lock);
+}
index c9cb8f7657b04d869d6d5b2bc262ad7379295f87..6bd9b86aee5b426176a2178f3d1ddb9f9a71997d 100644 (file)
@@ -320,7 +320,8 @@ extern const struct bch_sb_field_ops bch_sb_field_ops_members_v2;
 
 static inline bool bch2_member_alive(struct bch_member *m)
 {
-       return !bch2_is_zero(&m->uuid, sizeof(m->uuid));
+       return  !bch2_is_zero(&m->uuid, sizeof(m->uuid)) &&
+               !uuid_equal(&m->uuid, &BCH_SB_MEMBER_DELETED_UUID);
 }
 
 static inline bool bch2_member_exists(struct bch_sb *sb, unsigned dev)
@@ -381,5 +382,6 @@ bool bch2_dev_btree_bitmap_marked(struct bch_fs *, struct bkey_s_c);
 void bch2_dev_btree_bitmap_mark(struct bch_fs *, struct bkey_s_c);
 
 int bch2_sb_member_alloc(struct bch_fs *);
+void bch2_sb_members_clean_deleted(struct bch_fs *);
 
 #endif /* _BCACHEFS_SB_MEMBERS_H */
index 472218a5910257ddd1c129e8927ee91ff38767ff..fb72ad730518f7808914b0883022ef914d0381cb 100644 (file)
  */
 #define BCH_SB_MEMBER_INVALID          255
 
+#define BCH_SB_MEMBER_DELETED_UUID                                     \
+       UUID_INIT(0xffffffff, 0xffff, 0xffff,                           \
+                 0xd9, 0x6a, 0x60, 0xcf, 0x80, 0x3d, 0xf7, 0xef)
+
 #define BCH_MIN_NR_NBUCKETS    (1 << 6)
 
 #define BCH_IOPS_MEASUREMENTS()                        \