diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-07-11 00:25:02 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-28 19:30:10 -0400 |
commit | fe1b710530e60c8fbb07a73ad27e9f65305ce06a (patch) | |
tree | 916fed1e78bcabcb945a0e960508a97d6e7227b4 | |
parent | 63a53870bb23c2d991f378ae9137d775978d5ae9 (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.h | 1 | ||||
-rw-r--r-- | drivers/md/bcache/super.c | 11 |
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 | ||