mirror of
https://github.com/torvalds/linux.git
synced 2026-05-22 14:12:07 +02:00
bcachefs: bcachefs_metadata_version_backpointer_bucket_gen
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>
This commit is contained in:
parent
6679e363f4
commit
ebdca07268
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user