"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;
                }
        }
 
                                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;
                                        }
 
 
        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;
 
        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;