// SPDX-License-Identifier: GPL-2.0
/*
 * bcache sysfs interfaces
 *
 * Copyright 2010, 2011 Kent Overstreet <kent.overstreet@gmail.com>
 * Copyright 2012 Google, Inc.
 */

#include "bcache.h"
#include "sysfs.h"
#include "btree.h"
#include "request.h"
#include "writeback.h"

#include <linux/blkdev.h>
#include <linux/sort.h>
#include <linux/sched/clock.h>

/* Default is 0 ("writethrough") */
static const char * const bch_cache_modes[] = {
	"writethrough",
	"writeback",
	"writearound",
	"none",
	NULL
};

/* Default is 0 ("auto") */
static const char * const bch_stop_on_failure_modes[] = {
	"auto",
	"always",
	NULL
};

static const char * const cache_replacement_policies[] = {
	"lru",
	"fifo",
	"random",
	NULL
};

static const char * const error_actions[] = {
	"unregister",
	"panic",
	NULL
};

write_attribute(attach);
write_attribute(detach);
write_attribute(unregister);
write_attribute(stop);
write_attribute(clear_stats);
write_attribute(trigger_gc);
write_attribute(prune_cache);
write_attribute(flash_vol_create);

read_attribute(bucket_size);
read_attribute(block_size);
read_attribute(nbuckets);
read_attribute(tree_depth);
read_attribute(root_usage_percent);
read_attribute(priority_stats);
read_attribute(btree_cache_size);
read_attribute(btree_cache_max_chain);
read_attribute(cache_available_percent);
read_attribute(written);
read_attribute(btree_written);
read_attribute(metadata_written);
read_attribute(active_journal_entries);
read_attribute(backing_dev_name);
read_attribute(backing_dev_uuid);

sysfs_time_stats_attribute(btree_gc,	sec, ms);
sysfs_time_stats_attribute(btree_split, sec, us);
sysfs_time_stats_attribute(btree_sort,	ms,  us);
sysfs_time_stats_attribute(btree_read,	ms,  us);

read_attribute(btree_nodes);
read_attribute(btree_used_percent);
read_attribute(average_key_size);
read_attribute(dirty_data);
read_attribute(bset_tree_stats);

read_attribute(state);
read_attribute(cache_read_races);
read_attribute(reclaim);
read_attribute(flush_write);
read_attribute(retry_flush_write);
read_attribute(writeback_keys_done);
read_attribute(writeback_keys_failed);
read_attribute(io_errors);
read_attribute(congested);
read_attribute(cutoff_writeback);
read_attribute(cutoff_writeback_sync);
rw_attribute(congested_read_threshold_us);
rw_attribute(congested_write_threshold_us);

rw_attribute(sequential_cutoff);
rw_attribute(data_csum);
rw_attribute(cache_mode);
rw_attribute(stop_when_cache_set_failed);
rw_attribute(writeback_metadata);
rw_attribute(writeback_running);
rw_attribute(writeback_percent);
rw_attribute(writeback_delay);
rw_attribute(writeback_rate);

rw_attribute(writeback_rate_update_seconds);
rw_attribute(writeback_rate_i_term_inverse);
rw_attribute(writeback_rate_p_term_inverse);
rw_attribute(writeback_rate_minimum);
read_attribute(writeback_rate_debug);

read_attribute(stripe_size);
read_attribute(partial_stripes_expensive);

rw_attribute(synchronous);
rw_attribute(journal_delay_ms);
rw_attribute(io_disable);
rw_attribute(discard);
rw_attribute(running);
rw_attribute(label);
rw_attribute(readahead);
rw_attribute(errors);
rw_attribute(io_error_limit);
rw_attribute(io_error_halflife);
rw_attribute(verify);
rw_attribute(bypass_torture_test);
rw_attribute(key_merging_disabled);
rw_attribute(gc_always_rewrite);
rw_attribute(expensive_debug_checks);
rw_attribute(cache_replacement_policy);
rw_attribute(btree_shrinker_disabled);
rw_attribute(copy_gc_enabled);
rw_attribute(gc_after_writeback);
rw_attribute(size);

static ssize_t bch_snprint_string_list(char *buf,
				       size_t size,
				       const char * const list[],
				       size_t selected)
{
	char *out = buf;
	size_t i;

	for (i = 0; list[i]; i++)
		out += snprintf(out, buf + size - out,
				i == selected ? "[%s] " : "%s ", list[i]);

	out[-1] = '\n';
	return out - buf;
}

