diff options
author | Slava Pestov <sp@daterainc.com> | 2014-07-11 15:17:41 -0400 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2014-08-04 18:23:04 -0400 |
commit | bf0c55c986540483c34ca640f2eef4c3314388b1 (patch) | |
tree | 42507e423dd6f73e207329e1264b8101b8057880 /drivers/md | |
parent | d83353b319d47ef8cce82467da6a25c2d558253f (diff) |
bcache: fix crash with incomplete cache set
Change-Id: I6abde52afe917633480caaf4e2518f42a816d886
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/bcache/bcache.h | 4 | ||||
-rw-r--r-- | drivers/md/bcache/super.c | 4 |
2 files changed, 8 insertions, 0 deletions
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index d2ebcf323094..04f7bc28ef83 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h | |||
@@ -477,9 +477,13 @@ struct gc_stat { | |||
477 | * CACHE_SET_STOPPING always gets set first when we're closing down a cache set; | 477 | * CACHE_SET_STOPPING always gets set first when we're closing down a cache set; |
478 | * we'll continue to run normally for awhile with CACHE_SET_STOPPING set (i.e. | 478 | * we'll continue to run normally for awhile with CACHE_SET_STOPPING set (i.e. |
479 | * flushing dirty data). | 479 | * flushing dirty data). |
480 | * | ||
481 | * CACHE_SET_RUNNING means all cache devices have been registered and journal | ||
482 | * replay is complete. | ||
480 | */ | 483 | */ |
481 | #define CACHE_SET_UNREGISTERING 0 | 484 | #define CACHE_SET_UNREGISTERING 0 |
482 | #define CACHE_SET_STOPPING 1 | 485 | #define CACHE_SET_STOPPING 1 |
486 | #define CACHE_SET_RUNNING 2 | ||
483 | 487 | ||
484 | struct cache_set { | 488 | struct cache_set { |
485 | struct closure cl; | 489 | struct closure cl; |
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 29dd1e8ae19f..72fbaf79b0c8 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c | |||
@@ -1284,6 +1284,9 @@ int bch_flash_dev_create(struct cache_set *c, uint64_t size) | |||
1284 | if (test_bit(CACHE_SET_STOPPING, &c->flags)) | 1284 | if (test_bit(CACHE_SET_STOPPING, &c->flags)) |
1285 | return -EINTR; | 1285 | return -EINTR; |
1286 | 1286 | ||
1287 | if (!test_bit(CACHE_SET_RUNNING, &c->flags)) | ||
1288 | return -EPERM; | ||
1289 | |||
1287 | u = uuid_find_empty(c); | 1290 | u = uuid_find_empty(c); |
1288 | if (!u) { | 1291 | if (!u) { |
1289 | pr_err("Can't create volume, no room for UUID"); | 1292 | pr_err("Can't create volume, no room for UUID"); |
@@ -1706,6 +1709,7 @@ static void run_cache_set(struct cache_set *c) | |||
1706 | 1709 | ||
1707 | flash_devs_run(c); | 1710 | flash_devs_run(c); |
1708 | 1711 | ||
1712 | set_bit(CACHE_SET_RUNNING, &c->flags); | ||
1709 | return; | 1713 | return; |
1710 | err: | 1714 | err: |
1711 | closure_sync(&cl); | 1715 | closure_sync(&cl); |