aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-07-11 00:25:02 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-07-28 19:30:10 -0400
commitfe1b710530e60c8fbb07a73ad27e9f65305ce06a (patch)
tree916fed1e78bcabcb945a0e960508a97d6e7227b4
parent63a53870bb23c2d991f378ae9137d775978d5ae9 (diff)
bcache: Fix a sysfs splat on shutdown
commit c9502ea4424b31728703d113fc6b30bfead14633 upstream. If we stopped a bcache device when we were already detaching (or something like that), bcache_device_unlink() would try to remove a symlink from sysfs that was already gone because the bcache dev kobject had already been removed from sysfs. So keep track of whether we've removed stuff from sysfs. Signed-off-by: Kent Overstreet <kmo@daterainc.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/md/bcache/bcache.h1
-rw-r--r--drivers/md/bcache/super.c11
2 files changed, 11 insertions, 1 deletions
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index d3e15b42a4ab..c42b14b2304c 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -437,6 +437,7 @@ struct bcache_device {
437 437
438 /* If nonzero, we're detaching/unregistering from cache set */ 438 /* If nonzero, we're detaching/unregistering from cache set */
439 atomic_t detaching; 439 atomic_t detaching;
440 int flush_done;
440 441
441 atomic_long_t sectors_dirty; 442 atomic_long_t sectors_dirty;
442 unsigned long sectors_dirty_gc; 443 unsigned long sectors_dirty_gc;
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 88113fe57fed..b4713cea1913 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -704,7 +704,8 @@ static void bcache_device_detach(struct bcache_device *d)
704 atomic_set(&d->detaching, 0); 704 atomic_set(&d->detaching, 0);
705 } 705 }
706 706
707 bcache_device_unlink(d); 707 if (!d->flush_done)
708 bcache_device_unlink(d);
708 709
709 d->c->devices[d->id] = NULL; 710 d->c->devices[d->id] = NULL;
710 closure_put(&d->c->caching); 711 closure_put(&d->c->caching);
@@ -1016,6 +1017,14 @@ static void cached_dev_flush(struct closure *cl)
1016 struct cached_dev *dc = container_of(cl, struct cached_dev, disk.cl); 1017 struct cached_dev *dc = container_of(cl, struct cached_dev, disk.cl);
1017 struct bcache_device *d = &dc->disk; 1018 struct bcache_device *d = &dc->disk;
1018 1019
1020 mutex_lock(&bch_register_lock);
1021 d->flush_done = 1;
1022
1023 if (d->c)
1024 bcache_device_unlink(d);
1025
1026 mutex_unlock(&bch_register_lock);
1027
1019 bch_cache_accounting_destroy(&dc->accounting); 1028 bch_cache_accounting_destroy(&dc->accounting);
1020 kobject_del(&d->kobj); 1029 kobject_del(&d->kobj);
1021 1030