SHOW(__bch_cached_dev)
{
	struct cached_dev *dc = container_of(kobj, struct cached_dev,
					     disk.kobj);
	char const *states[] = { "no cache", "clean", "dirty", "inconsistent" };
	int wb = dc->writeback_running;

#define var(stat)		(dc->stat)

	if (attr == &sysfs_cache_mode)
		return bch_snprint_string_list(buf, PAGE_SIZE,
					       bch_cache_modes,
					       BDEV_CACHE_MODE(&dc->sb));

	if (attr == &sysfs_stop_when_cache_set_failed)
		return bch_snprint_string_list(buf, PAGE_SIZE,
					       bch_stop_on_failure_modes,
					       dc->stop_when_cache_set_failed);


	sysfs_printf(data_csum,		"%i", dc->disk.data_csum);
	var_printf(verify,		"%i");
	var_printf(bypass_torture_test,	"%i");
	var_printf(writeback_metadata,	"%i");
	var_printf(writeback_running,	"%i");
	var_print(writeback_delay);
	var_print(writeback_percent);
	sysfs_hprint(writeback_rate,
		     wb ? atomic_long_read(&dc->writeback_rate.rate) << 9 : 0);
	sysfs_hprint(io_errors,		atomic_read(&dc->io_errors));
	sysfs_printf(io_error_limit,	"%i", dc->error_limit);
	sysfs_printf(io_disable,	"%i", dc->io_disable);
	var_print(writeback_rate_update_seconds);
	var_print(writeback_rate_i_term_inverse);
	var_print(writeback_rate_p_term_inverse);
	var_print(writeback_rate_minimum);

	if (attr == &sysfs_writeback_rate_debug) {
		char rate[20];
		char dirty[20];
		char target[20];
		char proportional[20];
		char integral[20];
		char change[20];
		s64 next_io;

		/*
		 * Except for dirty and target, other values should
		 * be 0 if writeback is not running.
		 */
		bch_hprint(rate,
			   wb ? atomic_long_read(&dc->writeback_rate.rate) << 9
			      : 0);
		bch_hprint(dirty, bcache_dev_sectors_dirty(&dc->disk) << 9);
		bch_hprint(target, dc->writeback_rate_target << 9);
		bch_hprint(proportional,
			   wb ? dc->writeback_rate_proportional << 9 : 0);
		bch_hprint(integral,
			   wb ? dc->writeback_rate_integral_scaled << 9 : 0);
		bch_hprint(change, wb ? dc->writeback_rate_change << 9 : 0);
		next_io = wb ? div64_s64(dc->writeback_rate.next-local_clock(),
					 NSEC_PER_MSEC) : 0;

		return sprintf(buf,
			       "rate:\t\t%s/sec\n"
			       "dirty:\t\t%s\n"
			       "target:\t\t%s\n"
			       "proportional:\t%s\n"
			       "integral:\t%s\n"
			       "change:\t\t%s/sec\n"
			       "next io:\t%llims\n",
			       rate, dirty, target, proportional,
			       integral, change, next_io);
	}

	sysfs_hprint(dirty_data,
		     bcache_dev_sectors_dirty(&dc->disk) << 9);

	sysfs_hprint(stripe_size,	 ((uint64_t)dc->disk.stripe_size) << 9);
	var_printf(partial_stripes_expensive,	"%u");

	var_hprint(sequential_cutoff);
	var_hprint(readahead);

	sysfs_print(running,		atomic_read(&dc->running));
	sysfs_print(state,		states[BDEV_STATE(&dc->sb)]);

	if (attr == &sysfs_label) {
		memcpy(buf, dc->sb.label, SB_LABEL_SIZE);
		buf[SB_LABEL_SIZE + 1] = '\0';
		strcat(buf, "\n");
		return strlen(buf);
	}

	if (attr == &sysfs_backing_dev_name) {
		snprintf(buf, BDEVNAME_SIZE + 1, "%s", dc->backing_dev_name);
		strcat(buf, "\n");
		return strlen(buf);
	}

	if (attr == &sysfs_backing_dev_uuid) {
		/* convert binary uuid into 36-byte string plus '\0' */
		snprintf(buf, 36+1, "%pU", dc->sb.uuid);
		strcat(buf, "\n");
		return strlen(buf);
	}

#undef var
	return 0;
}
SHOW_LOCKED(bch_cached_dev)

STORE(__cached_dev)
{
	struct cached_dev *dc = container_of(kobj, struct cached_dev,
					     disk.kobj);
	ssize_t v;
	struct cache_set *c;
	struct kobj_uevent_env *env;

#define d_strtoul(var)		sysfs_strtoul(var, dc->var)
#define d_strtoul_nonzero(var)	sysfs_strtoul_clamp(var, dc->var, 1, INT_MAX)
#define d_strtoi_h(var)		sysfs_hatoi(var, dc->var)

	sysfs_strtoul(data_csum,	dc->disk.data_csum);
	d_strtoul(verify);
	sysfs_strtoul_bool(bypass_torture_test, dc->bypass_torture_test);
	sysfs_strtoul_bool(writeback_metadata, dc->writeback_metadata);
	sysfs_strtoul_bool(writeback_running, dc->writeback_running);
	sysfs_strtoul_clamp(writeback_delay, dc->writeback_delay, 0, UINT_MAX);

	sysfs_strtoul_clamp(writeback_percent, dc->writeback_percent,
			    0, bch_cutoff_writeback);

	if (attr == &sysfs_writeback_rate) {
		ssize_t ret;
		long int v = atomic_long_read(&dc->writeback_rate.rate);

		ret = strtoul_safe_clamp(buf, v, 1, INT_MAX);

		if (!ret) {
			atomic_long_set(&dc->writeback_rate.rate, v);
			ret = size;
		}

		return ret;
	}

	sysfs_strtoul_clamp(writeback_rate_update_seconds,
			    dc->writeback_rate_update_seconds,
			    1, WRITEBACK_RATE_UPDATE_SECS_MAX);
	sysfs_strtoul_clamp(writeback_rate_i_term_inverse,
			    dc->writeback_rate_i_term_inverse,
			    1, UINT_MAX);
	sysfs_strtoul_clamp(writeback_rate_p_term_inverse,
			    dc->writeback_rate_p_term_inverse,
			    1, UINT_MAX);
	sysfs_strtoul_clamp(writeback_rate_minimum,
			    dc->writeback_rate_minimum,
			    1, UINT_MAX);

	sysfs_strtoul_clamp(io_error_limit, dc->error_limit, 0, INT_MAX);

	if (attr == &sysfs_io_disable) {
		int v = strtoul_or_return(buf);

		dc->io_disable = v ? 1 : 0;
	}

	sysfs_strtoul_clamp(sequential_cutoff,
			    dc->sequential_cutoff,
			    0, UINT_MAX);
	d_strtoi_h(readahead);

	if (attr == &sysfs_clear_stats)
		bch_cache_accounting_clear(&dc->accounting);

	if (attr == &sysfs_running &&
	    strtoul_or_return(buf))
		bch_cached_dev_run(dc);

	if (attr == &sysfs_cache_mode) {
		v = __sysfs_match_string(bch_cache_modes, -1, buf);
		if (v < 0)
			return v;

		if ((unsigned int) v != BDEV_CACHE_MODE(&dc->sb)) {
			SET_BDEV_CACHE_MODE(&dc->sb, v);
			bch_write_bdev_super(dc, NULL);
		}
	}

	if (attr == &sysfs_stop_when_cache_set_failed) {
		v = __sysfs_match_string(bch_stop_on_failure_modes, -1, buf);
		if (v < 0)
			return v;

		dc->stop_when_cache_set_failed = v;
	}

	if (attr == &sysfs_label) {
		if (size > SB_LABEL_SIZE)
			return -EINVAL;
		memcpy(dc->sb.label, buf, size);
		if (size < SB_LABEL_SIZE)
			dc->sb.label[size] = '\0';
		if (size && dc->sb.label[size - 1] == '\n')
			dc->sb.label[size - 1] = '\0';
		bch_write_bdev_super(dc, NULL);
		if (dc->disk.c) {
			memcpy(dc->disk.c->uuids[dc->disk.id].label,
			       buf, SB_LABEL_SIZE);
			bch_uuid_write(dc->disk.c);
		}
		env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL);
		if (!env)
			return -ENOMEM;
		add_uevent_var(env, "DRIVER=bcache");
		add_uevent_var(env, "CACHED_UUID=%pU", dc->sb.uuid),
		add_uevent_var(env, "CACHED_LABEL=%s", buf);
		kobject_uevent_env(&disk_to_dev(dc->disk.disk)->kobj,
				   KOBJ_CHANGE,
				   env->envp);
		kfree(env);
	}

	if (attr == &sysfs_attach) {
		uint8_t		set_uuid[16];

		if (bch_parse_uuid(buf, set_uuid) < 16)
			return -EINVAL;

		v = -ENOENT;
		list_for_each_entry(c, &bch_cache_sets, list) {
			v = bch_cached_dev_attach(dc, c, set_uuid);
			if (!v)
				return size;
		}
		if (v == -ENOENT)
			pr_err("Can't attach %s: cache set not found", buf);
		return v;
	}

	if (attr == &sysfs_detach && dc->disk.c)
		bch_cached_dev_detach(dc);

	if (attr == &sysfs_stop)
		bcache_device_stop(&dc->disk);

	return size;
}

STORE(bch_cached_dev)
{
	struct cached_dev *dc = container_of(kobj, struct cached_dev,
					     disk.kobj);

	mutex_lock(&bch_register_lock);
	size = __cached_dev_store(kobj, attr, buf, size);

	if (attr == &sysfs_writeback_running) {
		/* dc->writeback_running changed in __cached_dev_store() */
		if (IS_ERR_OR_NULL(dc->writeback_thread)) {
			/*
			 * reject setting it to 1 via sysfs if writeback
			 * kthread is not created yet.
			 */
			if (dc->writeback_running) {
				dc->writeback_running = false;
				pr_err("%s: failed to run non-existent writeback thread",
						dc->disk.disk->disk_name);
			}
		} else
			/*
			 * writeback kthread will check if dc->writeback_running
			 * is true or false.
			 */
			bch_writeback_queue(dc);
	}

	/*
	 * Only set BCACHE_DEV_WB_RUNNING when cached device attached to
	 * a cache set, otherwise it doesn't make sense.
	 */
	if (attr == &sysfs_writeback_percent)
		if ((dc->disk.c != NULL) &&
		    (!test_and_set_bit(BCACHE_DEV_WB_RUNNING, &dc->disk.flags)))
			schedule_delayed_work(&dc->writeback_rate_update,
				      dc->writeback_rate_update_seconds * HZ);

	mutex_unlock(&bch_register_lock);
	return size;
}

static struct attribute *bch_cached_dev_files[] = {
	&sysfs_attach,
	&sysfs_detach,
	&sysfs_stop,
#if 0
	&sysfs_data_csum,
#endif
	&sysfs_cache_mode,
	&sysfs_stop_when_cache_set_failed,
	&sysfs_writeback_metadata,
	&sysfs_writeback_running,
	&sysfs_writeback_delay,
	&sysfs_writeback_percent,
	&sysfs_writeback_rate,
	&sysfs_writeback_rate_update_seconds,
	&sysfs_writeback_rate_i_term_inverse,
	&sysfs_writeback_rate_p_term_inverse,
	&sysfs_writeback_rate_minimum,
	&sysfs_writeback_rate_debug,
	&sysfs_errors,
	&sysfs_io_error_limit,
	&sysfs_io_disable,
	&sysfs_dirty_data,
	&sysfs_stripe_size,
	&sysfs_partial_stripes_expensive,
	&sysfs_sequential_cutoff,
	&sysfs_clear_stats,
	&sysfs_running,
	&sysfs_state,
	&sysfs_label,
	&sysfs_readahead,
#ifdef CONFIG_BCACHE_DEBUG
	&sysfs_verify,
	&sysfs_bypass_torture_test,
#endif
	&sysfs_backing_dev_name,
	&sysfs_backing_dev_uuid,
	NULL
};
KTYPE(bch_cached_dev);

SHOW(bch_flash_dev)
{
	struct bcache_device *d = container_of(kobj, struct bcache_device,
					       kobj);
	struct uuid_entry *u = &d->c->uuids[d->id];

	sysfs_printf(data_csum,	"%i", d->data_csum);
	sysfs_hprint(size,	u->sectors << 9);

	if (attr == &sysfs_label) {
		memcpy(buf, u->label, SB_LABEL_SIZE);
		buf[SB_LABEL_SIZE + 1] = '\0';
		strcat(buf, "\n");
		return strlen(buf);
	}

	return 0;
}

STORE(__bch_flash_dev)
{
	struct bcache_device *d = container_of(kobj, struct bcache_device,
					       kobj);
	struct uuid_entry *u = &d->c->uuids[d->id];

	sysfs_strtoul(data_csum,	d->data_csum);

	if (attr == &sysfs_size) {
		uint64_t v;

		strtoi_h_or_return(buf, v);

		u->sectors = v >> 9;
		bch_uuid_write(d->c);
		set_capacity(d->disk, u->sectors);
	}

	if (attr == &sysfs_label) {
		memcpy(u->label, buf, SB_LABEL_SIZE);
		bch_uuid_write(d->c);
	}

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

	return size;
}
STORE_LOCKED(bch_flash_dev)

static struct attribute *bch_flash_dev_files[] = {
	&sysfs_unregister,
#if 0
	&sysfs_data_csum,
#endif
	&sysfs_label,
	&sysfs_size,
	NULL
};
KTYPE(bch_flash_dev);

struct bset_stats_op {
	struct btree_op op;
	size_t nodes;
	struct bset_stats stats;
};

static int bch_btree_bset_stats(struct btree_op *b_op, struct btree *b)
{
	struct bset_stats_op *op = container_of(b_op, struct bset_stats_op, op);

	op->nodes++;
	bch_btree_keys_stats(&b->keys, &op->stats);

	return MAP_CONTINUE;
}

static int bch_bset_print_stats(struct cache_set *c, char *buf)
{
	struct bset_stats_op op;
	int ret;

	memset(&op, 0, sizeof(op));
	bch_btree_op_init(&op.op, -1);

	ret = bch_btree_map_nodes(&op.op, c, &ZERO_KEY, bch_btree_bset_stats);
	if (ret < 0)
		return ret;

	return snprintf(buf, PAGE_SIZE,
			"btree nodes:		%zu\n"
			"written sets:		%zu\n"
			"unwritten sets:		%zu\n"
			"written key bytes:	%zu\n"
			"unwritten key bytes:	%zu\n"
			"floats:			%zu\n"
			"failed:			%zu\n",
			op.nodes,
			op.stats.sets_written, op.stats.sets_unwritten,
			op.stats.bytes_written, op.stats.bytes_unwritten,
			op.stats.floats, op.stats.failed);
}

static unsigned int bch_root_usage(struct cache_set *c)
{
	unsigned int bytes = 0;
	struct bkey *k;
	struct btree *b;
	struct btree_iter iter;

	goto lock_root;

	do {
		rw_unlock(false, b);
lock_root:
		b = c->root;
		rw_lock(false, b, b->level);
	} while (b != c->root);

	for_each_key_filter(&b->keys, k, &iter, bch_ptr_bad)
		bytes += bkey_bytes(k);

	rw_unlock(false, b);

	return (bytes * 100) / btree_bytes(c);
}

static size_t bch_cache_size(struct cache_set *c)
{
	size_t ret = 0;
	struct btree *b;

	mutex_lock(&c->bucket_lock);
	list_for_each_entry(b, &c->btree_cache, list)
		ret += 1 << (b->keys.page_order + PAGE_SHIFT);

	mutex_unlock(&c->bucket_lock);
	return ret;
}

static unsigned int bch_cache_max_chain(struct cache_set *c)
{
	unsigned int ret = 0;
	struct hlist_head *h;

	mutex_lock(&c->bucket_lock);

	for (h = c->bucket_hash;
	     h < c->bucket_hash + (1 << BUCKET_HASH_BITS);
	     h++) {
		unsigned int i = 0;
		struct hlist_node *p;

		hlist_for_each(p, h)
			i++;

		ret = max(ret, i);
	}

	mutex_unlock(&c->bucket_lock);
	return ret;
}

static unsigned int bch_btree_used(struct cache_set *c)
{
	return div64_u64(c->gc_stats.key_bytes * 100,
			 (c->gc_stats.nodes ?: 1) * btree_bytes(c));
}

static unsigned int bch_average_key_size(struct cache_set *c)
{
	return c->gc_stats.nkeys
		? div64_u64(c->gc_stats.data, c->gc_stats.nkeys)
		: 0;
}

SHOW(__bch_cache_set)
{
	struct cache_set *c = container_of(kobj, struct cache_set, kobj);

	sysfs_print(synchronous,		CACHE_SYNC(&c->sb));
	sysfs_print(journal_delay_ms,		c->journal_delay_ms);
	sysfs_hprint(bucket_size,		bucket_bytes(c));
	sysfs_hprint(block_size,		block_bytes(c));
	sysfs_print(tree_depth,			c->root->level);
	sysfs_print(root_usage_percent,		bch_root_usage(c));

	sysfs_hprint(btree_cache_size,		bch_cache_size(c));
	sysfs_print(btree_cache_max_chain,	bch_cache_max_chain(c));
	sysfs_print(cache_available_percent,	100 - c->gc_stats.in_use);

	sysfs_print_time_stats(&c->btree_gc_time,	btree_gc, sec, ms);
	sysfs_print_time_stats(&c->btree_split_time,	btree_split, sec, us);
	sysfs_print_time_stats(&c->sort.time,		btree_sort, ms, us);
	sysfs_print_time_stats(&c->btree_read_time,	btree_read, ms, us);

	sysfs_print(btree_used_percent,	bch_btree_used(c));
	sysfs_print(btree_nodes,	c->gc_stats.nodes);
	sysfs_hprint(average_key_size,	bch_average_key_size(c));

	sysfs_print(cache_read_races,
		    atomic_long_read(&c->cache_read_races));

	sysfs_print(reclaim,
		    atomic_long_read(&c->reclaim));

	sysfs_print(flush_write,
		    atomic_long_read(&c->flush_write));

	sysfs_print(retry_flush_write,
		    atomic_long_read(&c->retry_flush_write));

	sysfs_print(writeback_keys_done,
		    atomic_long_read(&c->writeback_keys_done));
	sysfs_print(writeback_keys_failed,
		    atomic_long_read(&c->writeback_keys_failed));

	if (attr == &sysfs_errors)
		return bch_snprint_string_list(buf, PAGE_SIZE, error_actions,
					       c->on_error);

	/* See count_io_errors for why 88 */
	sysfs_print(io_error_halflife,	c->error_decay * 88);
	sysfs_print(io_error_limit,	c->error_limit);

	sysfs_hprint(congested,
		     ((uint64_t) bch_get_congested(c)) << 9);
	sysfs_print(congested_read_threshold_us,
		    c->congested_read_threshold_us);
	sysfs_print(congested_write_threshold_us,
		    c->congested_write_threshold_us);

	sysfs_print(cutoff_writeback, bch_cutoff_writeback);
	sysfs_print(cutoff_writeback_sync, bch_cutoff_writeback_sync);

	sysfs_print(active_journal_entries,	fifo_used(&c->journal.pin));
	sysfs_printf(verify,			"%i", c->verify);
	sysfs_printf(key_merging_disabled,	"%i", c->key_merging_disabled);
	sysfs_printf(expensive_debug_checks,
		     "%i", c->expensive_debug_checks);
	sysfs_printf(gc_always_rewrite,		"%i", c->gc_always_rewrite);
	sysfs_printf(btree_shrinker_disabled,	"%i", c->shrinker_disabled);
	sysfs_printf(copy_gc_enabled,		"%i", c->copy_gc_enabled);
	sysfs_printf(gc_after_writeback,	"%i", c->gc_after_writeback);
	sysfs_printf(io_disable,		"%i",
		     test_bit(CACHE_SET_IO_DISABLE, &c->flags));

	if (attr == &sysfs_bset_tree_stats)
		return bch_bset_print_stats(c, buf);

	return 0;
}
SHOW_LOCKED(bch_cache_set)

STORE(__bch_cache_set)
{
	struct cache_set *c = container_of(kobj, struct cache_set, kobj);
	ssize_t v;

	if (attr == &sysfs_unregister)
		bch_cache_set_unregister(c);

	if (attr == &sysfs_stop)
		bch_cache_set_stop(c);

	if (attr == &sysfs_synchronous) {
		bool sync = strtoul_or_return(buf);

		if (sync != CACHE_SYNC(&c->sb)) {
			SET_CACHE_SYNC(&c->sb, sync);
			bcache_write_super(c);
		}
	}

	if (attr == &sysfs_flash_vol_create) {
		int r;
		uint64_t v;

		strtoi_h_or_return(buf, v);

		r = bch_flash_dev_create(c, v);
		if (r)
			return r;
	}

	if (attr == &sysfs_clear_stats) {
		atomic_long_set(&c->writeback_keys_done,	0);
		atomic_long_set(&c->writeback_keys_failed,	0);

		memset(&c->gc_stats, 0, sizeof(struct gc_stat));
		bch_cache_accounting_clear(&c->accounting);
	}

	if (attr == &sysfs_trigger_gc)
		force_wake_up_gc(c);

	if (attr == &sysfs_prune_cache) {
		struct shrink_control sc;

		sc.gfp_mask = GFP_KERNEL;
		sc.nr_to_scan = strtoul_or_return(buf);
		c->shrink.scan_objects(&c->shrink, &sc);
	}

	sysfs_strtoul_clamp(congested_read_threshold_us,
			    c->congested_read_threshold_us,
			    0, UINT_MAX);
	sysfs_strtoul_clamp(congested_write_threshold_us,
			    c->congested_write_threshold_us,
			    0, UINT_MAX);

	if (attr == &sysfs_errors) {
		v = __sysfs_match_string(error_actions, -1, buf);
		if (v < 0)
			return v;

		c->on_error = v;
	}

	sysfs_strtoul_clamp(io_error_limit, c->error_limit, 0, UINT_MAX);

	/* See count_io_errors() for why 88 */
	if (attr == &sysfs_io_error_halflife) {
		unsigned long v = 0;
		ssize_t ret;

		ret = strtoul_safe_clamp(buf, v, 0, UINT_MAX);
		if (!ret) {
			c->error_decay = v / 88;
			return size;
		}
		return ret;
	}

	if (attr == &sysfs_io_disable) {
		v = strtoul_or_return(buf);
		if (v) {
			if (test_and_set_bit(CACHE_SET_IO_DISABLE,
					     &c->flags))
				pr_warn("CACHE_SET_IO_DISABLE already set");
		} else {
			if (!test_and_clear_bit(CACHE_SET_IO_DISABLE,
						&c->flags))
				pr_warn("CACHE_SET_IO_DISABLE already cleared");
		}
	}

	sysfs_strtoul_clamp(journal_delay_ms,
			    c->journal_delay_ms,
			    0, USHRT_MAX);
	sysfs_strtoul_bool(verify,		c->verify);
	sysfs_strtoul_bool(key_merging_disabled, c->key_merging_disabled);
	sysfs_strtoul(expensive_debug_checks,	c->expensive_debug_checks);
	sysfs_strtoul_bool(gc_always_rewrite,	c->gc_always_rewrite);
	sysfs_strtoul_bool(btree_shrinker_disabled, c->shrinker_disabled);
	sysfs_strtoul_bool(copy_gc_enabled,	c->copy_gc_enabled);
	/*
	 * write gc_after_writeback here may overwrite an already set
	 * BCH_DO_AUTO_GC, it doesn't matter because this flag will be
	 * set in next chance.
	 */
	sysfs_strtoul_clamp(gc_after_writeback, c->gc_after_writeback, 0, 1);

	return size;
}
STORE_LOCKED(bch_cache_set)

