bcache: cannot set writeback_running via sysfs if no writeback kthread created
authorShenghui Wang <shhuiw@foxmail.com>
Thu, 13 Dec 2018 14:53:51 +0000 (22:53 +0800)
committerJens Axboe <axboe@kernel.dk>
Thu, 13 Dec 2018 15:15:54 +0000 (08:15 -0700)
"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 available, reject setting to 1.

v2 -> v3:
  * Make message on wrong assignment more clear.
  * Print name of bcache device instead of name of backing device.

Signed-off-by: Shenghui Wang <shhuiw@foxmail.com>
Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/md/bcache/sysfs.c

index d2e5c9892d4d79afe1bee0d2e23fbcdf28b92e44..9d5fe12f0c9cfb0e624b5acde31eb161ab291c30 100644 (file)
@@ -384,8 +384,25 @@ 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) {
+               /* dc->writeback_running changed in __cached_dev_store() */
+               if (IS_ERR_OR_NULL(dc->writeback_thread)) {
+                       /*
+                        * 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: failed to run non-existent writeback thread",
+                                               dc->disk.disk->disk_name);
+                       }
+               } else
+                       /*
+                        * writeback kthread will check if dc->writeback_running
+                        * is true or false.
+                        */
+                       bch_writeback_queue(dc);
+       }
 
        if (attr == &sysfs_writeback_percent)
                if (!test_and_set_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags))