aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-08-21 20:49:09 -0400
committerKent Overstreet <kmo@daterainc.com>2013-11-11 00:56:41 -0500
commitc4d951ddb66fe1d087447b0ba65c4fa4446f1083 (patch)
tree80564725ffa4cfa0d1a02b0a80f419edcd424548
parent48a915a87f0bd98c3d68d029acf223a2e5116f07 (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.h10
-rw-r--r--drivers/md/bcache/request.c2
-rw-r--r--drivers/md/bcache/super.c41
-rw-r--r--drivers/md/bcache/sysfs.c2
-rw-r--r--drivers/md/bcache/writeback.c6
-rw-r--r--drivers/md/bcache/writeback.h2
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)
621static int open_dev(struct block_device *b, fmode_t mode) 621static 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
651void bcache_device_stop(struct bcache_device *d) 651void 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
657static void bcache_device_unlink(struct bcache_device *d) 657static 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
669static void bcache_device_link(struct bcache_device *d, struct cache_set *c, 673static 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