"echo 1 > writeback_running" marks writeback_running even if no writeback kthread created as "d_strtoul(writeback_running)" will simply set dc-> writeback_running without checking the existence of dc->writeback_thread. Add check for setting writeback_running via sysfs: * if no writeback kthread alive, reject setting to 1 * if writeback kthread alive, reject setting to 0 * consider none-0 values as true Signed-off-by: Shenghui Wang <shhuiw@xxxxxxxxxxx> --- drivers/md/bcache/sysfs.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 26f035a0c5b9..8e41f46c3f42 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -384,8 +384,30 @@ STORE(bch_cached_dev) mutex_lock(&bch_register_lock); size = __cached_dev_store(kobj, attr, buf, size); - if (attr == &sysfs_writeback_running) - bch_writeback_queue(dc); + if (attr == &sysfs_writeback_running) { + /* if set wrong value via sysfs, reset to previous value */ + if (!IS_ERR_OR_NULL(dc->writeback_thread)) { + if (!dc->writeback_running) + pr_err("%s: cannot stop running writeback thread", + dc->backing_dev_name); + else + /* wake up if alive already. */ + bch_writeback_queue(dc); + + /* all none-0 values are considered as true */ + dc->writeback_running = true; + } else { + /* + * reject setting it to 1 via sysfs if writeback + * kthread is not created yet. + */ + if (dc->writeback_running) { + dc->writeback_running = false; + pr_err("%s: writeback thread not created yet", + dc->backing_dev_name); + } + } + } if (attr == &sysfs_writeback_percent) if (!test_and_set_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags)) -- 2.18.0