bcachefs: Have fsck check for stripe pointers matching stripe
authorKent Overstreet <kent.overstreet@gmail.com>
Fri, 12 Mar 2021 21:55:28 +0000 (16:55 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:55 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_gc.c
fs/bcachefs/buckets.c
fs/bcachefs/ec.c
fs/bcachefs/ec.h
fs/bcachefs/ec_types.h

index 808bb9ca8d50fb4ab34a53ce8b63ec342086bd43..e8cdc82d3451f5a04dfb18f9c4adf2cdb0f6d77e 100644 (file)
@@ -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;
+
+                                       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) {
+                                       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;
                                        }
index 55b9818a1dc2c760025d7fff2d8f78bb247561b9..7bf2fded816ff80e23c95725727774da90d4f2e5 100644 (file)
@@ -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);
index ced8ceeef9921412b56579cdac7014157a2d6f29..f61d4c873a82bf3c1043021e57e7b5ba6ab9af31 100644 (file)
@@ -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;
index 765baa9d926426431e92791267d47b86fd14b48f..744e51eaf327e66577b768479b384d25c07a88db 100644 (file)
@@ -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)
+{
+       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;
 
-       if (block >= nr_data)
+       BUG_ON(!p.has_ec);
+
+       if (p.ec.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 __bch2_ptr_matches_stripe(&s->ptrs[p.ec.block], &p.ptr,
+                                        le16_to_cpu(s->sectors));
 }
 
-static inline bool bch2_ptr_matches_stripe(const struct bch_stripe *s,
-                                          struct extent_ptr_decoded p)
+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);
 
-       return __bch2_ptr_matches_stripe(s, &p.ptr, p.ec.block);
+       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;
index 847770166223f6af2e93c391bb996d1750cc7866..3fc31222459a81fd92ec2fbdc1225d5bf9bedbfe 100644 (file)
@@ -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;
 };