bcache: add return value check to bch_cached_dev_run()
authorColy Li <colyli@suse.de>
Fri, 28 Jun 2019 11:59:33 +0000 (19:59 +0800)
committerJens Axboe <axboe@kernel.dk>
Fri, 28 Jun 2019 13:39:14 +0000 (07:39 -0600)
This patch adds return value check to bch_cached_dev_run(), now if there
is error happens inside bch_cached_dev_run(), it can be catched.

Signed-off-by: Coly Li <colyli@suse.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/md/bcache/bcache.h
drivers/md/bcache/super.c
drivers/md/bcache/sysfs.c

index fdf75352e16a3aadf406c35484891c5aabcb431d..73a97586a2ef8880e90c40c02de5f186d65c978d 100644 (file)
@@ -1006,7 +1006,7 @@ int bch_flash_dev_create(struct cache_set *c, uint64_t size);
 int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
                          uint8_t *set_uuid);
 void bch_cached_dev_detach(struct cached_dev *dc);
-void bch_cached_dev_run(struct cached_dev *dc);
+int bch_cached_dev_run(struct cached_dev *dc);
 void bcache_device_stop(struct bcache_device *d);
 
 void bch_cache_set_unregister(struct cache_set *c);
index 73466bda12a7b9e7471cf761f15691d7676d02b5..0abee44092bfaa7164f235ba0b5cc66bfb38cae4 100644 (file)
@@ -910,7 +910,7 @@ static int cached_dev_status_update(void *arg)
 }
 
 
-void bch_cached_dev_run(struct cached_dev *dc)
+int bch_cached_dev_run(struct cached_dev *dc)
 {
        struct bcache_device *d = &dc->disk;
        char *buf = kmemdup_nul(dc->sb.label, SB_LABEL_SIZE, GFP_KERNEL);
@@ -921,11 +921,14 @@ void bch_cached_dev_run(struct cached_dev *dc)
                NULL,
        };
 
+       if (dc->io_disable)
+               return -EIO;
+
        if (atomic_xchg(&dc->running, 1)) {
                kfree(env[1]);
                kfree(env[2]);
                kfree(buf);
-               return;
+               return -EBUSY;
        }
 
        if (!d->c &&
@@ -951,8 +954,11 @@ void bch_cached_dev_run(struct cached_dev *dc)
        kfree(buf);
 
        if (sysfs_create_link(&d->kobj, &disk_to_dev(d->disk)->kobj, "dev") ||
-           sysfs_create_link(&disk_to_dev(d->disk)->kobj, &d->kobj, "bcache"))
+           sysfs_create_link(&disk_to_dev(d->disk)->kobj,
+                             &d->kobj, "bcache")) {
                pr_debug("error creating sysfs link");
+               return -ENOMEM;
+       }
 
        dc->status_update_thread = kthread_run(cached_dev_status_update,
                                               dc, "bcache_status_update");
@@ -961,6 +967,8 @@ void bch_cached_dev_run(struct cached_dev *dc)
                        "continue to run without monitoring backing "
                        "device status");
        }
+
+       return 0;
 }
 
 /*
@@ -1056,6 +1064,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
        uint32_t rtime = cpu_to_le32((u32)ktime_get_real_seconds());
        struct uuid_entry *u;
        struct cached_dev *exist_dc, *t;
+       int ret = 0;
 
        if ((set_uuid && memcmp(set_uuid, c->sb.set_uuid, 16)) ||
            (!set_uuid && memcmp(dc->sb.set_uuid, c->sb.set_uuid, 16)))
@@ -1165,7 +1174,12 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
 
        bch_sectors_dirty_init(&dc->disk);
 
-       bch_cached_dev_run(dc);
+       ret = bch_cached_dev_run(dc);
+       if (ret && (ret != -EBUSY)) {
+               up_write(&dc->writeback_lock);
+               return ret;
+       }
+
        bcache_device_link(&dc->disk, c, "bdev");
        atomic_inc(&c->attached_dev_nr);
 
@@ -1292,6 +1306,7 @@ static int register_bdev(struct cache_sb *sb, struct page *sb_page,
 {
        const char *err = "cannot allocate memory";
        struct cache_set *c;
+       int ret = -ENOMEM;
 
        bdevname(bdev, dc->backing_dev_name);
        memcpy(&dc->sb, sb, sizeof(struct cache_sb));
@@ -1321,14 +1336,18 @@ static int register_bdev(struct cache_sb *sb, struct page *sb_page,
                bch_cached_dev_attach(dc, c, NULL);
 
        if (BDEV_STATE(&dc->sb) == BDEV_STATE_NONE ||
-           BDEV_STATE(&dc->sb) == BDEV_STATE_STALE)
-               bch_cached_dev_run(dc);
+           BDEV_STATE(&dc->sb) == BDEV_STATE_STALE) {
+               err = "failed to run cached device";
+               ret = bch_cached_dev_run(dc);
+               if (ret)
+                       goto err;
+       }
 
        return 0;
 err:
        pr_notice("error %s: %s", dc->backing_dev_name, err);
        bcache_device_stop(&dc->disk);
-       return -EIO;
+       return ret;
 }
 
 /* Flash only volumes */
index 760cf8951338779cd67a5e1227186944367e7fdb..eb678e43ac00645c5d4330b51694fede143acf7e 100644 (file)
@@ -325,8 +325,11 @@ STORE(__cached_dev)
                bch_cache_accounting_clear(&dc->accounting);
 
        if (attr == &sysfs_running &&
-           strtoul_or_return(buf))
-               bch_cached_dev_run(dc);
+           strtoul_or_return(buf)) {
+               v = bch_cached_dev_run(dc);
+               if (v)
+                       return v;
+       }
 
        if (attr == &sysfs_cache_mode) {
                v = sysfs_match_string(bch_cache_modes, buf);