Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4d951dd authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcache: Fix sysfs splat on shutdown with flash only devs



Whoops.

Signed-off-by: default avatarKent Overstreet <kmo@daterainc.com>
parent 48a915a8
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -266,12 +266,10 @@ struct bcache_device {

	struct gendisk		*disk;

	/* If nonzero, we're closing */
	atomic_t		closing;

	/* If nonzero, we're detaching/unregistering from cache set */
	atomic_t		detaching;
	int			flush_done;
	unsigned long		flags;
#define BCACHE_DEV_CLOSING	0
#define BCACHE_DEV_DETACHING	1
#define BCACHE_DEV_UNLINK_DONE	2

	unsigned		nr_stripes;
	unsigned		stripe_size;
+1 −1
Original line number Diff line number Diff line
@@ -512,7 +512,7 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
	struct task_struct *task = current;
	struct io *i;

	if (atomic_read(&dc->disk.detaching) ||
	if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) ||
	    c->gc_stats.in_use > CUTOFF_CACHE_ADD ||
	    (bio->bi_rw & REQ_DISCARD))
		goto skip;
+20 −21
Original line number Diff line number Diff line
@@ -621,7 +621,7 @@ static void prio_read(struct cache *ca, uint64_t bucket)
static int open_dev(struct block_device *b, fmode_t mode)
{
	struct bcache_device *d = b->bd_disk->private_data;
	if (atomic_read(&d->closing))
	if (test_bit(BCACHE_DEV_CLOSING, &d->flags))
		return -ENXIO;

	closure_get(&d->cl);
@@ -650,12 +650,15 @@ static const struct block_device_operations bcache_ops = {

void bcache_device_stop(struct bcache_device *d)
{
	if (!atomic_xchg(&d->closing, 1))
	if (!test_and_set_bit(BCACHE_DEV_CLOSING, &d->flags))
		closure_queue(&d->cl);
}

static void bcache_device_unlink(struct bcache_device *d)
{
	lockdep_assert_held(&bch_register_lock);

	if (d->c && !test_and_set_bit(BCACHE_DEV_UNLINK_DONE, &d->flags)) {
		unsigned i;
		struct cache *ca;

@@ -665,6 +668,7 @@ static void bcache_device_unlink(struct bcache_device *d)
		for_each_cache(ca, d->c, i)
			bd_unlink_disk_holder(ca->bdev, d->disk);
	}
}

static void bcache_device_link(struct bcache_device *d, struct cache_set *c,
			       const char *name)
@@ -687,18 +691,15 @@ static void bcache_device_detach(struct bcache_device *d)
{
	lockdep_assert_held(&bch_register_lock);

	if (atomic_read(&d->detaching)) {
	if (test_bit(BCACHE_DEV_DETACHING, &d->flags)) {
		struct uuid_entry *u = d->c->uuids + d->id;

		SET_UUID_FLASH_ONLY(u, 0);
		memcpy(u->uuid, invalid_uuid, 16);
		u->invalidated = cpu_to_le32(get_seconds());
		bch_uuid_write(d->c);

		atomic_set(&d->detaching, 0);
	}

	if (!d->flush_done)
	bcache_device_unlink(d);

	d->c->devices[d->id] = NULL;
@@ -879,7 +880,7 @@ static void cached_dev_detach_finish(struct work_struct *w)
	struct closure cl;
	closure_init_stack(&cl);

	BUG_ON(!atomic_read(&dc->disk.detaching));
	BUG_ON(!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags));
	BUG_ON(atomic_read(&dc->count));

	mutex_lock(&bch_register_lock);
@@ -893,6 +894,8 @@ static void cached_dev_detach_finish(struct work_struct *w)
	bcache_device_detach(&dc->disk);
	list_move(&dc->list, &uncached_devices);

	clear_bit(BCACHE_DEV_DETACHING, &dc->disk.flags);

	mutex_unlock(&bch_register_lock);

	pr_info("Caching disabled for %s", bdevname(dc->bdev, buf));
@@ -905,10 +908,10 @@ void bch_cached_dev_detach(struct cached_dev *dc)
{
	lockdep_assert_held(&bch_register_lock);

	if (atomic_read(&dc->disk.closing))
	if (test_bit(BCACHE_DEV_CLOSING, &dc->disk.flags))
		return;

	if (atomic_xchg(&dc->disk.detaching, 1))
	if (test_and_set_bit(BCACHE_DEV_DETACHING, &dc->disk.flags))
		return;

	/*
@@ -1064,11 +1067,7 @@ static void cached_dev_flush(struct closure *cl)
	struct bcache_device *d = &dc->disk;

	mutex_lock(&bch_register_lock);
	d->flush_done = 1;

	if (d->c)
	bcache_device_unlink(d);

	mutex_unlock(&bch_register_lock);

	bch_cache_accounting_destroy(&dc->accounting);
+1 −1
Original line number Diff line number Diff line
@@ -370,7 +370,7 @@ STORE(__bch_flash_dev)
	}

	if (attr == &sysfs_unregister) {
		atomic_set(&d->detaching, 1);
		set_bit(BCACHE_DEV_DETACHING, &d->flags);
		bcache_device_stop(d);
	}

+3 −3
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ static unsigned writeback_delay(struct cached_dev *dc, unsigned sectors)
{
	uint64_t ret;

	if (atomic_read(&dc->disk.detaching) ||
	if (test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) ||
	    !dc->writeback_percent)
		return 0;

@@ -404,7 +404,7 @@ static int bch_writeback_thread(void *arg)
	while (!kthread_should_stop()) {
		down_write(&dc->writeback_lock);
		if (!atomic_read(&dc->has_dirty) ||
		    (!atomic_read(&dc->disk.detaching) &&
		    (!test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags) &&
		     !dc->writeback_running)) {
			up_write(&dc->writeback_lock);
			set_current_state(TASK_INTERRUPTIBLE);
@@ -437,7 +437,7 @@ static int bch_writeback_thread(void *arg)

			while (delay &&
			       !kthread_should_stop() &&
			       !atomic_read(&dc->disk.detaching))
			       !test_bit(BCACHE_DEV_DETACHING, &dc->disk.flags))
				delay = schedule_timeout_interruptible(delay);
		}
	}
Loading