diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2025-08-17 19:49:31 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2025-08-17 19:52:21 -0400 |
commit | 913e63252a3b3e076837bc2791abdfbacf106aad (patch) | |
tree | 594c455c19422e8d2a735a9d1fd3287cf63c98c9 /fs/bcachefs | |
parent | 6a8d62bbb0feda0cd215228edde0d0e166a96325 (diff) |
bcachefs: Plumb printbuf through device_set_statebcachefs-testing
To be used for improving ioctl error messages.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs')
-rw-r--r-- | fs/bcachefs/chardev.c | 3 | ||||
-rw-r--r-- | fs/bcachefs/error.c | 12 | ||||
-rw-r--r-- | fs/bcachefs/opts.c | 2 | ||||
-rw-r--r-- | fs/bcachefs/replicas.c | 14 | ||||
-rw-r--r-- | fs/bcachefs/replicas.h | 2 | ||||
-rw-r--r-- | fs/bcachefs/super-io.c | 4 | ||||
-rw-r--r-- | fs/bcachefs/super.c | 40 | ||||
-rw-r--r-- | fs/bcachefs/super.h | 9 |
8 files changed, 48 insertions, 38 deletions
diff --git a/fs/bcachefs/chardev.c b/fs/bcachefs/chardev.c index 467fc45e84fe..e6ed64dc11b7 100644 --- a/fs/bcachefs/chardev.c +++ b/fs/bcachefs/chardev.c @@ -287,7 +287,8 @@ static long bch2_ioctl_disk_set_state(struct bch_fs *c, if (IS_ERR(ca)) return PTR_ERR(ca); - int ret = bch2_dev_set_state(c, ca, arg.new_state, arg.flags); + CLASS(printbuf, err)(); + int ret = bch2_dev_set_state(c, ca, arg.new_state, arg.flags, &err); bch_err_msg(ca, ret, "setting device state"); return ret; } diff --git a/fs/bcachefs/error.c b/fs/bcachefs/error.c index 32a286b3a74e..e33f3166c48a 100644 --- a/fs/bcachefs/error.c +++ b/fs/bcachefs/error.c @@ -141,14 +141,16 @@ void bch2_io_error_work(struct work_struct *work) if (ca->mi.state >= BCH_MEMBER_STATE_ro) return; - bool dev = !__bch2_dev_set_state(c, ca, BCH_MEMBER_STATE_ro, - BCH_FORCE_IF_DEGRADED); CLASS(printbuf, buf)(); __bch2_log_msg_start(ca->name, &buf); - prt_printf(&buf, "writes erroring for %u seconds, setting %s ro", - c->opts.write_error_timeout, - dev ? "device" : "filesystem"); + prt_printf(&buf, "writes erroring for %u seconds\n", + c->opts.write_error_timeout); + + bool dev = !__bch2_dev_set_state(c, ca, BCH_MEMBER_STATE_ro, + BCH_FORCE_IF_DEGRADED, &buf); + + prt_printf(&buf, "setting %s ro", dev ? "device" : "filesystem"); if (!dev) bch2_fs_emergency_read_only2(c, &buf); diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c index 921f9049912d..c3ef35dc01e2 100644 --- a/fs/bcachefs/opts.c +++ b/fs/bcachefs/opts.c @@ -525,7 +525,7 @@ int bch2_opt_hook_pre_set(struct bch_fs *c, struct bch_dev *ca, enum bch_opt_id switch (id) { case Opt_state: if (ca) - return bch2_dev_set_state(c, ca, v, BCH_FORCE_IF_DEGRADED); + return bch2_dev_set_state(c, ca, v, BCH_FORCE_IF_DEGRADED, NULL); break; case Opt_compression: diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c index 0784283ce78c..3ffd68d2608d 100644 --- a/fs/bcachefs/replicas.c +++ b/fs/bcachefs/replicas.c @@ -784,7 +784,7 @@ const struct bch_sb_field_ops bch_sb_field_ops_replicas_v0 = { /* Query replicas: */ bool bch2_have_enough_devs(struct bch_fs *c, struct bch_devs_mask devs, - unsigned flags, bool print) + unsigned flags, struct printbuf *err) { struct bch_replicas_entry_v1 *e; @@ -823,16 +823,14 @@ bool bch2_have_enough_devs(struct bch_fs *c, struct bch_devs_mask devs, : BCH_FORCE_IF_DATA_DEGRADED; if (dflags & ~flags) { - if (print) { - CLASS(printbuf, buf)(); - - bch2_replicas_entry_to_text(&buf, e); - bch_err(c, "insufficient devices online (%u) for replicas entry %s", - nr_online, buf.buf); + if (err) { + prt_printf(err, "insufficient devices online (%u) for replicas entry ", + nr_online); + bch2_replicas_entry_to_text(err, e); + prt_newline(err); } return false; } - } return true; diff --git a/fs/bcachefs/replicas.h b/fs/bcachefs/replicas.h index 5aba2c1ce133..15023a9b0b1e 100644 --- a/fs/bcachefs/replicas.h +++ b/fs/bcachefs/replicas.h @@ -44,7 +44,7 @@ static inline void bch2_replicas_entry_cached(struct bch_replicas_entry_v1 *e, } bool bch2_have_enough_devs(struct bch_fs *, struct bch_devs_mask, - unsigned, bool); + unsigned, struct printbuf *); unsigned bch2_sb_dev_has_data(struct bch_sb *, unsigned); unsigned bch2_dev_has_data(struct bch_fs *, struct bch_dev *); diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index 5897380c4c08..61eeac671283 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -1189,13 +1189,13 @@ int bch2_write_super(struct bch_fs *c) nr_wrote = dev_mask_nr(&sb_written); can_mount_with_written = - bch2_have_enough_devs(c, sb_written, degraded_flags, false); + bch2_have_enough_devs(c, sb_written, degraded_flags, NULL); for (unsigned i = 0; i < ARRAY_SIZE(sb_written.d); i++) sb_written.d[i] = ~sb_written.d[i]; can_mount_without_written = - bch2_have_enough_devs(c, sb_written, degraded_flags, false); + bch2_have_enough_devs(c, sb_written, degraded_flags, NULL); /* * If we would be able to mount _without_ the devices we successfully diff --git a/fs/bcachefs/super.c b/fs/bcachefs/super.c index ee3b30b1c2b5..4281a20f7856 100644 --- a/fs/bcachefs/super.c +++ b/fs/bcachefs/super.c @@ -1368,10 +1368,14 @@ static bool bch2_fs_may_start(struct bch_fs *c) return false; } break; - } + } } - return bch2_have_enough_devs(c, c->online_devs, flags, true); + CLASS(printbuf, err)(); + bool ret = bch2_have_enough_devs(c, c->online_devs, flags, &err); + if (!ret) + bch2_print_str(c, KERN_ERR, err.buf); + return ret; } int bch2_fs_start(struct bch_fs *c) @@ -1833,7 +1837,8 @@ static int bch2_dev_attach_bdev(struct bch_fs *c, struct bch_sb_handle *sb) * because we got an error or what have you? */ bool bch2_dev_state_allowed(struct bch_fs *c, struct bch_dev *ca, - enum bch_member_state new_state, int flags) + enum bch_member_state new_state, int flags, + struct printbuf *err) { struct bch_devs_mask new_online_devs; int nr_rw = 0, required; @@ -1870,7 +1875,7 @@ bool bch2_dev_state_allowed(struct bch_fs *c, struct bch_dev *ca, new_online_devs = c->online_devs; __clear_bit(ca->dev_idx, new_online_devs.d); - return bch2_have_enough_devs(c, new_online_devs, flags, false); + return bch2_have_enough_devs(c, new_online_devs, flags, err); default: BUG(); } @@ -1904,14 +1909,15 @@ static void __bch2_dev_read_write(struct bch_fs *c, struct bch_dev *ca) } int __bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca, - enum bch_member_state new_state, int flags) + enum bch_member_state new_state, int flags, + struct printbuf *err) { int ret = 0; if (ca->mi.state == new_state) return 0; - if (!bch2_dev_state_allowed(c, ca, new_state, flags)) + if (!bch2_dev_state_allowed(c, ca, new_state, flags, err)) return bch_err_throw(c, device_state_not_allowed); if (new_state != BCH_MEMBER_STATE_rw) @@ -1934,10 +1940,11 @@ int __bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca, } int bch2_dev_set_state(struct bch_fs *c, struct bch_dev *ca, - enum bch_member_state new_state, int flags) + enum bch_member_state new_state, int flags, + struct printbuf *err) { guard(rwsem_write)(&c->state_lock); - return __bch2_dev_set_state(c, ca, new_state, flags); + return __bch2_dev_set_state(c, ca, new_state, flags, err); } /* Device add/removal: */ @@ -1957,7 +1964,7 @@ int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags) */ bch2_dev_put(ca); - if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, flags)) { + if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, flags, NULL)) { bch_err(ca, "Cannot remove without losing data"); ret = bch_err_throw(c, device_state_not_allowed); goto err; @@ -2278,7 +2285,7 @@ int bch2_dev_offline(struct bch_fs *c, struct bch_dev *ca, int flags) return 0; } - if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, flags)) { + if (!bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, flags, NULL)) { bch_err(ca, "Cannot offline required disk"); return bch_err_throw(c, device_state_not_allowed); } @@ -2455,10 +2462,14 @@ static void bch2_fs_bdev_mark_dead(struct block_device *bdev, bool surprise) struct bch_dev *ca = bdev_to_bch_dev(c, bdev); if (ca) { + CLASS(printbuf, buf)(); + __bch2_log_msg_start(ca->name, &buf); + prt_printf(&buf, "offline from block layer\n"); + bool dev = bch2_dev_state_allowed(c, ca, BCH_MEMBER_STATE_failed, - BCH_FORCE_IF_DEGRADED); - + BCH_FORCE_IF_DEGRADED, + &buf); if (!dev && sb) { if (!surprise) sync_filesystem(sb); @@ -2466,11 +2477,6 @@ static void bch2_fs_bdev_mark_dead(struct block_device *bdev, bool surprise) evict_inodes(sb); } - CLASS(printbuf, buf)(); - __bch2_log_msg_start(ca->name, &buf); - - prt_printf(&buf, "offline from block layer"); - if (dev) { __bch2_dev_offline(c, ca); } else { diff --git a/fs/bcachefs/super.h b/fs/bcachefs/super.h index e90bab9afe78..de2c4430b8f7 100644 --- a/fs/bcachefs/super.h +++ b/fs/bcachefs/super.h @@ -17,11 +17,14 @@ struct bch_fs *bch2_dev_to_fs(dev_t); struct bch_fs *bch2_uuid_to_fs(__uuid_t); bool bch2_dev_state_allowed(struct bch_fs *, struct bch_dev *, - enum bch_member_state, int); + enum bch_member_state, int, + struct printbuf *); int __bch2_dev_set_state(struct bch_fs *, struct bch_dev *, - enum bch_member_state, int); + enum bch_member_state, int, + struct printbuf *); int bch2_dev_set_state(struct bch_fs *, struct bch_dev *, - enum bch_member_state, int); + enum bch_member_state, int, + struct printbuf *); int bch2_dev_fail(struct bch_dev *, int); int bch2_dev_remove(struct bch_fs *, struct bch_dev *, int); |