bcache: add comments for kobj release callback routine
[linux-block.git] / drivers / md / bcache / super.c
index a697a3a923cd24638dd538ca2c3a110e1ff98ec1..f8d80adcafeca9e9a5bf5f140d37969112d8245a 100644 (file)
@@ -906,21 +906,18 @@ static int cached_dev_status_update(void *arg)
 void bch_cached_dev_run(struct cached_dev *dc)
 {
        struct bcache_device *d = &dc->disk;
-       char buf[SB_LABEL_SIZE + 1];
+       char *buf = kmemdup_nul(dc->sb.label, SB_LABEL_SIZE, GFP_KERNEL);
        char *env[] = {
                "DRIVER=bcache",
                kasprintf(GFP_KERNEL, "CACHED_UUID=%pU", dc->sb.uuid),
-               NULL,
+               kasprintf(GFP_KERNEL, "CACHED_LABEL=%s", buf ? : ""),
                NULL,
        };
 
-       memcpy(buf, dc->sb.label, SB_LABEL_SIZE);
-       buf[SB_LABEL_SIZE] = '\0';
-       env[2] = kasprintf(GFP_KERNEL, "CACHED_LABEL=%s", buf);
-
        if (atomic_xchg(&dc->running, 1)) {
                kfree(env[1]);
                kfree(env[2]);
+               kfree(buf);
                return;
        }
 
@@ -944,6 +941,7 @@ void bch_cached_dev_run(struct cached_dev *dc)
        kobject_uevent_env(&disk_to_dev(d->disk)->kobj, KOBJ_CHANGE, env);
        kfree(env[1]);
        kfree(env[2]);
+       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"))
@@ -1174,6 +1172,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
        return 0;
 }
 
+/* when dc->disk.kobj released */
 void bch_cached_dev_release(struct kobject *kobj)
 {
        struct cached_dev *dc = container_of(kobj, struct cached_dev,
@@ -1326,6 +1325,7 @@ err:
 
 /* Flash only volumes */
 
+/* When d->kobj released */
 void bch_flash_dev_release(struct kobject *kobj)
 {
        struct bcache_device *d = container_of(kobj, struct bcache_device,
@@ -1496,6 +1496,7 @@ bool bch_cache_set_error(struct cache_set *c, const char *fmt, ...)
        return true;
 }
 
+/* When c->kobj released */
 void bch_cache_set_release(struct kobject *kobj)
 {
        struct cache_set *c = container_of(kobj, struct cache_set, kobj);
@@ -1516,6 +1517,7 @@ static void cache_set_free(struct closure *cl)
        bch_btree_cache_free(c);
        bch_journal_free(c);
 
+       mutex_lock(&bch_register_lock);
        for_each_cache(ca, c, i)
                if (ca) {
                        ca->set = NULL;
@@ -1534,7 +1536,6 @@ static void cache_set_free(struct closure *cl)
        mempool_exit(&c->search);
        kfree(c->devices);
 
-       mutex_lock(&bch_register_lock);
        list_del(&c->list);
        mutex_unlock(&bch_register_lock);
 
@@ -1775,7 +1776,7 @@ err:
        return NULL;
 }
 
-static void run_cache_set(struct cache_set *c)
+static int run_cache_set(struct cache_set *c)
 {
        const char *err = "cannot allocate memory";
        struct cached_dev *dc, *t;
@@ -1869,7 +1870,9 @@ static void run_cache_set(struct cache_set *c)
                if (j->version < BCACHE_JSET_VERSION_UUID)
                        __uuid_write(c);
 
-               bch_journal_replay(c, &journal);
+               err = "bcache: replay journal failed";
+               if (bch_journal_replay(c, &journal))
+                       goto err;
        } else {
                pr_notice("invalidating existing data");
 
@@ -1937,11 +1940,13 @@ static void run_cache_set(struct cache_set *c)
        flash_devs_run(c);
 
        set_bit(CACHE_SET_RUNNING, &c->flags);
-       return;
+       return 0;
 err:
        closure_sync(&cl);
        /* XXX: test this, it's broken */
        bch_cache_set_error(c, "%s", err);
+
+       return -EIO;
 }
 
 static bool can_attach_cache(struct cache *ca, struct cache_set *c)
@@ -2005,8 +2010,11 @@ found:
        ca->set->cache[ca->sb.nr_this_dev] = ca;
        c->cache_by_alloc[c->caches_loaded++] = ca;
 
-       if (c->caches_loaded == c->sb.nr_in_set)
-               run_cache_set(c);
+       if (c->caches_loaded == c->sb.nr_in_set) {
+               err = "failed to run cache set";
+               if (run_cache_set(c) < 0)
+                       goto err;
+       }
 
        return NULL;
 err:
@@ -2016,6 +2024,7 @@ err:
 
 /* Cache device */
 
+/* When ca->kobj released */
 void bch_cache_release(struct kobject *kobj)
 {
        struct cache *ca = container_of(kobj, struct cache, kobj);