Commit 5250b74d authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: bucket_gens btree

To improve mount times, add a btree for just bucket gens, 256 of them
per key: this means we'll have to scan drastically less metadata at
startup.

This adds
 - trigger for keeping it in sync with the all btree
 - initialization code, for filesystems from previous versions
 - new path for reading bucket gens
 - new fsck code

And a new on disk format version.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 19fe87e0
This diff is collapsed.
......@@ -148,6 +148,16 @@ void bch2_alloc_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
.atomic_trigger = bch2_mark_alloc, \
})
int bch2_bucket_gens_invalid(const struct bch_fs *, struct bkey_s_c, int, struct printbuf *);
void bch2_bucket_gens_to_text(struct printbuf *, struct bch_fs *, struct bkey_s_c);
#define bch2_bkey_ops_bucket_gens ((struct bkey_ops) { \
.key_invalid = bch2_bucket_gens_invalid, \
.val_to_text = bch2_bucket_gens_to_text, \
})
int bch2_bucket_gens_init(struct bch_fs *);
static inline bool bkey_is_alloc(const struct bkey *k)
{
return k->type == KEY_TYPE_alloc ||
......@@ -156,6 +166,7 @@ static inline bool bkey_is_alloc(const struct bkey *k)
}
int bch2_alloc_read(struct bch_fs *);
int bch2_bucket_gens_read(struct bch_fs *);
int bch2_trans_mark_alloc(struct btree_trans *, enum btree_id, unsigned,
struct bkey_s_c, struct bkey_i *, unsigned);
......
......@@ -441,6 +441,7 @@ enum gc_phase {
GC_PHASE_BTREE_freespace,
GC_PHASE_BTREE_need_discard,
GC_PHASE_BTREE_backpointers,
GC_PHASE_BTREE_bucket_gens,
GC_PHASE_PENDING_DELETE,
};
......
......@@ -371,7 +371,8 @@ static inline void bkey_init(struct bkey *k)
x(lru, 26) \
x(alloc_v4, 27) \
x(backpointer, 28) \
x(inode_v3, 29)
x(inode_v3, 29) \
x(bucket_gens, 30)
enum bch_bkey_type {
#define x(name, nr) KEY_TYPE_##name = nr,
......@@ -1013,6 +1014,15 @@ struct bch_backpointer {
struct bpos pos;
} __packed __aligned(8);
#define KEY_TYPE_BUCKET_GENS_BITS 8
#define KEY_TYPE_BUCKET_GENS_NR (1U << KEY_TYPE_BUCKET_GENS_BITS)
#define KEY_TYPE_BUCKET_GENS_MASK (KEY_TYPE_BUCKET_GENS_NR - 1)
struct bch_bucket_gens {
struct bch_val v;
u8 gens[KEY_TYPE_BUCKET_GENS_NR];
} __packed __aligned(8);
/* Quotas: */
enum quota_types {
......@@ -1551,7 +1561,8 @@ struct bch_sb_field_journal_seq_blacklist {
x(new_data_types, 21) \
x(backpointers, 22) \
x(inode_v3, 23) \
x(unwritten_extents, 24)
x(unwritten_extents, 24) \
x(bucket_gens, 25)
enum bcachefs_metadata_version {
bcachefs_metadata_version_min = 9,
......@@ -2086,7 +2097,8 @@ LE32_BITMASK(JSET_NO_FLUSH, struct jset, flags, 5, 6);
x(lru, 10) \
x(freespace, 11) \
x(need_discard, 12) \
x(backpointers, 13)
x(backpointers, 13) \
x(bucket_gens, 14)
enum btree_id {
#define x(kwd, val) BTREE_ID_##kwd = val,
......
......@@ -196,6 +196,9 @@ static unsigned bch2_key_types_allowed[] = {
[BKEY_TYPE_backpointers] =
(1U << KEY_TYPE_deleted)|
(1U << KEY_TYPE_backpointer),
[BKEY_TYPE_bucket_gens] =
(1U << KEY_TYPE_deleted)|
(1U << KEY_TYPE_bucket_gens),
[BKEY_TYPE_btree] =
(1U << KEY_TYPE_deleted)|
(1U << KEY_TYPE_btree_ptr)|
......
......@@ -929,6 +929,7 @@ static bool btree_id_is_alloc(enum btree_id id)
case BTREE_ID_backpointers:
case BTREE_ID_need_discard:
case BTREE_ID_freespace:
case BTREE_ID_bucket_gens:
return true;
default:
return false;
......@@ -1237,7 +1238,9 @@ int bch2_fs_recovery(struct bch_fs *c)
err = "error reading allocation information";
down_read(&c->gc_lock);
ret = bch2_alloc_read(c);
ret = c->sb.version < bcachefs_metadata_version_bucket_gens
? bch2_alloc_read(c)
: bch2_bucket_gens_read(c);
up_read(&c->gc_lock);
if (ret)
......@@ -1362,6 +1365,16 @@ int bch2_fs_recovery(struct bch_fs *c)
if (ret)
goto err;
if (c->sb.version < bcachefs_metadata_version_bucket_gens &&
c->opts.version_upgrade) {
bch_info(c, "initializing bucket_gens");
err = "error initializing bucket gens";
ret = bch2_bucket_gens_init(c);
if (ret)
goto err;
bch_verbose(c, "bucket_gens init done");
}
if (c->sb.version < bcachefs_metadata_version_snapshot_2) {
/* set bi_subvol on root inode */
err = "error upgrade root inode for subvolumes";
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment