mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-08 14:13:53 +00:00
bcachefs: Correctly initialize new buckets on device resize
bch2_dev_resize() was never updated for the allocator rewrite with persistent freelists, and it wasn't noticed because the tests weren't running fsck - oops. Fix this by running bch2_dev_freespace_init() for the new buckets. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
4fc1f402c6
commit
69d1f052d1
@ -1831,29 +1831,33 @@ void bch2_do_invalidates(struct bch_fs *c)
|
||||
bch2_write_ref_put(c, BCH_WRITE_REF_invalidate);
|
||||
}
|
||||
|
||||
static int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
|
||||
unsigned long *last_updated)
|
||||
int bch2_dev_freespace_init(struct bch_fs *c, struct bch_dev *ca,
|
||||
u64 bucket_start, u64 bucket_end)
|
||||
{
|
||||
struct btree_trans *trans = bch2_trans_get(c);
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bkey hole;
|
||||
struct bpos end = POS(ca->dev_idx, ca->mi.nbuckets);
|
||||
struct bpos end = POS(ca->dev_idx, bucket_end);
|
||||
struct bch_member *m;
|
||||
unsigned long last_updated = jiffies;
|
||||
int ret;
|
||||
|
||||
BUG_ON(bucket_start > bucket_end);
|
||||
BUG_ON(bucket_end > ca->mi.nbuckets);
|
||||
|
||||
bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc,
|
||||
POS(ca->dev_idx, ca->mi.first_bucket),
|
||||
BTREE_ITER_PREFETCH);
|
||||
POS(ca->dev_idx, max_t(u64, ca->mi.first_bucket, bucket_start)),
|
||||
BTREE_ITER_PREFETCH);
|
||||
/*
|
||||
* Scan the alloc btree for every bucket on @ca, and add buckets to the
|
||||
* freespace/need_discard/need_gc_gens btrees as needed:
|
||||
*/
|
||||
while (1) {
|
||||
if (*last_updated + HZ * 10 < jiffies) {
|
||||
if (last_updated + HZ * 10 < jiffies) {
|
||||
bch_info(ca, "%s: currently at %llu/%llu",
|
||||
__func__, iter.pos.offset, ca->mi.nbuckets);
|
||||
*last_updated = jiffies;
|
||||
last_updated = jiffies;
|
||||
}
|
||||
|
||||
bch2_trans_begin(trans);
|
||||
@ -1935,7 +1939,6 @@ int bch2_fs_freespace_init(struct bch_fs *c)
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
bool doing_init = false;
|
||||
unsigned long last_updated = jiffies;
|
||||
|
||||
/*
|
||||
* We can crash during the device add path, so we need to check this on
|
||||
@ -1951,7 +1954,7 @@ int bch2_fs_freespace_init(struct bch_fs *c)
|
||||
doing_init = true;
|
||||
}
|
||||
|
||||
ret = bch2_dev_freespace_init(c, ca, &last_updated);
|
||||
ret = bch2_dev_freespace_init(c, ca, 0, ca->mi.nbuckets);
|
||||
if (ret) {
|
||||
percpu_ref_put(&ca->ref);
|
||||
bch_err_fn(c, ret);
|
||||
|
@ -245,6 +245,7 @@ static inline const struct bch_backpointer *alloc_v4_backpointers_c(const struct
|
||||
return (void *) ((u64 *) &a->v + BCH_ALLOC_V4_BACKPOINTERS_START(a));
|
||||
}
|
||||
|
||||
int bch2_dev_freespace_init(struct bch_fs *, struct bch_dev *, u64, u64);
|
||||
int bch2_fs_freespace_init(struct bch_fs *);
|
||||
|
||||
void bch2_recalc_capacity(struct bch_fs *);
|
||||
|
@ -1808,9 +1808,11 @@ int bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca, int flags)
|
||||
int bch2_dev_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
|
||||
{
|
||||
struct bch_member *m;
|
||||
u64 old_nbuckets;
|
||||
int ret = 0;
|
||||
|
||||
down_write(&c->state_lock);
|
||||
old_nbuckets = ca->mi.nbuckets;
|
||||
|
||||
if (nbuckets < ca->mi.nbuckets) {
|
||||
bch_err(ca, "Cannot shrink yet");
|
||||
@ -1843,6 +1845,18 @@ int bch2_dev_resize(struct bch_fs *c, struct bch_dev *ca, u64 nbuckets)
|
||||
bch2_write_super(c);
|
||||
mutex_unlock(&c->sb_lock);
|
||||
|
||||
if (ca->mi.freespace_initialized) {
|
||||
ret = bch2_dev_freespace_init(c, ca, old_nbuckets, nbuckets);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/*
|
||||
* XXX: this is all wrong transactionally - we'll be able to do
|
||||
* this correctly after the disk space accounting rewrite
|
||||
*/
|
||||
ca->usage_base->d[BCH_DATA_free].buckets += nbuckets - old_nbuckets;
|
||||
}
|
||||
|
||||
bch2_recalc_capacity(c);
|
||||
err:
|
||||
up_write(&c->state_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user