bcachefs: Fix validation of replicas entries
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 20 Sep 2019 18:28:35 +0000 (14:28 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:27 +0000 (17:08 -0400)
When an extent is erasure coded, we need to record a replicas entry to
indicate that data is present on the devices that extent has pointers to
- but nr_required should be 0, because it's erasure coded.

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

index 64024ce016655146d7aaf171ac34d84216512364..afd226f3c8e7d7e2744189246ba5de36a97b9c7e 100644 (file)
@@ -16,11 +16,16 @@ static inline int u8_cmp(u8 l, u8 r)
        return cmp_int(l, r);
 }
 
-static void verify_replicas_entry_sorted(struct bch_replicas_entry *e)
+static void verify_replicas_entry(struct bch_replicas_entry *e)
 {
-#ifdef CONFIG_BCACHES_DEBUG
+#ifdef CONFIG_BCACHEFS_DEBUG
        unsigned i;
 
+       BUG_ON(e->data_type >= BCH_DATA_NR);
+       BUG_ON(!e->nr_devs);
+       BUG_ON(e->nr_required > 1 &&
+              e->nr_required >= e->nr_devs);
+
        for (i = 0; i + 1 < e->nr_devs; i++)
                BUG_ON(e->devs[i] >= e->devs[i + 1]);
 #endif
@@ -158,7 +163,7 @@ cpu_replicas_add_entry(struct bch_replicas_cpu *old,
        };
 
        BUG_ON(!new_entry->data_type);
-       verify_replicas_entry_sorted(new_entry);
+       verify_replicas_entry(new_entry);
 
        new.entries = kcalloc(new.nr, new.entry_size, GFP_NOIO);
        if (!new.entries)
@@ -185,7 +190,7 @@ static inline int __replicas_entry_idx(struct bch_replicas_cpu *r,
        if (unlikely(entry_size > r->entry_size))
                return -1;
 
-       verify_replicas_entry_sorted(search);
+       verify_replicas_entry(search);
 
 #define entry_cmp(_l, _r, size)        memcmp(_l, _r, entry_size)
        idx = eytzinger0_find(r->entries, r->nr, r->entry_size,
@@ -216,7 +221,7 @@ static bool bch2_replicas_marked_locked(struct bch_fs *c,
        if (!search->nr_devs)
                return true;
 
-       verify_replicas_entry_sorted(search);
+       verify_replicas_entry(search);
 
        return __replicas_has_entry(&c->replicas, search) &&
                (!check_gc_replicas ||
@@ -363,6 +368,8 @@ static int bch2_mark_replicas_slowpath(struct bch_fs *c,
        struct bch_replicas_cpu new_r, new_gc;
        int ret = -ENOMEM;
 
+       verify_replicas_entry(new_entry);
+
        memset(&new_r, 0, sizeof(new_r));
        memset(&new_gc, 0, sizeof(new_gc));
 
@@ -878,9 +885,8 @@ static const char *bch2_sb_validate_replicas(struct bch_sb *sb, struct bch_sb_fi
                        goto err;
 
                err = "invalid replicas entry: bad nr_required";
-               if (!e->nr_required ||
-                   (e->nr_required > 1 &&
-                    e->nr_required >= e->nr_devs))
+               if (e->nr_required > 1 &&
+                   e->nr_required >= e->nr_devs)
                        goto err;
 
                err = "invalid replicas entry: invalid device";