gentoo-overlay/sys-kernel/hardened-kernel/files/linux-6.12/0211-bcachefs-bcachefs_meta...

167 lines
6.4 KiB
Diff

From ab7eb8e365936471733a4ea529818354132e4bd2 Mon Sep 17 00:00:00 2001
From: Kent Overstreet <kent.overstreet@linux.dev>
Date: Sat, 16 Nov 2024 23:53:07 -0500
Subject: [PATCH 211/233] bcachefs:
bcachefs_metadata_version_backpointer_bucket_gen
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit
New on disk format version: backpointers new include the generation
number of the bucket they refer to, and the obsolete bucket_offset field
(no longer needed because we no longer store backpointers in alloc keys)
is gone.
This is an expensive forced upgrade - hopefully the last; we have to run
the extents_to_backpointers recovery pass to regenerate backpointers.
It's a forced incompatible upgrade because the alternative would've been
permamently making backpointers bigger, and as one of the biggest btrees
(along with the extents btree) that's not an ideal option.
It's worth it though, because this allows us to make the
check_extents_to_backpointers pass drastically cheaper: an upcoming
patch changes it to sum up backpointers in a bucket and check the sum
against the sector counts for that bucket, only looking for missing
backpointers if they don't match (and then only for specific buckets).
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Signed-off-by: Alexander Miroshnichenko <alex@millerson.name>
---
fs/bcachefs/backpointers.c | 27 +++++----------------------
fs/bcachefs/backpointers.h | 2 +-
fs/bcachefs/bcachefs_format.h | 6 ++++--
fs/bcachefs/sb-downgrade.c | 15 +++++++++++++--
4 files changed, 23 insertions(+), 27 deletions(-)
diff --git a/fs/bcachefs/backpointers.c b/fs/bcachefs/backpointers.c
index 0e3b7b5d626e..b19719b02df8 100644
--- a/fs/bcachefs/backpointers.c
+++ b/fs/bcachefs/backpointers.c
@@ -28,23 +28,6 @@ int bch2_backpointer_validate(struct bch_fs *c, struct bkey_s_c k,
bkey_fsck_err_on(bp.k->p.inode == BCH_SB_MEMBER_INVALID,
c, backpointer_dev_bad,
"backpointer for BCH_SB_MEMBER_INVALID");
-
- rcu_read_lock();
- struct bch_dev *ca = bch2_dev_rcu_noerror(c, bp.k->p.inode);
- if (!ca) {
- /* these will be caught by fsck */
- rcu_read_unlock();
- return 0;
- }
-
- struct bpos bucket = bp_pos_to_bucket(ca, bp.k->p);
- struct bpos bp_pos = bucket_pos_to_bp_noerror(ca, bucket, bp.v->bucket_offset);
- rcu_read_unlock();
-
- bkey_fsck_err_on((bp.v->bucket_offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT) >= ca->mi.bucket_size ||
- !bpos_eq(bp.k->p, bp_pos),
- c, backpointer_bucket_offset_wrong,
- "backpointer bucket_offset wrong (%llu)", (u64) bp.v->bucket_offset);
fsck_err:
return ret;
}
@@ -59,16 +42,17 @@ void bch2_backpointer_to_text(struct printbuf *out, struct bch_fs *c, struct bke
u32 bucket_offset;
struct bpos bucket = bp_pos_to_bucket_and_offset(ca, bp.k->p, &bucket_offset);
rcu_read_unlock();
- prt_printf(out, "bucket=%llu:%llu:%u", bucket.inode, bucket.offset, bucket_offset);
+ prt_printf(out, "bucket=%llu:%llu:%u ", bucket.inode, bucket.offset, bucket_offset);
} else {
rcu_read_unlock();
- prt_printf(out, "sector=%llu:%llu", bp.k->p.inode, bp.k->p.offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT);
+ prt_printf(out, "sector=%llu:%llu ", bp.k->p.inode, bp.k->p.offset >> MAX_EXTENT_COMPRESS_RATIO_SHIFT);
}
bch2_btree_id_level_to_text(out, bp.v->btree_id, bp.v->level);
- prt_printf(out, " suboffset=%u len=%u pos=",
+ prt_printf(out, " suboffset=%u len=%u gen=%u pos=",
(u32) bp.k->p.offset & ~(~0U << MAX_EXTENT_COMPRESS_RATIO_SHIFT),
- bp.v->bucket_len);
+ bp.v->bucket_len,
+ bp.v->bucket_gen);
bch2_bpos_to_text(out, bp.v->pos);
}
@@ -76,7 +60,6 @@ void bch2_backpointer_swab(struct bkey_s k)
{
struct bkey_s_backpointer bp = bkey_s_to_backpointer(k);
- bp.v->bucket_offset = swab40(bp.v->bucket_offset);
bp.v->bucket_len = swab32(bp.v->bucket_len);
bch2_bpos_swab(&bp.v->pos);
}
diff --git a/fs/bcachefs/backpointers.h b/fs/bcachefs/backpointers.h
index 95caeabb8978..caffc68407ab 100644
--- a/fs/bcachefs/backpointers.h
+++ b/fs/bcachefs/backpointers.h
@@ -158,7 +158,7 @@ static inline void __bch2_extent_ptr_to_bp(struct bch_fs *c, struct bch_dev *ca,
.btree_id = btree_id,
.level = level,
.data_type = bch2_bkey_ptr_data_type(k, p, entry),
- .bucket_offset = bp_bucket_offset,
+ .bucket_gen = p.ptr.gen,
.bucket_len = sectors,
.pos = k.k->p,
};
diff --git a/fs/bcachefs/bcachefs_format.h b/fs/bcachefs/bcachefs_format.h
index dc14bfe37e3b..e4bb74d6f439 100644
--- a/fs/bcachefs/bcachefs_format.h
+++ b/fs/bcachefs/bcachefs_format.h
@@ -463,7 +463,8 @@ struct bch_backpointer {
__u8 btree_id;
__u8 level;
__u8 data_type;
- __u64 bucket_offset:40;
+ __u8 bucket_gen;
+ __u32 pad;
__u32 bucket_len;
struct bpos pos;
} __packed __aligned(8);
@@ -677,7 +678,8 @@ struct bch_sb_field_ext {
x(disk_accounting_v3, BCH_VERSION(1, 10)) \
x(disk_accounting_inum, BCH_VERSION(1, 11)) \
x(rebalance_work_acct_fix, BCH_VERSION(1, 12)) \
- x(inode_has_child_snapshots, BCH_VERSION(1, 13))
+ x(inode_has_child_snapshots, BCH_VERSION(1, 13)) \
+ x(backpointer_bucket_gen, BCH_VERSION(1, 14))
enum bcachefs_metadata_version {
bcachefs_metadata_version_min = 9,
diff --git a/fs/bcachefs/sb-downgrade.c b/fs/bcachefs/sb-downgrade.c
index 8767c33c2b51..9879845413a6 100644
--- a/fs/bcachefs/sb-downgrade.c
+++ b/fs/bcachefs/sb-downgrade.c
@@ -81,7 +81,11 @@
BCH_FSCK_ERR_accounting_mismatch) \
x(inode_has_child_snapshots, \
BIT_ULL(BCH_RECOVERY_PASS_check_inodes), \
- BCH_FSCK_ERR_inode_has_child_snapshots_wrong)
+ BCH_FSCK_ERR_inode_has_child_snapshots_wrong) \
+ x(backpointer_bucket_gen, \
+ BIT_ULL(BCH_RECOVERY_PASS_check_extents_to_backpointers),\
+ BCH_FSCK_ERR_backpointer_to_missing_ptr, \
+ BCH_FSCK_ERR_ptr_to_missing_backpointer)
#define DOWNGRADE_TABLE() \
x(bucket_stripe_sectors, \
@@ -117,7 +121,14 @@
BCH_FSCK_ERR_bkey_version_in_future) \
x(rebalance_work_acct_fix, \
BIT_ULL(BCH_RECOVERY_PASS_check_allocations), \
- BCH_FSCK_ERR_accounting_mismatch)
+ BCH_FSCK_ERR_accounting_mismatch, \
+ BCH_FSCK_ERR_accounting_key_replicas_nr_devs_0, \
+ BCH_FSCK_ERR_accounting_key_junk_at_end) \
+ x(backpointer_bucket_gen, \
+ BIT_ULL(BCH_RECOVERY_PASS_check_extents_to_backpointers),\
+ BCH_FSCK_ERR_backpointer_bucket_offset_wrong, \
+ BCH_FSCK_ERR_backpointer_to_missing_ptr, \
+ BCH_FSCK_ERR_ptr_to_missing_backpointer)
struct upgrade_downgrade_entry {
u64 recovery_passes;
--
2.45.2