Commit 2a3731e3 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Erasure coding fixes & refactoring

 - Originally bch_extent_stripe_ptr didn't contain the block index,
   instead we'd have to search through the stripe pointers to figure out
   which pointer matched. When the block field was added to
   bch_extent_stripe_ptr, not all of the code was updated to use it.
   This patch fixes that, and we also now verify that field where it
   makes sense.

 - The ec_stripe_buf_init/exit() functions have been improved, and are
   now used by the bch2_ec_read_extent() (recovery read) path.

 - get_stripe_key() is now used by bch2_ec_read_extent().

 - We now have a getter and setter for checksums within a stripe, like
   we had previously for block sector counts, and ec_generate_checksums
   and ec_validate_checksums are now quite a bit smaller and cleaner.

ec.c still needs a lot of work, but this patch is slowly moving things
in the right direction.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent b929bbef
......@@ -1656,7 +1656,7 @@ static int bch2_trans_mark_pointer(struct btree_trans *trans,
}
static int bch2_trans_mark_stripe_ptr(struct btree_trans *trans,
struct bch_extent_stripe_ptr p,
struct extent_ptr_decoded p,
s64 sectors, enum bch_data_type data_type)
{
struct bch_fs *c = trans->c;
......@@ -1666,14 +1666,22 @@ static int bch2_trans_mark_stripe_ptr(struct btree_trans *trans,
struct bch_replicas_padded r;
int ret = 0;
ret = trans_get_key(trans, BTREE_ID_EC, POS(0, p.idx), &iter, &k);
ret = trans_get_key(trans, BTREE_ID_EC, POS(0, p.ec.idx), &iter, &k);
if (ret < 0)
return ret;
if (k.k->type != KEY_TYPE_stripe) {
bch2_fs_inconsistent(c,
"pointer to nonexistent stripe %llu",
(u64) p.idx);
(u64) p.ec.idx);
ret = -EIO;
goto out;
}
if (!bch2_ptr_matches_stripe(bkey_s_c_to_stripe(k).v, p)) {
bch2_fs_inconsistent(c,
"stripe pointer doesn't match stripe %llu",
(u64) p.ec.idx);
ret = -EIO;
goto out;
}
......@@ -1684,8 +1692,8 @@ static int bch2_trans_mark_stripe_ptr(struct btree_trans *trans,
goto out;
bkey_reassemble(&s->k_i, k);
stripe_blockcount_set(&s->v, p.block,
stripe_blockcount_get(&s->v, p.block) +
stripe_blockcount_set(&s->v, p.ec.block,
stripe_blockcount_get(&s->v, p.ec.block) +
sectors);
bch2_trans_update(trans, iter, &s->k_i, 0);
......@@ -1736,7 +1744,7 @@ static int bch2_trans_mark_extent(struct btree_trans *trans,
dirty_sectors += disk_sectors;
r.e.devs[r.e.nr_devs++] = p.ptr.dev;
} else {
ret = bch2_trans_mark_stripe_ptr(trans, p.ec,
ret = bch2_trans_mark_stripe_ptr(trans, p,
disk_sectors, data_type);
if (ret)
return ret;
......
This diff is collapsed.
......@@ -60,9 +60,51 @@ static inline unsigned stripe_val_u64s(const struct bch_stripe *s)
}
static inline void *stripe_csum(struct bch_stripe *s,
unsigned dev, unsigned csum_idx)
unsigned block, unsigned csum_idx)
{
return (void *) s + stripe_csum_offset(s, dev, csum_idx);
EBUG_ON(block >= s->nr_blocks);
EBUG_ON(csum_idx >= stripe_csums_per_device(s));
return (void *) s + stripe_csum_offset(s, block, csum_idx);
}
static inline struct bch_csum stripe_csum_get(struct bch_stripe *s,
unsigned block, unsigned csum_idx)
{
struct bch_csum csum = { 0 };
memcpy(&csum, stripe_csum(s, block, csum_idx), bch_crc_bytes[s->csum_type]);
return csum;
}
static inline void stripe_csum_set(struct bch_stripe *s,
unsigned block, unsigned csum_idx,
struct bch_csum csum)
{
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)
{
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);
}
static inline bool bch2_ptr_matches_stripe(const struct bch_stripe *s,
struct extent_ptr_decoded p)
{
BUG_ON(!p.has_ec);
return __bch2_ptr_matches_stripe(s, &p.ptr, p.ec.block);
}
struct bch_read_bio;
......
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