summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-03-13 00:55:52 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2025-03-24 09:50:35 -0400
commit8d7b7ac367cd0e7f0e496ba6526799994b3c1237 (patch)
treedf23b493f75aac2f26544537f9a6ed3687b7dd26
parent7b84d934a16274eaedfb38cb94b909426048c48e (diff)
bcachefs: Device state is now a runtime option
Other options can normally be set at runtime via sysfs, no reason for this one not to be as well - it just doesn't support the degraded flags argument this way, that requires the ioctl. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/opts.c7
-rw-r--r--fs/bcachefs/opts.h2
-rw-r--r--fs/bcachefs/sysfs.c3
3 files changed, 11 insertions, 1 deletions
diff --git a/fs/bcachefs/opts.c b/fs/bcachefs/opts.c
index de24af773224..d0ce96529dd4 100644
--- a/fs/bcachefs/opts.c
+++ b/fs/bcachefs/opts.c
@@ -482,9 +482,16 @@ void bch2_opts_to_text(struct printbuf *out,
int bch2_opt_check_may_set(struct bch_fs *c, struct bch_dev *ca, int id, u64 v)
{
+ lockdep_assert_held(&c->state_lock);
+
int ret = 0;
switch (id) {
+ case Opt_state:
+ if (ca)
+ return __bch2_dev_set_state(c, ca, v, BCH_FORCE_IF_DEGRADED);
+ break;
+
case Opt_compression:
case Opt_background_compression:
ret = bch2_check_set_has_compressed_data(c, v);
diff --git a/fs/bcachefs/opts.h b/fs/bcachefs/opts.h
index 19fcc0e51c0b..0bf39e4b1c8e 100644
--- a/fs/bcachefs/opts.h
+++ b/fs/bcachefs/opts.h
@@ -495,7 +495,7 @@ enum fsck_err_opts {
NULL, "Skip submit_bio() for data reads and writes, " \
"for performance testing purposes") \
x(state, u64, \
- OPT_DEVICE, \
+ OPT_DEVICE|OPT_RUNTIME, \
OPT_STR(bch2_member_states), \
BCH_MEMBER_STATE, BCH_MEMBER_STATE_rw, \
"state", "rw,ro,failed,spare") \
diff --git a/fs/bcachefs/sysfs.c b/fs/bcachefs/sysfs.c
index b01b2ae87051..e8a795578186 100644
--- a/fs/bcachefs/sysfs.c
+++ b/fs/bcachefs/sysfs.c
@@ -631,6 +631,8 @@ static ssize_t sysfs_opt_store(struct bch_fs *c,
if (unlikely(!bch2_write_ref_tryget(c, BCH_WRITE_REF_sysfs)))
return -EROFS;
+ down_write(&c->state_lock);
+
char *tmp = kstrdup(buf, GFP_KERNEL);
if (!tmp) {
ret = -ENOMEM;
@@ -664,6 +666,7 @@ static ssize_t sysfs_opt_store(struct bch_fs *c,
ret = size;
err:
+ up_write(&c->state_lock);
bch2_write_ref_put(c, BCH_WRITE_REF_sysfs);
return ret;
}