bcachefs: Have fsck check for stripe pointers matching stripe
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
53b3e3c0e2
commit
b3b66e3044
@ -223,6 +223,11 @@ static int bch2_check_fix_ptrs(struct bch_fs *c, enum btree_id btree_id,
|
||||
"pointer to nonexistent stripe %llu",
|
||||
(u64) p.ec.idx))
|
||||
do_update = true;
|
||||
|
||||
if (fsck_err_on(!bch2_ptr_matches_stripe_m(m, p), c,
|
||||
"pointer does not match stripe %llu",
|
||||
(u64) p.ec.idx))
|
||||
do_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,8 +279,22 @@ again:
|
||||
if (extent_entry_type(entry) == BCH_EXTENT_ENTRY_stripe_ptr) {
|
||||
struct stripe *m = genradix_ptr(&c->stripes[true],
|
||||
entry->stripe_ptr.idx);
|
||||
union bch_extent_entry *next_ptr;
|
||||
|
||||
if (!m || !m->alive) {
|
||||
bkey_extent_entry_for_each_from(ptrs, next_ptr, entry)
|
||||
if (extent_entry_type(next_ptr) == BCH_EXTENT_ENTRY_ptr)
|
||||
goto found;
|
||||
next_ptr = NULL;
|
||||
found:
|
||||
if (!next_ptr) {
|
||||
bch_err(c, "aieee, found stripe ptr with no data ptr");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!m || !m->alive ||
|
||||
!__bch2_ptr_matches_stripe(&m->ptrs[entry->stripe_ptr.block],
|
||||
&next_ptr->ptr,
|
||||
m->sectors)) {
|
||||
bch2_bkey_extent_entry_drop(new, entry);
|
||||
goto again;
|
||||
}
|
||||
|
@ -1215,6 +1215,8 @@ static int bch2_mark_stripe(struct bch_fs *c,
|
||||
m->block_sectors[i] =
|
||||
stripe_blockcount_get(new_s, i);
|
||||
m->blocks_nonempty += !!m->block_sectors[i];
|
||||
|
||||
m->ptrs[i] = new_s->ptrs[i];
|
||||
}
|
||||
|
||||
bch2_bkey_to_replicas(&m->r.e, new);
|
||||
|
@ -151,7 +151,8 @@ static int bkey_matches_stripe(struct bch_stripe *s,
|
||||
|
||||
bkey_for_each_ptr(ptrs, ptr)
|
||||
for (i = 0; i < nr_data; i++)
|
||||
if (__bch2_ptr_matches_stripe(s, ptr, i))
|
||||
if (__bch2_ptr_matches_stripe(&s->ptrs[i], ptr,
|
||||
le16_to_cpu(s->sectors)))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
|
@ -84,27 +84,42 @@ static inline void stripe_csum_set(struct bch_stripe *s,
|
||||
memcpy(stripe_csum(s, block, csum_idx), &csum, bch_crc_bytes[s->csum_type]);
|
||||
}
|
||||
|
||||
static inline bool __bch2_ptr_matches_stripe(const struct bch_stripe *s,
|
||||
const struct bch_extent_ptr *ptr,
|
||||
unsigned block)
|
||||
static inline bool __bch2_ptr_matches_stripe(const struct bch_extent_ptr *stripe_ptr,
|
||||
const struct bch_extent_ptr *data_ptr,
|
||||
unsigned sectors)
|
||||
{
|
||||
unsigned nr_data = s->nr_blocks - s->nr_redundant;
|
||||
|
||||
if (block >= nr_data)
|
||||
return false;
|
||||
|
||||
return ptr->dev == s->ptrs[block].dev &&
|
||||
ptr->gen == s->ptrs[block].gen &&
|
||||
ptr->offset >= s->ptrs[block].offset &&
|
||||
ptr->offset < s->ptrs[block].offset + le16_to_cpu(s->sectors);
|
||||
return data_ptr->dev == stripe_ptr->dev &&
|
||||
data_ptr->gen == stripe_ptr->gen &&
|
||||
data_ptr->offset >= stripe_ptr->offset &&
|
||||
data_ptr->offset < stripe_ptr->offset + sectors;
|
||||
}
|
||||
|
||||
static inline bool bch2_ptr_matches_stripe(const struct bch_stripe *s,
|
||||
struct extent_ptr_decoded p)
|
||||
{
|
||||
unsigned nr_data = s->nr_blocks - s->nr_redundant;
|
||||
|
||||
BUG_ON(!p.has_ec);
|
||||
|
||||
return __bch2_ptr_matches_stripe(s, &p.ptr, p.ec.block);
|
||||
if (p.ec.block >= nr_data)
|
||||
return false;
|
||||
|
||||
return __bch2_ptr_matches_stripe(&s->ptrs[p.ec.block], &p.ptr,
|
||||
le16_to_cpu(s->sectors));
|
||||
}
|
||||
|
||||
static inline bool bch2_ptr_matches_stripe_m(const struct stripe *m,
|
||||
struct extent_ptr_decoded p)
|
||||
{
|
||||
unsigned nr_data = m->nr_blocks - m->nr_redundant;
|
||||
|
||||
BUG_ON(!p.has_ec);
|
||||
|
||||
if (p.ec.block >= nr_data)
|
||||
return false;
|
||||
|
||||
return __bch2_ptr_matches_stripe(&m->ptrs[p.ec.block], &p.ptr,
|
||||
m->sectors);
|
||||
}
|
||||
|
||||
struct bch_read_bio;
|
||||
|
@ -22,6 +22,7 @@ struct stripe {
|
||||
unsigned on_heap:1;
|
||||
u8 blocks_nonempty;
|
||||
u16 block_sectors[BCH_BKEY_PTRS_MAX];
|
||||
struct bch_extent_ptr ptrs[BCH_BKEY_PTRS_MAX];
|
||||
|
||||
struct bch_replicas_padded r;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user