summaryrefslogtreecommitdiff
path: root/drivers/md/bcache/super.c
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-07-10 21:03:25 -0700
committerKent Overstreet <kmo@daterainc.com>2013-07-12 00:22:47 -0700
commit5caa52afc5abd1396e4af720469abb5843a71eb8 (patch)
treefbe7658aab74ad20a536f9c64b031bc75d75683c /drivers/md/bcache/super.c
parentc9502ea4424b31728703d113fc6b30bfead14633 (diff)
downloadlwn-5caa52afc5abd1396e4af720469abb5843a71eb8.tar.gz
lwn-5caa52afc5abd1396e4af720469abb5843a71eb8.zip
bcache: Shutdown fix
Stopping a cache set is supposed to make it stop attached backing devices, but somewhere along the way that code got lost. Fixing this mainly has the effect of fixing our reboot notifier. Signed-off-by: Kent Overstreet <kmo@daterainc.com> Cc: linux-stable <stable@vger.kernel.org> # >= v3.10
Diffstat (limited to 'drivers/md/bcache/super.c')
-rw-r--r--drivers/md/bcache/super.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 7a1dcdb2536e..f6a62174e8f6 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -1354,18 +1354,22 @@ static void cache_set_flush(struct closure *cl)
static void __cache_set_unregister(struct closure *cl)
{
struct cache_set *c = container_of(cl, struct cache_set, caching);
- struct cached_dev *dc, *t;
+ struct cached_dev *dc;
size_t i;
mutex_lock(&bch_register_lock);
- if (test_bit(CACHE_SET_UNREGISTERING, &c->flags))
- list_for_each_entry_safe(dc, t, &c->cached_devs, list)
- bch_cached_dev_detach(dc);
-
for (i = 0; i < c->nr_uuids; i++)
- if (c->devices[i] && UUID_FLASH_ONLY(&c->uuids[i]))
- bcache_device_stop(c->devices[i]);
+ if (c->devices[i]) {
+ if (!UUID_FLASH_ONLY(&c->uuids[i]) &&
+ test_bit(CACHE_SET_UNREGISTERING, &c->flags)) {
+ dc = container_of(c->devices[i],
+ struct cached_dev, disk);
+ bch_cached_dev_detach(dc);
+ } else {
+ bcache_device_stop(c->devices[i]);
+ }
+ }
mutex_unlock(&bch_register_lock);