1

bcachefs: gc mark fn fixes, cleanups

mark_stripe_bucket() was busted; it was using @new unitialized.

Also, clean up all the gc mark functions, and convert them to the same
style.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
Kent Overstreet 2022-04-02 18:00:04 -04:00 committed by Kent Overstreet
parent 80c80164a5
commit c6b6d41612
2 changed files with 44 additions and 47 deletions

View File

@ -624,13 +624,13 @@ int bch2_mark_alloc(struct btree_trans *trans,
return 0; return 0;
} }
void bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca, int bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
size_t b, enum bch_data_type data_type, size_t b, enum bch_data_type data_type,
unsigned sectors, struct gc_pos pos, unsigned sectors, struct gc_pos pos,
unsigned flags) unsigned flags)
{ {
struct bucket old, new, *g; struct bucket old, new, *g;
bool overflow; int ret = 0;
BUG_ON(!(flags & BTREE_TRIGGER_GC)); BUG_ON(!(flags & BTREE_TRIGGER_GC));
BUG_ON(data_type != BCH_DATA_sb && BUG_ON(data_type != BCH_DATA_sb &&
@ -640,7 +640,7 @@ void bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
* Backup superblock might be past the end of our normal usable space: * Backup superblock might be past the end of our normal usable space:
*/ */
if (b >= ca->mi.nbuckets) if (b >= ca->mi.nbuckets)
return; return 0;
percpu_down_read(&c->mark_lock); percpu_down_read(&c->mark_lock);
g = gc_bucket(ca, b); g = gc_bucket(ca, b);
@ -648,27 +648,34 @@ void bch2_mark_metadata_bucket(struct bch_fs *c, struct bch_dev *ca,
bucket_lock(g); bucket_lock(g);
old = *g; old = *g;
if (bch2_fs_inconsistent_on(g->data_type &&
g->data_type != data_type, c,
"different types of data in same bucket: %s, %s",
bch2_data_types[g->data_type],
bch2_data_types[data_type])) {
ret = -EIO;
goto err;
}
if (bch2_fs_inconsistent_on((u64) g->dirty_sectors + sectors > ca->mi.bucket_size, c,
"bucket %u:%zu gen %u data type %s sector count overflow: %u + %u > bucket size",
ca->dev_idx, b, g->gen,
bch2_data_types[g->data_type ?: data_type],
g->dirty_sectors, sectors)) {
ret = -EIO;
goto err;
}
g->data_type = data_type; g->data_type = data_type;
g->dirty_sectors += sectors; g->dirty_sectors += sectors;
overflow = g->dirty_sectors < sectors;
new = *g; new = *g;
err:
bucket_unlock(g); bucket_unlock(g);
if (!ret)
bch2_fs_inconsistent_on(old.data_type &&
old.data_type != data_type, c,
"different types of data in same bucket: %s, %s",
bch2_data_types[old.data_type],
bch2_data_types[data_type]);
bch2_fs_inconsistent_on(overflow, c,
"bucket %u:%zu gen %u data type %s sector count overflow: %u + %u > U16_MAX",
ca->dev_idx, b, new.gen,
bch2_data_types[old.data_type ?: data_type],
old.dirty_sectors, sectors);
bch2_dev_usage_update_m(c, ca, old, new, 0, true); bch2_dev_usage_update_m(c, ca, old, new, 0, true);
percpu_up_read(&c->mark_lock); percpu_up_read(&c->mark_lock);
return ret;
} }
static s64 ptr_disk_sectors(s64 sectors, struct extent_ptr_decoded p) static s64 ptr_disk_sectors(s64 sectors, struct extent_ptr_decoded p)
@ -811,25 +818,22 @@ static int mark_stripe_bucket(struct btree_trans *trans,
old = *g; old = *g;
ret = check_bucket_ref(c, k, ptr, sectors, data_type, ret = check_bucket_ref(c, k, ptr, sectors, data_type,
new.gen, new.data_type, g->gen, g->data_type,
new.dirty_sectors, new.cached_sectors); g->dirty_sectors, g->cached_sectors);
if (ret) { if (ret)
bucket_unlock(g);
goto err; goto err;
}
new.dirty_sectors += sectors;
if (data_type) if (data_type)
new.data_type = data_type; g->data_type = data_type;
g->dirty_sectors += sectors;
g->stripe = k.k->p.offset; g->stripe = k.k->p.offset;
g->stripe_redundancy = s->nr_redundant; g->stripe_redundancy = s->nr_redundant;
new = *g; new = *g;
bucket_unlock(g);
bch2_dev_usage_update_m(c, ca, old, new, journal_seq, true);
err: err:
bucket_unlock(g);
if (!ret)
bch2_dev_usage_update_m(c, ca, old, new, journal_seq, true);
percpu_up_read(&c->mark_lock); percpu_up_read(&c->mark_lock);
printbuf_exit(&buf); printbuf_exit(&buf);
return ret; return ret;
@ -875,29 +879,22 @@ static int bch2_mark_pointer(struct btree_trans *trans,
percpu_down_read(&c->mark_lock); percpu_down_read(&c->mark_lock);
g = PTR_GC_BUCKET(ca, &p.ptr); g = PTR_GC_BUCKET(ca, &p.ptr);
bucket_lock(g); bucket_lock(g);
old = *g; old = *g;
bucket_data_type = g->data_type; bucket_data_type = g->data_type;
ret = __mark_pointer(trans, k, &p.ptr, sectors, ret = __mark_pointer(trans, k, &p.ptr, sectors,
data_type, g->gen, data_type, g->gen,
&bucket_data_type, &bucket_data_type,
&g->dirty_sectors, &g->dirty_sectors,
&g->cached_sectors); &g->cached_sectors);
if (ret) { if (!ret)
bucket_unlock(g);
goto err;
}
g->data_type = bucket_data_type; g->data_type = bucket_data_type;
new = *g; new = *g;
bucket_unlock(g); bucket_unlock(g);
if (!ret)
bch2_dev_usage_update_m(c, ca, old, new, journal_seq, true); bch2_dev_usage_update_m(c, ca, old, new, journal_seq, true);
err:
percpu_up_read(&c->mark_lock); percpu_up_read(&c->mark_lock);
return ret; return ret;

View File

@ -194,7 +194,7 @@ bch2_fs_usage_read_short(struct bch_fs *);
void bch2_fs_usage_initialize(struct bch_fs *); void bch2_fs_usage_initialize(struct bch_fs *);
void bch2_mark_metadata_bucket(struct bch_fs *, struct bch_dev *, int bch2_mark_metadata_bucket(struct bch_fs *, struct bch_dev *,
size_t, enum bch_data_type, unsigned, size_t, enum bch_data_type, unsigned,
struct gc_pos, unsigned); struct gc_pos, unsigned);