diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2025-08-17 20:22:13 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2025-08-18 00:17:11 -0400 |
commit | 905297ad0fab4b2a2b48acfde9392f1abf4ce8fa (patch) | |
tree | 3432f3b961b4947ea6b571fda650c33573f6b8f8 /libbcachefs/chardev.c | |
parent | c1c4d03aa6923dadc7cc31fcff37a6243b51d0b4 (diff) |
Update bcachefs sources to d863521e4078 bcachefs: BCH_IOCTL_DISK_SET_STATE_v2
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'libbcachefs/chardev.c')
-rw-r--r-- | libbcachefs/chardev.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/libbcachefs/chardev.c b/libbcachefs/chardev.c index 467fc45e..3b8c1409 100644 --- a/libbcachefs/chardev.c +++ b/libbcachefs/chardev.c @@ -287,11 +287,44 @@ 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; } +static long bch2_ioctl_disk_set_state_v2(struct bch_fs *c, + struct bch_ioctl_disk_set_state_v2 arg) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if ((arg.flags & ~(BCH_FORCE_IF_DATA_LOST| + BCH_FORCE_IF_METADATA_LOST| + BCH_FORCE_IF_DEGRADED| + BCH_BY_INDEX)) || + arg.pad[0] || arg.pad[1] || arg.pad[2] || + arg.new_state >= BCH_MEMBER_STATE_NR) + return -EINVAL; + + CLASS(bch2_device_lookup, ca)(c, arg.dev, arg.flags); + if (IS_ERR(ca)) + return PTR_ERR(ca); + + CLASS(printbuf, err)(); + int ret = bch2_dev_set_state(c, ca, arg.new_state, arg.flags, &err); + if (ret) { + if (err.pos > arg.err.msg_len) + return -ERANGE; + + prt_printf(&err, "\nerror=%s", bch2_err_str(ret)); + ret = copy_to_user_errcode((void __user *)(ulong)arg.err.msg_ptr, + err.buf, + err.pos) ?: ret; + } + return ret; +} + struct bch_data_ctx { struct thread_with_file thr; @@ -692,6 +725,8 @@ long bch2_fs_ioctl(struct bch_fs *c, unsigned cmd, void __user *arg) BCH_IOCTL(disk_offline, struct bch_ioctl_disk); case BCH_IOCTL_DISK_SET_STATE: BCH_IOCTL(disk_set_state, struct bch_ioctl_disk_set_state); + case BCH_IOCTL_DISK_SET_STATE_v2: + BCH_IOCTL(disk_set_state_v2, struct bch_ioctl_disk_set_state_v2); case BCH_IOCTL_DATA: BCH_IOCTL(data, struct bch_ioctl_data); case BCH_IOCTL_DISK_RESIZE: |