Commit eab32c8e authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Fix validation of replicas entries

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: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 5f786787
...@@ -16,11 +16,16 @@ static inline int u8_cmp(u8 l, u8 r) ...@@ -16,11 +16,16 @@ static inline int u8_cmp(u8 l, u8 r)
return cmp_int(l, 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; 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++) for (i = 0; i + 1 < e->nr_devs; i++)
BUG_ON(e->devs[i] >= e->devs[i + 1]); BUG_ON(e->devs[i] >= e->devs[i + 1]);
#endif #endif
...@@ -158,7 +163,7 @@ cpu_replicas_add_entry(struct bch_replicas_cpu *old, ...@@ -158,7 +163,7 @@ cpu_replicas_add_entry(struct bch_replicas_cpu *old,
}; };
BUG_ON(!new_entry->data_type); 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); new.entries = kcalloc(new.nr, new.entry_size, GFP_NOIO);
if (!new.entries) if (!new.entries)
...@@ -185,7 +190,7 @@ static inline int __replicas_entry_idx(struct bch_replicas_cpu *r, ...@@ -185,7 +190,7 @@ static inline int __replicas_entry_idx(struct bch_replicas_cpu *r,
if (unlikely(entry_size > r->entry_size)) if (unlikely(entry_size > r->entry_size))
return -1; return -1;
verify_replicas_entry_sorted(search); verify_replicas_entry(search);
#define entry_cmp(_l, _r, size) memcmp(_l, _r, entry_size) #define entry_cmp(_l, _r, size) memcmp(_l, _r, entry_size)
idx = eytzinger0_find(r->entries, r->nr, 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, ...@@ -216,7 +221,7 @@ static bool bch2_replicas_marked_locked(struct bch_fs *c,
if (!search->nr_devs) if (!search->nr_devs)
return true; return true;
verify_replicas_entry_sorted(search); verify_replicas_entry(search);
return __replicas_has_entry(&c->replicas, search) && return __replicas_has_entry(&c->replicas, search) &&
(!check_gc_replicas || (!check_gc_replicas ||
...@@ -363,6 +368,8 @@ static int bch2_mark_replicas_slowpath(struct bch_fs *c, ...@@ -363,6 +368,8 @@ static int bch2_mark_replicas_slowpath(struct bch_fs *c,
struct bch_replicas_cpu new_r, new_gc; struct bch_replicas_cpu new_r, new_gc;
int ret = -ENOMEM; int ret = -ENOMEM;
verify_replicas_entry(new_entry);
memset(&new_r, 0, sizeof(new_r)); memset(&new_r, 0, sizeof(new_r));
memset(&new_gc, 0, sizeof(new_gc)); 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 ...@@ -878,9 +885,8 @@ static const char *bch2_sb_validate_replicas(struct bch_sb *sb, struct bch_sb_fi
goto err; goto err;
err = "invalid replicas entry: bad nr_required"; err = "invalid replicas entry: bad nr_required";
if (!e->nr_required || if (e->nr_required > 1 &&
(e->nr_required > 1 && e->nr_required >= e->nr_devs)
e->nr_required >= e->nr_devs))
goto err; goto err;
err = "invalid replicas entry: invalid device"; err = "invalid replicas entry: invalid device";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment