diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2017-01-13 01:41:53 -0900 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-01-13 01:41:53 -0900 |
commit | 7597926bdef9c14ee544cfc2dff4ccb371ac1d9e (patch) | |
tree | e57216030083db55399c0c64eb3cf351a83df312 | |
parent | 743761bb2e0b887d03262b949cb100ba23d3af0a (diff) |
bcache: add interfaces for manually fixing uuid entriesbcache_uuid_debug
-rw-r--r-- | drivers/md/bcache/sysfs.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index b3ff57d61dde..bc1342b5409e 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -36,6 +36,9 @@ write_attribute(trigger_gc); write_attribute(prune_cache); write_attribute(flash_vol_create); +write_attribute(unsafe_clear_all_uuids); +write_attribute(unsafe_uuid_set); + read_attribute(bucket_size); read_attribute(block_size); read_attribute(nbuckets); @@ -60,6 +63,7 @@ read_attribute(btree_used_percent); read_attribute(average_key_size); read_attribute(dirty_data); read_attribute(bset_tree_stats); +read_attribute(inode_data); read_attribute(state); read_attribute(cache_read_races); @@ -514,6 +518,55 @@ static unsigned bch_average_key_size(struct cache_set *c) : 0; } +struct print_inode_data { + struct btree_op op; + u64 inode; + u64 sectors; + + char *buf; + size_t offset; +}; + +static void print_inode(struct print_inode_data *s) +{ + if (s->sectors) + s->offset += snprintf(s->buf + s->offset, PAGE_SIZE - s->offset, + "%-6llu %10llu\n", s->inode, s->sectors); + s->sectors = 0; +} + +static int print_inode_data_fn(struct btree_op *op, struct btree *b, + struct bkey *k) +{ + struct print_inode_data *s = + container_of(op, struct print_inode_data, op); + + if (KEY_INODE(k) != s->inode) + print_inode(s); + + s->inode = KEY_INODE(k); + s->sectors += KEY_SIZE(k); + + return MAP_CONTINUE; +} + +static int bch_print_inode_data(struct cache_set *c, char *buf) +{ + struct print_inode_data s; + + memset(&s, 0, sizeof(s)); + bch_btree_op_init(&s.op, -1); + + s.buf = buf; + s.offset = snprintf(s.buf, PAGE_SIZE, "Inode Sectors\n"); + + bch_btree_map_keys(&s.op, c, &ZERO_KEY, print_inode_data_fn, 0); + + print_inode(&s); + + return s.offset; +} + SHOW(__bch_cache_set) { struct cache_set *c = container_of(kobj, struct cache_set, kobj); @@ -573,10 +626,24 @@ SHOW(__bch_cache_set) if (attr == &sysfs_bset_tree_stats) return bch_bset_print_stats(c, buf); + if (attr == &sysfs_inode_data) + return bch_print_inode_data(c, buf); + return 0; } SHOW_LOCKED(bch_cache_set) +static char *strsep_nonempty(char **s, const char *ct) +{ + char *tok; + + do { + tok = strsep(s, ct); + } while (tok && !*tok); + + return tok; +} + STORE(__bch_cache_set) { struct cache_set *c = container_of(kobj, struct cache_set, kobj); @@ -653,6 +720,48 @@ STORE(__bch_cache_set) sysfs_strtoul(btree_shrinker_disabled, c->shrinker_disabled); sysfs_strtoul(copy_gc_enabled, c->copy_gc_enabled); + if (attr == &sysfs_unsafe_clear_all_uuids) { + memset(c->uuids, 0, sizeof(struct uuid_entry) * c->nr_uuids); + bch_uuid_write(c); + } + + if (attr == &sysfs_unsafe_uuid_set) { + struct uuid_entry *u; + char *inode_s, *uuid_s, *line, *p; + u64 inode; + char uuid[16]; + ssize_t ret = -EINVAL; + + line = p = kstrdup(buf, GFP_KERNEL); + if (!line) + return -ENOMEM; + + inode_s = strsep_nonempty(&p, " \t\n"); + uuid_s = strsep_nonempty(&p, " \t\n"); + + if (!inode_s || kstrtou64(inode_s, 10, &inode)) + goto invalid; + + if (!uuid_s || bch_parse_uuid(uuid_s, uuid) < 16) + goto invalid; + + if (inode >= c->nr_uuids) + goto invalid; + + u = &c->uuids[inode]; + + memset(u, 0, sizeof(struct uuid_entry)); + memcpy(u->uuid, uuid, 16); + u->first_reg = u->last_reg = cpu_to_le32(get_seconds()); + + bch_uuid_write(c); + + ret = size; +invalid: + kfree(line); + return ret; + } + return size; } STORE_LOCKED(bch_cache_set) @@ -713,10 +822,14 @@ static struct attribute *bch_cache_set_internal_files[] = { &sysfs_btree_cache_max_chain, &sysfs_bset_tree_stats, + &sysfs_inode_data, &sysfs_cache_read_races, &sysfs_writeback_keys_done, &sysfs_writeback_keys_failed, + &sysfs_unsafe_clear_all_uuids, + &sysfs_unsafe_uuid_set, + &sysfs_trigger_gc, &sysfs_prune_cache, #ifdef CONFIG_BCACHE_DEBUG |