bcachefs: Rewrite bch2_bucket_alloc_new_fs()

This changes bch2_bucket_alloc_new_fs() to a simple bump allocator that
doesn't need to use the in memory bucket array, part of a larger patch
series to entirely get rid of the in memory bucket array, except for
gc/fsck.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
Kent Overstreet 2021-12-24 04:22:20 -05:00 committed by Kent Overstreet
parent 7243498de7
commit 09943313d7
6 changed files with 45 additions and 13 deletions

View File

@ -513,6 +513,18 @@ static bool bch2_can_invalidate_bucket(struct bch_dev *ca, size_t b,
test_bit(b, ca->buckets_nouse))
return false;
if (ca->new_fs_bucket_idx) {
/*
* Device or filesystem is still being initialized, and we
* haven't fully marked superblocks & journal:
*/
if (is_superblock_bucket(ca, b))
return false;
if (b < ca->new_fs_bucket_idx)
return false;
}
gc_gen = bucket_gc_gen(bucket(ca, b));
ca->inc_gen_needs_gc += gc_gen >= BUCKET_GC_GEN_MAX / 2;

View File

@ -144,21 +144,15 @@ static void verify_not_stale(struct bch_fs *c, const struct open_buckets *obs)
/* _only_ for allocating the journal on a new device: */
long bch2_bucket_alloc_new_fs(struct bch_dev *ca)
{
struct bucket_array *buckets;
ssize_t b;
while (ca->new_fs_bucket_idx < ca->mi.nbuckets) {
u64 b = ca->new_fs_bucket_idx++;
rcu_read_lock();
buckets = bucket_array(ca);
if (!is_superblock_bucket(ca, b) &&
(!ca->buckets_nouse || !test_bit(b, ca->buckets_nouse)))
return b;
}
for (b = buckets->first_bucket; b < buckets->nbuckets; b++)
if (is_available_bucket(buckets->b[b].mark) &&
(!ca->buckets_nouse || !test_bit(b, ca->buckets_nouse)) &&
!buckets->b[b].mark.owned_by_allocator)
goto success;
b = -1;
success:
rcu_read_unlock();
return b;
return -1;
}
static inline unsigned open_buckets_reserved(enum alloc_reserve reserve)

View File

@ -453,6 +453,7 @@ struct bch_dev {
struct bch_dev_usage __percpu *usage_gc;
/* Allocator: */
u64 new_fs_bucket_idx;
struct task_struct __rcu *alloc_thread;
/*

View File

@ -1429,6 +1429,8 @@ int bch2_fs_initialize(struct bch_fs *c)
percpu_ref_put(&ca->ref);
goto err;
}
ca->new_fs_bucket_idx = 0;
}
err = "error creating root snapshot node";

View File

@ -1726,6 +1726,8 @@ int bch2_dev_add(struct bch_fs *c, const char *path)
if (ret)
goto err_late;
ca->new_fs_bucket_idx = 0;
if (ca->mi.state == BCH_MEMBER_STATE_rw) {
ret = __bch2_dev_read_write(c, ca);
if (ret)

View File

@ -194,6 +194,27 @@ static inline struct bch_devs_mask bch2_online_devs(struct bch_fs *c)
return devs;
}
static inline bool is_superblock_bucket(struct bch_dev *ca, u64 b)
{
struct bch_sb_layout *layout = &ca->disk_sb.sb->layout;
u64 b_offset = bucket_to_sector(ca, b);
u64 b_end = bucket_to_sector(ca, b + 1);
unsigned i;
if (!b)
return true;
for (i = 0; i < layout->nr_superblocks; i++) {
u64 offset = le64_to_cpu(layout->sb_offset[i]);
u64 end = offset + (1 << layout->sb_max_size_bits);
if (!(offset >= b_end || end <= b_offset))
return true;
}
return false;
}
struct bch_fs *bch2_dev_to_fs(dev_t);
struct bch_fs *bch2_uuid_to_fs(__uuid_t);