mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 09:09:55 -04:00
bcachefs: Fix degraded mode fsck
We don't know where the superblock and journal lives on offline devices; that means if a device is offline fsck can't check those buckets. Previously, fsck would incorrectly clear bucket data types for those buckets on offline devices; now we just use the previous state. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
@@ -1365,11 +1365,10 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bch_dev *ca = bch_dev_bkey_exists(c, iter->pos.inode);
|
||||
struct bucket gc, *b;
|
||||
struct bucket old_gc, gc, *b;
|
||||
struct bkey_i_alloc_v4 *a;
|
||||
struct bch_alloc_v4 old_convert, new;
|
||||
const struct bch_alloc_v4 *old;
|
||||
enum bch_data_type type;
|
||||
int ret;
|
||||
|
||||
old = bch2_alloc_to_v4(k, &old_convert);
|
||||
@@ -1377,30 +1376,31 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
|
||||
|
||||
percpu_down_read(&c->mark_lock);
|
||||
b = gc_bucket(ca, iter->pos.offset);
|
||||
old_gc = *b;
|
||||
|
||||
if ((old->data_type == BCH_DATA_sb ||
|
||||
old->data_type == BCH_DATA_journal) &&
|
||||
!bch2_dev_is_online(ca)) {
|
||||
b->data_type = old->data_type;
|
||||
b->dirty_sectors = old->dirty_sectors;
|
||||
}
|
||||
|
||||
/*
|
||||
* b->data_type doesn't yet include need_discard & need_gc_gen states -
|
||||
* fix that here:
|
||||
*/
|
||||
type = __alloc_data_type(b->dirty_sectors,
|
||||
b->cached_sectors,
|
||||
b->stripe,
|
||||
*old,
|
||||
b->data_type);
|
||||
if (b->data_type != type) {
|
||||
struct bch_dev_usage *u;
|
||||
|
||||
preempt_disable();
|
||||
u = this_cpu_ptr(ca->usage_gc);
|
||||
u->d[b->data_type].buckets--;
|
||||
b->data_type = type;
|
||||
u->d[b->data_type].buckets++;
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
b->data_type = __alloc_data_type(b->dirty_sectors,
|
||||
b->cached_sectors,
|
||||
b->stripe,
|
||||
*old,
|
||||
b->data_type);
|
||||
gc = *b;
|
||||
percpu_up_read(&c->mark_lock);
|
||||
|
||||
if (gc.data_type != old_gc.data_type ||
|
||||
gc.dirty_sectors != old_gc.dirty_sectors)
|
||||
bch2_dev_usage_update_m(c, ca, &old_gc, &gc);
|
||||
|
||||
if (metadata_only &&
|
||||
gc.data_type != BCH_DATA_sb &&
|
||||
gc.data_type != BCH_DATA_journal &&
|
||||
|
||||
Reference in New Issue
Block a user