diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2018-11-13 01:26:36 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-23 00:08:11 +0300 |
commit | 91f8b5677b5d831cff34b25ef03322ae49e03256 (patch) | |
tree | 40589f97cf8e112b335865540d746198ce1854a7 /fs | |
parent | 1d25849c2c2d552b09494b984da915be4a703a18 (diff) | |
download | linux-91f8b5677b5d831cff34b25ef03322ae49e03256.tar.xz |
bcachefs: More btree gc refactorings
more prep work for erasure coding
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/bcachefs/btree_gc.c | 174 | ||||
-rw-r--r-- | fs/bcachefs/btree_gc.h | 1 |
2 files changed, 97 insertions, 78 deletions
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index b0d04ed5f2a6..92b82eaee69d 100644 --- a/fs/bcachefs/btree_gc.c +++ b/fs/bcachefs/btree_gc.c @@ -122,86 +122,105 @@ static bool bkey_type_needs_gc(enum bkey_type type) } } -u8 bch2_btree_key_recalc_oldest_gen(struct bch_fs *c, struct bkey_s_c k) +static void ptr_gen_recalc_oldest(struct bch_fs *c, + const struct bch_extent_ptr *ptr, + u8 *max_stale) { - const struct bch_extent_ptr *ptr; - u8 max_stale = 0; + struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev); + size_t b = PTR_BUCKET_NR(ca, ptr); - if (bkey_extent_is_data(k.k)) { - struct bkey_s_c_extent e = bkey_s_c_to_extent(k); + if (gen_after(ca->oldest_gens[b], ptr->gen)) + ca->oldest_gens[b] = ptr->gen; - extent_for_each_ptr(e, ptr) { - struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev); - size_t b = PTR_BUCKET_NR(ca, ptr); + *max_stale = max(*max_stale, ptr_stale(ca, ptr)); +} - if (gen_after(ca->oldest_gens[b], ptr->gen)) - ca->oldest_gens[b] = ptr->gen; +static u8 ptr_gens_recalc_oldest(struct bch_fs *c, + enum bkey_type type, + struct bkey_s_c k) +{ + const struct bch_extent_ptr *ptr; + u8 max_stale = 0; - max_stale = max(max_stale, ptr_stale(ca, ptr)); + switch (type) { + case BKEY_TYPE_BTREE: + case BKEY_TYPE_EXTENTS: + switch (k.k->type) { + case BCH_EXTENT: + case BCH_EXTENT_CACHED: { + struct bkey_s_c_extent e = bkey_s_c_to_extent(k); + + extent_for_each_ptr(e, ptr) + ptr_gen_recalc_oldest(c, ptr, &max_stale); + break; } + } + break; + default: + break; } return max_stale; } -static int bch2_btree_mark_ptrs_initial(struct bch_fs *c, enum bkey_type type, - struct bkey_s_c k) +static int ptr_gen_check(struct bch_fs *c, + enum bkey_type type, + const struct bch_extent_ptr *ptr) { - enum bch_data_type data_type = type == BKEY_TYPE_BTREE - ? BCH_DATA_BTREE : BCH_DATA_USER; + struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev); + size_t b = PTR_BUCKET_NR(ca, ptr); + struct bucket *g = PTR_BUCKET(ca, ptr); int ret = 0; - BUG_ON(journal_seq_verify(c) && - k.k->version.lo > journal_cur_seq(&c->journal)); + if (mustfix_fsck_err_on(!g->mark.gen_valid, c, + "found ptr with missing gen in alloc btree,\n" + "type %u gen %u", + type, ptr->gen)) { + g->_mark.gen = ptr->gen; + g->_mark.gen_valid = 1; + set_bit(b, ca->buckets_dirty); + } - if (test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags) || - fsck_err_on(!bch2_bkey_replicas_marked(c, type, k, false), c, - "superblock not marked as containing replicas (type %u)", - data_type)) { - ret = bch2_mark_bkey_replicas(c, type, k); - if (ret) - return ret; + if (mustfix_fsck_err_on(gen_cmp(ptr->gen, g->mark.gen) > 0, c, + "%u ptr gen in the future: %u > %u", + type, ptr->gen, g->mark.gen)) { + g->_mark.gen = ptr->gen; + g->_mark.gen_valid = 1; + set_bit(b, ca->buckets_dirty); + set_bit(BCH_FS_FIXED_GENS, &c->flags); } +fsck_err: + return ret; +} - switch (k.k->type) { - case BCH_EXTENT: - case BCH_EXTENT_CACHED: { - struct bkey_s_c_extent e = bkey_s_c_to_extent(k); - const struct bch_extent_ptr *ptr; - - extent_for_each_ptr(e, ptr) { - struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev); - size_t b = PTR_BUCKET_NR(ca, ptr); - struct bucket *g = PTR_BUCKET(ca, ptr); - - if (mustfix_fsck_err_on(!g->mark.gen_valid, c, - "found ptr with missing gen in alloc btree,\n" - "type %s gen %u", - bch2_data_types[data_type], - ptr->gen)) { - g->_mark.gen = ptr->gen; - g->_mark.gen_valid = 1; - set_bit(b, ca->buckets_dirty); - } +static int ptr_gens_check(struct bch_fs *c, enum bkey_type type, + struct bkey_s_c k) +{ + const struct bch_extent_ptr *ptr; + int ret = 0; - if (mustfix_fsck_err_on(gen_cmp(ptr->gen, g->mark.gen) > 0, c, - "%s ptr gen in the future: %u > %u", - bch2_data_types[data_type], - ptr->gen, g->mark.gen)) { - g->_mark.gen = ptr->gen; - g->_mark.gen_valid = 1; - set_bit(b, ca->buckets_dirty); - set_bit(BCH_FS_FIXED_GENS, &c->flags); - } + switch (type) { + case BKEY_TYPE_BTREE: + case BKEY_TYPE_EXTENTS: + switch (k.k->type) { + case BCH_EXTENT: + case BCH_EXTENT_CACHED: { + struct bkey_s_c_extent e = bkey_s_c_to_extent(k); + extent_for_each_ptr(e, ptr) { + ret = ptr_gen_check(c, type, ptr); + if (ret) + return ret; + + } + break; + } } break; - } + default: + break; } - if (k.k->version.lo > atomic64_read(&c->key_version)) - atomic64_set(&c->key_version, k.k->version.lo); -fsck_err: return ret; } @@ -218,31 +237,32 @@ static int bch2_gc_mark_key(struct bch_fs *c, enum bkey_type type, (initial ? BCH_BUCKET_MARK_NOATOMIC : 0); int ret = 0; - switch (type) { - case BKEY_TYPE_BTREE: - case BKEY_TYPE_EXTENTS: - if (initial) { - ret = bch2_btree_mark_ptrs_initial(c, type, k); - if (ret < 0) + if (initial) { + BUG_ON(journal_seq_verify(c) && + k.k->version.lo > journal_cur_seq(&c->journal)); + + if (k.k->version.lo > atomic64_read(&c->key_version)) + atomic64_set(&c->key_version, k.k->version.lo); + + if (test_bit(BCH_FS_REBUILD_REPLICAS, &c->flags) || + fsck_err_on(!bch2_bkey_replicas_marked(c, type, k, + false), c, + "superblock not marked as containing replicas (type %u)", + type)) { + ret = bch2_mark_bkey_replicas(c, type, k); + if (ret) return ret; } - break; - default: - break; - } - bch2_mark_key(c, type, k, true, k.k->size, - pos, NULL, 0, flags); - - switch (type) { - case BKEY_TYPE_BTREE: - case BKEY_TYPE_EXTENTS: - ret = bch2_btree_key_recalc_oldest_gen(c, k); - break; - default: - break; + ret = ptr_gens_check(c, type, k); + if (ret) + return ret; } + bch2_mark_key(c, type, k, true, k.k->size, pos, NULL, 0, flags); + + ret = ptr_gens_recalc_oldest(c, type, k); +fsck_err: return ret; } diff --git a/fs/bcachefs/btree_gc.h b/fs/bcachefs/btree_gc.h index 54c6bc845930..86b80e32e310 100644 --- a/fs/bcachefs/btree_gc.h +++ b/fs/bcachefs/btree_gc.h @@ -11,7 +11,6 @@ void bch2_gc(struct bch_fs *); void bch2_gc_thread_stop(struct bch_fs *); int bch2_gc_thread_start(struct bch_fs *); int bch2_initial_gc(struct bch_fs *, struct list_head *); -u8 bch2_btree_key_recalc_oldest_gen(struct bch_fs *, struct bkey_s_c); void bch2_mark_dev_superblock(struct bch_fs *, struct bch_dev *, unsigned); /* |