summaryrefslogtreecommitdiff
path: root/fs/bcachefs/ec.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-01-11 21:51:23 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:08:51 +0300
commit2a3731e34de9365038b25d76bb6e11cf5c40ac36 (patch)
tree2f9ac84593d5caf0c3fd174c7fc1ec71c22008ff /fs/bcachefs/ec.h
parentb929bbef6f9284350ad3e23a77a822a5bb2fec3d (diff)
downloadlinux-2a3731e34de9365038b25d76bb6e11cf5c40ac36.tar.xz
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 'fs/bcachefs/ec.h')
-rw-r--r--fs/bcachefs/ec.h46
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;