diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2021-01-11 19:51:23 +0100 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 23:08:51 +0200 |
commit | 2a3731e34de9365038b25d76bb6e11cf5c40ac36 (patch) | |
tree | 2f9ac84593d5caf0c3fd174c7fc1ec71c22008ff /fs/bcachefs/ec.h | |
parent | bcachefs: Add cannibalize lock to btree_cache_to_text() (diff) | |
download | linux-2a3731e34de9365038b25d76bb6e11cf5c40ac36.tar.xz linux-2a3731e34de9365038b25d76bb6e11cf5c40ac36.zip |
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: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to '')
-rw-r--r-- | fs/bcachefs/ec.h | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/fs/bcachefs/ec.h b/fs/bcachefs/ec.h index 97a263cf9c87..c3959af46833 100644 --- a/fs/bcachefs/ec.h +++ b/fs/bcachefs/ec.h @@ -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; |