diff options
Diffstat (limited to 'libbcachefs/sb-members.c')
-rw-r--r-- | libbcachefs/sb-members.c | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/libbcachefs/sb-members.c b/libbcachefs/sb-members.c index 6245e342..0573c7b0 100644 --- a/libbcachefs/sb-members.c +++ b/libbcachefs/sb-members.c @@ -12,27 +12,34 @@ int bch2_dev_missing_bkey(struct bch_fs *c, struct bkey_s_c k, unsigned dev) { - struct printbuf buf = PRINTBUF; + CLASS(printbuf, buf)(); bch2_log_msg_start(c, &buf); - prt_printf(&buf, "pointer to nonexistent device %u in key\n", dev); + bool removed = test_bit(dev, c->devs_removed.d); + + prt_printf(&buf, "pointer to %s device %u in key\n", + removed ? "removed" : "nonexistent", dev); bch2_bkey_val_to_text(&buf, c, k); + prt_newline(&buf); - bool print = bch2_count_fsck_err(c, ptr_to_invalid_device, &buf); + bool print = removed + ? bch2_count_fsck_err(c, ptr_to_removed_device, &buf) + : bch2_count_fsck_err(c, ptr_to_invalid_device, &buf); int ret = bch2_run_explicit_recovery_pass(c, &buf, BCH_RECOVERY_PASS_check_allocations, 0); if (print) bch2_print_str(c, KERN_ERR, buf.buf); - printbuf_exit(&buf); return ret; } void bch2_dev_missing_atomic(struct bch_fs *c, unsigned dev) { if (dev != BCH_SB_MEMBER_INVALID) - bch2_fs_inconsistent(c, "pointer to nonexistent device %u", dev); + bch2_fs_inconsistent(c, "pointer to %s device %u", + test_bit(dev, c->devs_removed.d) + ? "removed" : "nonexistent", dev); } void bch2_dev_bucket_missing(struct bch_dev *ca, u64 bucket) @@ -413,14 +420,29 @@ void bch2_sb_members_from_cpu(struct bch_fs *c) } } +void bch2_sb_members_to_cpu(struct bch_fs *c) +{ + for_each_member_device(c, ca) { + struct bch_member m = bch2_sb_member_get(c->disk_sb.sb, ca->dev_idx); + ca->mi = bch2_mi_to_cpu(&m); + } + + struct bch_sb_field_members_v2 *mi2 = bch2_sb_field_get(c->disk_sb.sb, members_v2); + if (mi2) + for (unsigned i = 0; i < c->sb.nr_devices; i++) { + struct bch_member m = members_v2_get(mi2, i); + bool removed = uuid_equal(&m.uuid, &BCH_SB_MEMBER_DELETED_UUID); + mod_bit(i, c->devs_removed.d, removed); + } +} + void bch2_dev_io_errors_to_text(struct printbuf *out, struct bch_dev *ca) { struct bch_fs *c = ca->fs; struct bch_member m; - mutex_lock(&ca->fs->sb_lock); - m = bch2_sb_member_get(c->disk_sb.sb, ca->dev_idx); - mutex_unlock(&ca->fs->sb_lock); + scoped_guard(mutex, &ca->fs->sb_lock) + m = bch2_sb_member_get(c->disk_sb.sb, ca->dev_idx); printbuf_tabstop_push(out, 12); @@ -447,16 +469,15 @@ void bch2_dev_io_errors_to_text(struct printbuf *out, struct bch_dev *ca) void bch2_dev_errors_reset(struct bch_dev *ca) { struct bch_fs *c = ca->fs; - struct bch_member *m; - mutex_lock(&c->sb_lock); - m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx); + guard(mutex)(&c->sb_lock); + + struct bch_member *m = bch2_members_v2_get_mut(c->disk_sb.sb, ca->dev_idx); for (unsigned i = 0; i < ARRAY_SIZE(m->errors_at_reset); i++) m->errors_at_reset[i] = cpu_to_le64(atomic64_read(&ca->errors[i])); m->errors_reset_time = cpu_to_le64(ktime_get_real_seconds()); bch2_write_super(c); - mutex_unlock(&c->sb_lock); } /* @@ -588,7 +609,7 @@ have_slot: void bch2_sb_members_clean_deleted(struct bch_fs *c) { - mutex_lock(&c->sb_lock); + guard(mutex)(&c->sb_lock); bool write_sb = false; for (unsigned i = 0; i < c->sb.nr_devices; i++) { @@ -602,5 +623,4 @@ void bch2_sb_members_clean_deleted(struct bch_fs *c) if (write_sb) bch2_write_super(c); - mutex_unlock(&c->sb_lock); } |