From: Slava Pestov Date: Fri, 11 Jul 2014 19:17:41 +0000 (-0700) Subject: bcache: fix crash with incomplete cache set X-Git-Tag: v3.12.32~116 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=57c68d49b58d2c6c942dbc89d2c4fec2041e0e9e;p=thirdparty%2Fkernel%2Fstable.git bcache: fix crash with incomplete cache set commit bf0c55c986540483c34ca640f2eef4c3314388b1 upstream. Change-Id: I6abde52afe917633480caaf4e2518f42a816d886 Signed-off-by: Jiri Slaby --- diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index 0f12382aa35d6..7552207a479bc 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h @@ -663,9 +663,13 @@ struct gc_stat { * CACHE_SET_STOPPING always gets set first when we're closing down a cache set; * we'll continue to run normally for awhile with CACHE_SET_STOPPING set (i.e. * flushing dirty data). + * + * CACHE_SET_RUNNING means all cache devices have been registered and journal + * replay is complete. */ #define CACHE_SET_UNREGISTERING 0 #define CACHE_SET_STOPPING 1 +#define CACHE_SET_RUNNING 2 struct cache_set { struct closure cl; diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 3a2ccf9b624be..f5004c5c4b962 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1235,6 +1235,9 @@ int bch_flash_dev_create(struct cache_set *c, uint64_t size) if (test_bit(CACHE_SET_STOPPING, &c->flags)) return -EINTR; + if (!test_bit(CACHE_SET_RUNNING, &c->flags)) + return -EPERM; + u = uuid_find_empty(c); if (!u) { pr_err("Can't create volume, no room for UUID"); @@ -1640,6 +1643,7 @@ static void run_cache_set(struct cache_set *c) flash_devs_run(c); + set_bit(CACHE_SET_RUNNING, &c->flags); return; err_unlock_gc: closure_set_stopped(&c->gc.cl);