bcachefs: Check for duplicate device ptrs in bch2_bkey_ptrs_invalid()
authorKent Overstreet <kent.overstreet@gmail.com>
Wed, 16 Dec 2020 19:18:33 +0000 (14:18 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:50 +0000 (17:08 -0400)
This is something we clearly should be checking for, but weren't -
oops.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/extents.c
fs/bcachefs/replicas.c
fs/bcachefs/util.h

index f9838c1..7cdfd09 100644 (file)
@@ -1045,11 +1045,13 @@ static const char *extent_ptr_invalid(const struct bch_fs *c,
 const char *bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k)
 {
        struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
+       struct bch_devs_list devs;
        const union bch_extent_entry *entry;
        struct bch_extent_crc_unpacked crc;
        unsigned size_ondisk = k.k->size;
        const char *reason;
        unsigned nonce = UINT_MAX;
+       unsigned i;
 
        if (k.k->type == KEY_TYPE_btree_ptr)
                size_ondisk = c->opts.btree_node_size;
@@ -1100,6 +1102,12 @@ const char *bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k)
                }
        }
 
+       devs = bch2_bkey_devs(k);
+       bubble_sort(devs.devs, devs.nr, u8_cmp);
+       for (i = 0; i + 1 < devs.nr; i++)
+               if (devs.devs[i] == devs.devs[i + 1])
+                       return "multiple ptrs to same device";
+
        return NULL;
 }
 
index 85c97f6..57c2e66 100644 (file)
@@ -11,11 +11,6 @@ static int bch2_cpu_replicas_to_sb_replicas(struct bch_fs *,
 
 /* Replicas tracking - in memory: */
 
-static inline int u8_cmp(u8 l, u8 r)
-{
-       return cmp_int(l, r);
-}
-
 static void verify_replicas_entry(struct bch_replicas_entry *e)
 {
 #ifdef CONFIG_BCACHEFS_DEBUG
index 7b7c638..91aa8c0 100644 (file)
@@ -750,4 +750,9 @@ u64 *bch2_acc_percpu_u64s(u64 __percpu *, unsigned);
 
 #define cmp_int(l, r)          ((l > r) - (l < r))
 
+static inline int u8_cmp(u8 l, u8 r)
+{
+       return cmp_int(l, r);
+}
+
 #endif /* _BCACHEFS_UTIL_H */