SHOW(bch_cache_set_internal)
{
	struct cache_set *c = container_of(kobj, struct cache_set, internal);

	return bch_cache_set_show(&c->kobj, attr, buf);
}

STORE(bch_cache_set_internal)
{
	struct cache_set *c = container_of(kobj, struct cache_set, internal);

	return bch_cache_set_store(&c->kobj, attr, buf, size);
}

static void bch_cache_set_internal_release(struct kobject *k)
{
}

static struct attribute *bch_cache_set_files[] = {
	&sysfs_unregister,
	&sysfs_stop,
	&sysfs_synchronous,
	&sysfs_journal_delay_ms,
	&sysfs_flash_vol_create,

	&sysfs_bucket_size,
	&sysfs_block_size,
	&sysfs_tree_depth,
	&sysfs_root_usage_percent,
	&sysfs_btree_cache_size,
	&sysfs_cache_available_percent,

	&sysfs_average_key_size,

	&sysfs_errors,
	&sysfs_io_error_limit,
	&sysfs_io_error_halflife,
	&sysfs_congested,
	&sysfs_congested_read_threshold_us,
	&sysfs_congested_write_threshold_us,
	&sysfs_clear_stats,
	NULL
};
KTYPE(bch_cache_set);

static struct attribute *bch_cache_set_internal_files[] = {
	&sysfs_active_journal_entries,

	sysfs_time_stats_attribute_list(btree_gc, sec, ms)
	sysfs_time_stats_attribute_list(btree_split, sec, us)
	sysfs_time_stats_attribute_list(btree_sort, ms, us)
	sysfs_time_stats_attribute_list(btree_read, ms, us)

	&sysfs_btree_nodes,
	&sysfs_btree_used_percent,
	&sysfs_btree_cache_max_chain,

	&sysfs_bset_tree_stats,
	&sysfs_cache_read_races,
	&sysfs_reclaim,
	&sysfs_flush_write,
	&sysfs_retry_flush_write,
	&sysfs_writeback_keys_done,
	&sysfs_writeback_keys_failed,

	&sysfs_trigger_gc,
	&sysfs_prune_cache,
#ifdef CONFIG_BCACHE_DEBUG
	&sysfs_verify,
	&sysfs_key_merging_disabled,
	&sysfs_expensive_debug_checks,
#endif
	&sysfs_gc_always_rewrite,
	&sysfs_btree_shrinker_disabled,
	&sysfs_copy_gc_enabled,
	&sysfs_gc_after_writeback,
	&sysfs_io_disable,
	&sysfs_cutoff_writeback,
	&sysfs_cutoff_writeback_sync,
	NULL
};
KTYPE(bch_cache_set_internal);

static int __bch_cache_cmp(const void *l, const void *r)
{
	return *((uint16_t *)r) - *((uint16_t *)l);
}

