]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: bcachefs_metadata_version_stripe_backpointers
authorKent Overstreet <kent.overstreet@linux.dev>
Fri, 7 Feb 2025 06:34:00 +0000 (01:34 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 15 Mar 2025 01:02:15 +0000 (21:02 -0400)
Stripes now have backpointers.

This is needed for proper scrub - stripe checksums need to be verified,
separately from extents within the stripe, since a block may not be full
of live extents but it's still needed for reconstruct.

And this will be needed for (efficient) evacuate/repair paths.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/backpointers.h
fs/bcachefs/bcachefs_format.h
fs/bcachefs/ec.c
fs/bcachefs/move.c
fs/bcachefs/sb-downgrade.c

index 7786731d4adaa735334b73088cd19a1f73527e41..16575dbc5736b9cb369e18504563e14a2091ab23 100644 (file)
@@ -152,7 +152,20 @@ static inline void bch2_extent_ptr_to_bp(struct bch_fs *c,
                           struct bkey_i_backpointer *bp)
 {
        bkey_backpointer_init(&bp->k_i);
-       bp->k.p = POS(p.ptr.dev, ((u64) p.ptr.offset << MAX_EXTENT_COMPRESS_RATIO_SHIFT) + p.crc.offset);
+       bp->k.p.inode = p.ptr.dev;
+
+       if (k.k->type != KEY_TYPE_stripe)
+               bp->k.p.offset = ((u64) p.ptr.offset << MAX_EXTENT_COMPRESS_RATIO_SHIFT) + p.crc.offset;
+       else {
+               /*
+                * Put stripe backpointers where they won't collide with the
+                * extent backpointers within the stripe:
+                */
+               struct bkey_s_c_stripe s = bkey_s_c_to_stripe(k);
+               bp->k.p.offset = ((u64) (p.ptr.offset + le16_to_cpu(s.v->sectors)) <<
+                                 MAX_EXTENT_COMPRESS_RATIO_SHIFT) - 1;
+       }
+
        bp->v   = (struct bch_backpointer) {
                .btree_id       = btree_id,
                .level          = level,
index ef5009b18dd5eeab81348f3c8a611adfd6acb9b0..bf3723a2bca46dfb4303f18b815120296b3c7639 100644 (file)
@@ -687,7 +687,8 @@ struct bch_sb_field_ext {
        x(persistent_inode_cursors,     BCH_VERSION(1, 18))             \
        x(autofix_errors,               BCH_VERSION(1, 19))             \
        x(directory_size,               BCH_VERSION(1, 20))             \
-       x(cached_backpointers,          BCH_VERSION(1, 21))
+       x(cached_backpointers,          BCH_VERSION(1, 21))             \
+       x(stripe_backpointers,          BCH_VERSION(1, 22))
 
 enum bcachefs_metadata_version {
        bcachefs_metadata_version_min = 9,
index 1aa56d28de335b76d717392eab34c99c7a1ed281..36590c0ce09f85b4800d323f482f9cf48bc47c1f 100644 (file)
@@ -298,10 +298,22 @@ static int mark_stripe_bucket(struct btree_trans *trans,
        struct bpos bucket = PTR_BUCKET_POS(ca, ptr);
 
        if (flags & BTREE_TRIGGER_transactional) {
+               struct extent_ptr_decoded p = {
+                       .ptr = *ptr,
+                       .crc = bch2_extent_crc_unpack(s.k, NULL),
+               };
+               struct bkey_i_backpointer bp;
+               bch2_extent_ptr_to_bp(c, BTREE_ID_stripes, 0, s.s_c, p,
+                                     (const union bch_extent_entry *) ptr, &bp);
+
                struct bkey_i_alloc_v4 *a =
                        bch2_trans_start_alloc_update(trans, bucket, 0);
-               ret = PTR_ERR_OR_ZERO(a) ?:
-                       __mark_stripe_bucket(trans, ca, s, ptr_idx, deleting, bucket, &a->v, flags);
+               ret   = PTR_ERR_OR_ZERO(a) ?:
+                       __mark_stripe_bucket(trans, ca, s, ptr_idx, deleting, bucket, &a->v, flags) ?:
+                       bch2_bucket_backpointer_mod(trans, s.s_c, &bp,
+                                                   !(flags & BTREE_TRIGGER_overwrite));
+               if (ret)
+                       goto err;
        }
 
        if (flags & BTREE_TRIGGER_gc) {
index 12519181026f5a22e84013e30d05965a4335e116..ee489d222fba4ba4e65792942476d2c26df6ad29 100644 (file)
@@ -774,6 +774,9 @@ static int __bch2_move_data_phys(struct moving_context *ctxt,
                if (!(data_types & BIT(bp.v->data_type)))
                        goto next;
 
+               if (!bp.v->level && bp.v->btree_id == BTREE_ID_stripes)
+                       goto next;
+
                k = bch2_backpointer_get_key(trans, bp, &iter, 0, &last_flushed);
                ret = bkey_err(k);
                if (bch2_err_matches(ret, BCH_ERR_transaction_restart))
index ef985c851300da68610138083f3e1fd80dc8cbc8..acb5d845841e537fd2054e7056aec84cd26b2905 100644 (file)
@@ -92,6 +92,9 @@
          BCH_FSCK_ERR_accounting_key_replicas_nr_devs_0,       \
          BCH_FSCK_ERR_accounting_key_junk_at_end)              \
        x(cached_backpointers,                                  \
+         BIT_ULL(BCH_RECOVERY_PASS_check_extents_to_backpointers),\
+         BCH_FSCK_ERR_ptr_to_missing_backpointer)              \
+       x(stripe_backpointers,                                  \
          BIT_ULL(BCH_RECOVERY_PASS_check_extents_to_backpointers),\
          BCH_FSCK_ERR_ptr_to_missing_backpointer)