diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-08-21 20:49:09 -0400 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2013-11-11 00:56:41 -0500 |
commit | c4d951ddb66fe1d087447b0ba65c4fa4446f1083 (patch) | |
tree | 80564725ffa4cfa0d1a02b0a80f419edcd424548 | |
parent | 48a915a87f0bd98c3d68d029acf223a2e5116f07 (diff) |
bcache: Fix sysfs splat on shutdown with flash only devs
Whoops.
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
-rw-r--r-- | drivers/md/bcache/bcache.h | 10 | ||||
-rw-r--r-- | drivers/md/bcache/request.c | 2 | ||||
-rw-r--r-- | drivers/md/bcache/super.c | 41 | ||||
-rw-r--r-- | drivers/md/bcache/sysfs.c | 2 | ||||
-rw-r--r-- | drivers/md/bcache/writeback.c | 6 | ||||
-rw-r--r-- | drivers/md/bcache/writeback.h | 2 |
6 files changed, 30 insertions, 33 deletions
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h index ab0b2150fed6..97ef126b68bb 100644 --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h | |||
@@ -266,12 +266,10 @@ struct bcache_device { | |||
266 | 266 | ||
267 | struct gendisk *disk; | 267 | struct gendisk *disk; |
268 | 268 | ||
269 | /* If nonzero, we're closing */ | 269 | unsigned long flags; |
270 | atomic_t closing; | 270 | #define BCACHE_DEV_CLOSING 0 |
271 | 271 | #define BCACHE_DEV_DETACHING 1 | |
272 | /* If nonzero, we're detaching/unregistering from cache set */ | 272 | #define BCACHE_DEV_UNLINK_DONE 2 |
273 | atomic_t detaching; | ||
274 | int flush_done; | ||
275 | 273 | ||
276 | unsigned nr_stripes; | 274 | unsigned nr_stripes; |
277 | unsigned stripe_size; | 275 | unsigned stripe_size; |
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c index f645da61189a..9f5a1386f77a 100644 --- a/drivers/md/bcache/request.c +++ b/drivers/md/bcache/request.c | |||
@@ -512,7 +512,7 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio) | |||
512 | struct task_struct *task = current; | 512 | struct task_struct *task = current; |
513 | struct io *i; | 513 | struct io *i; |
514 | 514 | ||
515 | if (atomic_read(&dc->disk.detaching) || | 515 | if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) || |
516 | c->gc_stats.in_use > CUTOFF_CACHE_ADD || | 516 | c->gc_stats.in_use > CUTOFF_CACHE_ADD || |
517 | (bio->bi_rw & REQ_DISCARD)) | 517 | (bio->bi_rw & REQ_DISCARD)) |
518 | goto skip; | 518 | goto skip; |
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 43fcfe38be11..fa1d53087f88 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c | |||
@@ -621,7 +621,7 @@ static void prio_read(struct cache *ca, uint64_t bucket) | |||
621 | static int open_dev(struct block_device *b, fmode_t mode) | 621 | static int open_dev(struct block_device *b, fmode_t mode) |
622 | { | 622 | { |
623 | struct bcache_device *d = b->bd_disk->private_data; | 623 | struct bcache_device *d = b->bd_disk->private_data; |
624 | if (atomic_read(&d->closing)) | 624 | if (test_bit(BCACHE_DEV_CLOSING, &d->flags)) |
625 | return -ENXIO; | 625 | return -ENXIO; |
626 | 626 | ||
627 | closure_get(&d->cl); | 627 | closure_get(&d->cl); |
@@ -650,20 +650,24 @@ static const struct block_device_operations bcache_ops = { | |||
650 | 650 | ||
651 | void bcache_device_stop(struct bcache_device *d) | 651 | void bcache_device_stop(struct bcache_device *d) |
652 | { | 652 | { |
653 | if (!atomic_xchg(&d->closing, 1)) | 653 | if (!test_and_set_bit(BCACHE_DEV_CLOSING, &d->flags)) |
654 | closure_queue(&d->cl); | 654 | closure_queue(&d->cl); |
655 | } | 655 | } |
656 | 656 | ||
657 | static void bcache_device_unlink(struct bcache_device *d) | 657 | static void bcache_device_unlink(struct bcache_device *d) |
658 | { | 658 | { |
659 | unsigned i; | 659 | lockdep_assert_held(&bch_register_lock); |
660 | struct cache *ca; | ||
661 | 660 | ||
662 | sysfs_remove_link(&d->c->kobj, d->name); | 661 | if (d->c && !test_and_set_bit(BCACHE_DEV_UNLINK_DONE, &d->flags)) { |
663 | sysfs_remove_link(&d->kobj, "cache"); | 662 | unsigned i; |
663 | struct cache *ca; | ||
664 | 664 | ||
665 | for_each_cache(ca, d->c, i) | 665 | sysfs_remove_link(&d->c->kobj, d->name); |
666 | bd_unlink_disk_holder(ca->bdev, d->disk); | 666 | sysfs_remove_link(&d->kobj, "cache"); |
667 | |||
668 | for_each_cache(ca, d->c, i) | ||
669 | bd_unlink_disk_holder(ca->bdev, d->disk); | ||
670 | } | ||
667 | } | 671 | } |
668 | 672 | ||
669 | static void bcache_device_link(struct bcache_device *d, struct cache_set *c, | 673 | static void bcache_device_link(struct bcache_device *d, struct cache_set *c, |
@@ -687,19 +691,16 @@ static void bcache_device_detach(struct bcache_device *d) | |||
687 | { | 691 | { |
688 | lockdep_assert_held(&bch_register_lock); | 692 | lockdep_assert_held(&bch_register_lock); |
689 | 693 | ||
690 | if (atomic_read(&d->detaching)) { | 694 | if (test_bit(BCACHE_DEV_DETACHING, &d->flags)) { |
691 | struct uuid_entry *u = d->c->uuids + d->id; | 695 | struct uuid_entry *u = d->c->uuids + d->id; |
692 | 696 | ||
693 | SET_UUID_FLASH_ONLY(u, 0); | 697 | SET_UUID_FLASH_ONLY(u, 0); |
694 | memcpy(u->uuid, invalid_uuid, 16); | 698 | memcpy(u->uuid, invalid_uuid, 16); |
695 | u->invalidated = cpu_to_le32(get_seconds()); | 699 | u->invalidated = cpu_to_le32(get_seconds()); |
696 | bch_uuid_write(d->c); | 700 | bch_uuid_write(d->c); |
697 | |||
698 | atomic_set(&d->detaching, 0); | ||
699 | } | 701 | } |
700 | 702 | ||
701 | if (!d->flush_done) | 703 | bcache_device_unlink(d); |
702 | bcache_device_unlink(d); | ||
703 | 704 | ||
704 | d->c->devices[d->id] = NULL; | 705 | d->c->devices[d->id] = NULL; |
705 | closure_put(&d->c->caching); | 706 | closure_put(&d->c->caching); |
@@ -879,7 +880,7 @@ static void cached_dev_detach_finish(struct work_struct *w) | |||
879 | struct closure cl; | 880 | struct closure cl; |
880 | closure_init_stack(&cl); | 881 | closure_init_stack(&cl); |
881 | 882 | ||
882 | BUG_ON(!atomic_read(&dc->disk.detaching)); | 883 | BUG_ON(!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags)); |
883 | BUG_ON(atomic_read(&dc->count)); | 884 | BUG_ON(atomic_read(&dc->count)); |
884 | 885 | ||
885 | mutex_lock(&bch_register_lock); | 886 | mutex_lock(&bch_register_lock); |
@@ -893,6 +894,8 @@ static void cached_dev_detach_finish(struct work_struct *w) | |||
893 | bcache_device_detach(&dc->disk); | 894 | bcache_device_detach(&dc->disk); |
894 | list_move(&dc->list, &uncached_devices); | 895 | list_move(&dc->list, &uncached_devices); |
895 | 896 | ||
897 | clear_bit(BCACHE_DEV_DETACHING, &dc->disk.flags); | ||
898 | |||
896 | mutex_unlock(&bch_register_lock); | 899 | mutex_unlock(&bch_register_lock); |
897 | 900 | ||
898 | pr_info("Caching disabled for %s", bdevname(dc->bdev, buf)); | 901 | pr_info("Caching disabled for %s", bdevname(dc->bdev, buf)); |
@@ -905,10 +908,10 @@ void bch_cached_dev_detach(struct cached_dev *dc) | |||
905 | { | 908 | { |
906 | lockdep_assert_held(&bch_register_lock); | 909 | lockdep_assert_held(&bch_register_lock); |
907 | 910 | ||
908 | if (atomic_read(&dc->disk.closing)) | 911 | if (test_bit(BCACHE_DEV_CLOSING, &dc->disk.flags)) |
909 | return; | 912 | return; |
910 | 913 | ||
911 | if (atomic_xchg(&dc->disk.detaching, 1)) | 914 | if (test_and_set_bit(BCACHE_DEV_DETACHING, &dc->disk.flags)) |
912 | return; | 915 | return; |
913 | 916 | ||
914 | /* | 917 | /* |
@@ -1064,11 +1067,7 @@ static void cached_dev_flush(struct closure *cl) | |||
1064 | struct bcache_device *d = &dc->disk; | 1067 | struct bcache_device *d = &dc->disk; |
1065 | 1068 | ||
1066 | mutex_lock(&bch_register_lock); | 1069 | mutex_lock(&bch_register_lock); |
1067 | d->flush_done = 1; | 1070 | bcache_device_unlink(d); |
1068 | |||
1069 | if (d->c) | ||
1070 | bcache_device_unlink(d); | ||
1071 | |||
1072 | mutex_unlock(&bch_register_lock); | 1071 | mutex_unlock(&bch_register_lock); |
1073 | 1072 | ||
1074 | bch_cache_accounting_destroy(&dc->accounting); | 1073 | bch_cache_accounting_destroy(&dc->accounting); |
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 4b672449ffaf..194d43782ea4 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c | |||
@@ -370,7 +370,7 @@ STORE(__bch_flash_dev) | |||
370 | } | 370 | } |
371 | 371 | ||
372 | if (attr == &sysfs_unregister) { | 372 | if (attr == &sysfs_unregister) { |
373 | atomic_set(&d->detaching, 1); | 373 | set_bit(BCACHE_DEV_DETACHING, &d->flags); |
374 | bcache_device_stop(d); | 374 | bcache_device_stop(d); |
375 | } | 375 | } |
376 | 376 | ||
diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c index 22e21dc9a037..99053b1251be 100644 --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c | |||
@@ -89,7 +89,7 @@ static unsigned writeback_delay(struct cached_dev *dc, unsigned sectors) | |||
89 | { | 89 | { |
90 | uint64_t ret; | 90 | uint64_t ret; |
91 | 91 | ||
92 | if (atomic_read(&dc->disk.detaching) || | 92 | if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) || |
93 | !dc->writeback_percent) | 93 | !dc->writeback_percent) |
94 | return 0; | 94 | return 0; |
95 | 95 | ||
@@ -404,7 +404,7 @@ static int bch_writeback_thread(void *arg) | |||
404 | while (!kthread_should_stop()) { | 404 | while (!kthread_should_stop()) { |
405 | down_write(&dc->writeback_lock); | 405 | down_write(&dc->writeback_lock); |
406 | if (!atomic_read(&dc->has_dirty) || | 406 | if (!atomic_read(&dc->has_dirty) || |
407 | (!atomic_read(&dc->disk.detaching) && | 407 | (!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) && |
408 | !dc->writeback_running)) { | 408 | !dc->writeback_running)) { |
409 | up_write(&dc->writeback_lock); | 409 | up_write(&dc->writeback_lock); |
410 | set_current_state(TASK_INTERRUPTIBLE); | 410 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -437,7 +437,7 @@ static int bch_writeback_thread(void *arg) | |||
437 | 437 | ||
438 | while (delay && | 438 | while (delay && |
439 | !kthread_should_stop() && | 439 | !kthread_should_stop() && |
440 | !atomic_read(&dc->disk.detaching)) | 440 | !test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags)) |
441 | delay = schedule_timeout_interruptible(delay); | 441 | delay = schedule_timeout_interruptible(delay); |
442 | } | 442 | } |
443 | } | 443 | } |
diff --git a/drivers/md/bcache/writeback.h b/drivers/md/bcache/writeback.h index fe7d9d56492b..c9ddcf4614b9 100644 --- a/drivers/md/bcache/writeback.h +++ b/drivers/md/bcache/writeback.h | |||
@@ -45,7 +45,7 @@ static inline bool should_writeback(struct cached_dev *dc, struct bio *bio, | |||
45 | unsigned in_use = dc->disk.c->gc_stats.in_use; | 45 | unsigned in_use = dc->disk.c->gc_stats.in_use; |
46 | 46 | ||
47 | if (cache_mode != CACHE_MODE_WRITEBACK || | 47 | if (cache_mode != CACHE_MODE_WRITEBACK || |
48 | atomic_read(&dc->disk.detaching) || | 48 | test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) || |
49 | in_use > CUTOFF_WRITEBACK_SYNC) | 49 | in_use > CUTOFF_WRITEBACK_SYNC) |
50 | return false; | 50 | return false; |
51 | 51 | ||