167 lines
6.4 KiB
Diff
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
|
|
|