bcachefs: rebalance_work btree is not a snapshots btree
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 3 Nov 2023 22:30:08 +0000 (18:30 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 5 Nov 2023 02:19:13 +0000 (22:19 -0400)
rebalance_work entries may refer to entries in the extents btree, which
is a snapshots btree, or they may also refer to entries in the reflink
btree, which is not.

Hence rebalance_work keys may use the snapshot field but it's not
required to be nonzero - add a new btree flag to reflect this.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/bcachefs_format.h
fs/bcachefs/bkey_methods.c
fs/bcachefs/btree_iter.h
fs/bcachefs/btree_trans_commit.c
fs/bcachefs/btree_types.h

index 5b44598b9df93af0f39688a49f1107b6e39aadbb..a191baa518f066cf3c229a41241ba8330983d5a2 100644 (file)
@@ -2260,7 +2260,8 @@ LE32_BITMASK(JSET_NO_FLUSH,       struct jset, flags, 5, 6);
 enum btree_id_flags {
        BTREE_ID_EXTENTS        = BIT(0),
        BTREE_ID_SNAPSHOTS      = BIT(1),
-       BTREE_ID_DATA           = BIT(2),
+       BTREE_ID_SNAPSHOT_FIELD = BIT(2),
+       BTREE_ID_DATA           = BIT(3),
 };
 
 #define BCH_BTREE_IDS()                                                                \
@@ -2315,12 +2316,12 @@ enum btree_id_flags {
          BIT_ULL(KEY_TYPE_bucket_gens))                                        \
        x(snapshot_trees,       15,     0,                                      \
          BIT_ULL(KEY_TYPE_snapshot_tree))                                      \
-       x(deleted_inodes,       16,     BTREE_ID_SNAPSHOTS,                     \
+       x(deleted_inodes,       16,     BTREE_ID_SNAPSHOT_FIELD,                \
          BIT_ULL(KEY_TYPE_set))                                                \
        x(logged_ops,           17,     0,                                      \
          BIT_ULL(KEY_TYPE_logged_op_truncate)|                                 \
          BIT_ULL(KEY_TYPE_logged_op_finsert))                                  \
-       x(rebalance_work,       18,     BTREE_ID_SNAPSHOTS,                     \
+       x(rebalance_work,       18,     BTREE_ID_SNAPSHOT_FIELD,                \
          BIT_ULL(KEY_TYPE_set)|BIT_ULL(KEY_TYPE_cookie))
 
 enum btree_id {
index 2f518d7e1a6444fa2f03b86235f850f7190c010c..761f5e33b1e69e94ca0aaaa41a9825e496b5840f 100644 (file)
@@ -186,15 +186,20 @@ int __bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
        if (type != BKEY_TYPE_btree) {
                enum btree_id btree = type - 1;
 
-               bkey_fsck_err_on(!btree_type_has_snapshots(btree) &&
-                                k.k->p.snapshot, c, err,
-                                bkey_snapshot_nonzero,
-                                "nonzero snapshot");
-
-               bkey_fsck_err_on(btree_type_has_snapshots(btree) &&
-                                !k.k->p.snapshot, c, err,
-                                bkey_snapshot_zero,
-                                "snapshot == 0");
+               if (btree_type_has_snapshots(btree)) {
+                       bkey_fsck_err_on(!k.k->p.snapshot, c, err,
+                                        bkey_snapshot_zero,
+                                        "snapshot == 0");
+               } else if (!btree_type_has_snapshot_field(btree)) {
+                       bkey_fsck_err_on(k.k->p.snapshot, c, err,
+                                        bkey_snapshot_nonzero,
+                                        "nonzero snapshot");
+               } else {
+                       /*
+                        * btree uses snapshot field but it's not required to be
+                        * nonzero
+                        */
+               }
 
                bkey_fsck_err_on(bkey_eq(k.k->p, POS_MAX), c, err,
                                 bkey_at_pos_max,
index 5e103f519e62ec280863c389cb765904a6becb91..967cde33d4332e1ccb7f324f7fb7e12f86d76cc3 100644 (file)
@@ -416,6 +416,7 @@ static inline unsigned __bch2_btree_iter_flags(struct btree_trans *trans,
                flags |= BTREE_ITER_IS_EXTENTS;
 
        if (!(flags & __BTREE_ITER_ALL_SNAPSHOTS) &&
+           !btree_type_has_snapshot_field(btree_id) &&
            !btree_type_has_snapshots(btree_id))
                flags &= ~BTREE_ITER_ALL_SNAPSHOTS;
 
index 32693f7c6221043d0c28b07e57f1b396bd845582..decad7b66c59c114a9315d7acd1ec3bf755a4230 100644 (file)
@@ -269,6 +269,7 @@ static inline void btree_insert_entry_checks(struct btree_trans *trans,
        BUG_ON(i->level         != i->path->level);
        BUG_ON(i->btree_id      != i->path->btree_id);
        EBUG_ON(!i->level &&
+               btree_type_has_snapshots(i->btree_id) &&
                !(i->flags & BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE) &&
                test_bit(JOURNAL_REPLAY_DONE, &trans->c->journal.flags) &&
                i->k->k.p.snapshot &&
index 7cc8d6b12161be2fe1c64c68a7d034c7323bd193..a685883e540590fe322b6d95abf268f3fc6928d9 100644 (file)
@@ -710,6 +710,17 @@ static inline bool btree_type_has_snapshots(enum btree_id id)
        return (1U << id) & mask;
 }
 
+static inline bool btree_type_has_snapshot_field(enum btree_id id)
+{
+       const unsigned mask = 0
+#define x(name, nr, flags, ...)        |((!!((flags) & BTREE_ID_SNAPSHOT_FIELD)) << nr)
+       BCH_BTREE_IDS()
+#undef x
+       ;
+
+       return (1U << id) & mask;
+}
+
 static inline bool btree_type_has_ptrs(enum btree_id id)
 {
        const unsigned mask = 0