SHOW(__bch_cache)
{
	struct cache *ca = container_of(kobj, struct cache, kobj);

	sysfs_hprint(bucket_size,	bucket_bytes(ca));
	sysfs_hprint(block_size,	block_bytes(ca));
	sysfs_print(nbuckets,		ca->sb.nbuckets);
	sysfs_print(discard,		ca->discard);
	sysfs_hprint(written, atomic_long_read(&ca->sectors_written) << 9);
	sysfs_hprint(btree_written,
		     atomic_long_read(&ca->btree_sectors_written) << 9);
	sysfs_hprint(metadata_written,
		     (atomic_long_read(&ca->meta_sectors_written) +
		      atomic_long_read(&ca->btree_sectors_written)) << 9);

	sysfs_print(io_errors,
		    atomic_read(&ca->io_errors) >> IO_ERROR_SHIFT);

	if (attr == &sysfs_cache_replacement_policy)
		return bch_snprint_string_list(buf, PAGE_SIZE,
					       cache_replacement_policies,
					       CACHE_REPLACEMENT(&ca->sb));

	if (attr == &sysfs_priority_stats) {
		struct bucket *b;
		size_t n = ca->sb.nbuckets, i;
		size_t unused = 0, available = 0, dirty = 0, meta = 0;
		uint64_t sum = 0;
		/* Compute 31 quantiles */
		uint16_t q[31], *p, *cached;
		ssize_t ret;

		cached = p = vmalloc(array_size(sizeof(uint16_t),
						ca->sb.nbuckets));
		if (!p)
			return -ENOMEM;

		mutex_lock(&ca->set->bucket_lock);
		for_each_bucket(b, ca) {
			if (!GC_SECTORS_USED(b))
				unused++;
			if (GC_MARK(b) == GC_MARK_RECLAIMABLE)
				available++;
			if (GC_MARK(b) == GC_MARK_DIRTY)
				dirty++;
			if (GC_MARK(b) == GC_MARK_METADATA)
				meta++;
		}

		for (i = ca->sb.first_bucket; i < n; i++)
			p[i] = ca->buckets[i].prio;
		mutex_unlock(&ca->set->bucket_lock);

		sort(p, n, sizeof(uint16_t), __bch_cache_cmp, NULL);

		while (n &&
		       !cached[n - 1])
			--n;

		while (cached < p + n &&
		       *cached == BTREE_PRIO)
			cached++, n--;

		for (i = 0; i < n; i++)
			sum += INITIAL_PRIO - cached[i];

		if (n)
			do_div(sum, n);

		for (i = 0; i < ARRAY_SIZE(q); i++)
			q[i] = INITIAL_PRIO - cached[n * (i + 1) /
				(ARRAY_SIZE(q) + 1)];

		vfree(p);

		ret = scnprintf(buf, PAGE_SIZE,
				"Unused:		%zu%%\n"
				"Clean:		%zu%%\n"
				"Dirty:		%zu%%\n"
				"Metadata:	%zu%%\n"
				"Average:	%llu\n"
				"Sectors per Q:	%zu\n"
				"Quantiles:	[",
				unused * 100 / (size_t) ca->sb.nbuckets,
				available * 100 / (size_t) ca->sb.nbuckets,
				dirty * 100 / (size_t) ca->sb.nbuckets,
				meta * 100 / (size_t) ca->sb.nbuckets, sum,
				n * ca->sb.bucket_size / (ARRAY_SIZE(q) + 1));

		for (i = 0; i < ARRAY_SIZE(q); i++)
			ret += scnprintf(buf + ret, PAGE_SIZE - ret,
					 "%u ", q[i]);
		ret--;

		ret += scnprintf(buf + ret, PAGE_SIZE - ret, "]\n");

		return ret;
	}

	return 0;
}
SHOW_LOCKED(bch_cache)

STORE(__bch_cache)
{
	struct cache *ca = container_of(kobj, struct cache, kobj);
	ssize_t v;

	if (attr == &sysfs_discard) {
		bool v = strtoul_or_return(buf);

		if (blk_queue_discard(bdev_get_queue(ca->bdev)))
			ca->discard = v;

		if (v != CACHE_DISCARD(&ca->sb)) {
			SET_CACHE_DISCARD(&ca->sb, v);
			bcache_write_super(ca->set);
		}
	}

	if (attr == &sysfs_cache_replacement_policy) {
		v = __sysfs_match_string(cache_replacement_policies, -1, buf);
		if (v < 0)
			return v;

		if ((unsigned int) v != CACHE_REPLACEMENT(&ca->sb)) {
			mutex_lock(&ca->set->bucket_lock);
			SET_CACHE_REPLACEMENT(&ca->sb, v);
			mutex_unlock(&ca->set->bucket_lock);

			bcache_write_super(ca->set);
		}
	}

	if (attr == &sysfs_clear_stats) {
		atomic_long_set(&ca->sectors_written, 0);
		atomic_long_set(&ca->btree_sectors_written, 0);
		atomic_long_set(&ca->meta_sectors_written, 0);
		atomic_set(&ca->io_count, 0);
		atomic_set(&ca->io_errors, 0);
	}

	return size;
}
STORE_LOCKED(bch_cache)

static struct attribute *bch_cache_files[] = {
	&sysfs_bucket_size,
	&sysfs_block_size,
	&sysfs_nbuckets,
	&sysfs_priority_stats,
	&sysfs_discard,
	&sysfs_written,
	&sysfs_btree_written,
	&sysfs_metadata_written,
	&sysfs_io_errors,
	&sysfs_clear_stats,
	&sysfs_cache_replacement_policy,
	NULL
};
KTYPE(bch_cache);
