summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2015-06-19 00:45:52 -0700
committerKent Overstreet <kent.overstreet@gmail.com>2016-10-07 12:34:31 -0800
commit64960f9024d202ef9c75001dc532b94af431a442 (patch)
tree4ebd025fc484e1c4fa9d13d6cff0e0c68fc25f4f
parentb6f11ba1f954e09cbbc9f595280a81d30e580f71 (diff)
bcache: Mount options for checksumming, compression
-rw-r--r--drivers/md/bcache/alloc.c2
-rw-r--r--drivers/md/bcache/bcache.h1
-rw-r--r--drivers/md/bcache/btree.c2
-rw-r--r--drivers/md/bcache/fs.c61
-rw-r--r--drivers/md/bcache/io.c4
-rw-r--r--drivers/md/bcache/journal.c2
-rw-r--r--drivers/md/bcache/opts.h60
-rw-r--r--drivers/md/bcache/super.c37
-rw-r--r--drivers/md/bcache/super.h12
-rw-r--r--drivers/md/bcache/super_types.h11
-rw-r--r--drivers/md/bcache/sysfs.c18
11 files changed, 139 insertions, 71 deletions
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index d86133c79420..c71939db8699 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -264,7 +264,7 @@ static int bch_prio_write(struct cache *ca)
p->next_bucket = ca->prio_buckets[i + 1];
p->magic = pset_magic(&c->sb);
- SET_PSET_CSUM_TYPE(p, CACHE_META_PREFERRED_CSUM_TYPE(&c->sb));
+ SET_PSET_CSUM_TYPE(p, c->opts.meta_csum_type);
p->csum = bch_checksum(PSET_CSUM_TYPE(p),
&p->magic,
bucket_bytes(ca) - 8);
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index d1b0b61de590..00b28947fd51 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -196,6 +196,7 @@
#include "fifo.h"
#include "util.h"
#include "closure.h"
+#include "opts.h"
#include <linux/dynamic_fault.h>
diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c
index bda2f38171f4..ce33985d2f9c 100644
--- a/drivers/md/bcache/btree.c
+++ b/drivers/md/bcache/btree.c
@@ -789,7 +789,7 @@ static void do_btree_node_write(struct closure *cl)
i->version = BCACHE_BSET_VERSION;
- SET_BSET_CSUM_TYPE(i, CACHE_META_PREFERRED_CSUM_TYPE(&c->sb));
+ SET_BSET_CSUM_TYPE(i, c->opts.meta_csum_type);
if (!b->written) {
BUG_ON(b->data->magic != bset_magic(&c->sb));
diff --git a/drivers/md/bcache/fs.c b/drivers/md/bcache/fs.c
index 8ccf8c3f291c..6a71ac45ddb8 100644
--- a/drivers/md/bcache/fs.c
+++ b/drivers/md/bcache/fs.c
@@ -2015,22 +2015,23 @@ out:
}
enum {
- Opt_err_cont, Opt_err_panic, Opt_err_ro,
- Opt_user_xattr, Opt_nouser_xattr,
+ Opt_err_action,
+ Opt_meta_checksum,
+ Opt_data_checksum,
+ Opt_compression,
Opt_acl, Opt_noacl,
Opt_verbose_recovery,
Opt_err
};
static const match_table_t tokens = {
- {Opt_err_cont, "errors=continue"},
- {Opt_err_panic, "errors=panic"},
- {Opt_err_ro, "errors=remount-ro"},
- {Opt_user_xattr, "user_xattr"},
- {Opt_nouser_xattr, "nouser_xattr"},
+ {Opt_err_action, "errors=%s"},
+ {Opt_meta_checksum, "metadata_checksum=%s"},
+ {Opt_data_checksum, "data_checksum=%s"},
+ {Opt_compression, "compression=%s"},
+ {Opt_verbose_recovery, "verbose_recovery"},
{Opt_acl, "acl"},
{Opt_noacl, "noacl"},
- {Opt_verbose_recovery, "verbose_recovery"},
{Opt_err, NULL}
};
@@ -2038,6 +2039,8 @@ static int parse_options(struct cache_set_opts *opts, int flags, char *options)
{
char *p;
substring_t args[MAX_OPT_ARGS];
+ char arg[80];
+ ssize_t v;
*opts = cache_set_opts_empty();
@@ -2054,17 +2057,40 @@ static int parse_options(struct cache_set_opts *opts, int flags, char *options)
token = match_token(p, tokens, args);
switch (token) {
- case Opt_err_panic:
- opts->on_error_action = BCH_ON_ERROR_PANIC;
+ case Opt_err_action:
+ match_strlcpy(arg, &args[0], sizeof(arg));
+ v = bch_read_string_list(arg, bch_error_actions);
+ if (v < 0)
+ return 0;
+
+ opts->on_error_action = v;
break;
- case Opt_err_ro:
- opts->on_error_action = BCH_ON_ERROR_RO;
+ case Opt_meta_checksum:
+ match_strlcpy(arg, &args[0], sizeof(arg));
+ v = bch_read_string_list(arg, bch_csum_types);
+ if (v < 0)
+ return 0;
+
+ opts->meta_csum_type = v;
+ break;
+ case Opt_data_checksum:
+ match_strlcpy(arg, &args[0], sizeof(arg));
+ v = bch_read_string_list(arg, bch_csum_types);
+ if (v < 0)
+ return 0;
+
+ opts->data_csum_type = v;
break;
- case Opt_err_cont:
- opts->on_error_action = BCH_ON_ERROR_CONTINUE;
+ case Opt_compression:
+ match_strlcpy(arg, &args[0], sizeof(arg));
+ v = bch_read_string_list(arg, bch_compression_types);
+ if (v < 0)
+ return 0;
+
+ opts->compression_type = v;
break;
- case Opt_user_xattr:
- case Opt_nouser_xattr:
+ case Opt_verbose_recovery:
+ opts->verbose_recovery = true;
break;
case Opt_acl:
opts->posix_acl = true;
@@ -2072,9 +2098,6 @@ static int parse_options(struct cache_set_opts *opts, int flags, char *options)
case Opt_noacl:
opts->posix_acl = false;
break;
- case Opt_verbose_recovery:
- opts->verbose_recovery = true;
- break;
default:
return 0;
}
diff --git a/drivers/md/bcache/io.c b/drivers/md/bcache/io.c
index 46dacb05ab91..6dc685bb74b3 100644
--- a/drivers/md/bcache/io.c
+++ b/drivers/md/bcache/io.c
@@ -701,8 +701,8 @@ static void bch_write_extent(struct bch_write_op *op,
struct bkey_i_extent *e = bkey_i_to_extent(k);
struct bch_extent_ptr *ptr;
unsigned ptrs_from = 0;
- unsigned csum_type = CACHE_DATA_PREFERRED_CSUM_TYPE(&c->sb);
- unsigned compression_type = CACHE_COMPRESSION_TYPE(&c->sb);
+ unsigned csum_type = c->opts.data_csum_type;
+ unsigned compression_type = c->opts.compression_type;
/* don't refetch csum type/compression type */
barrier();
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index b05ae06bc6c9..e6e3020131bb 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -1425,7 +1425,7 @@ static void journal_write_locked(struct closure *cl)
w->data->version = BCACHE_JSET_VERSION;
w->data->last_seq = last_seq(j);
- SET_JSET_CSUM_TYPE(w->data, CACHE_META_PREFERRED_CSUM_TYPE(&c->sb));
+ SET_JSET_CSUM_TYPE(w->data, c->opts.meta_csum_type);
w->data->csum = csum_set(w->data, JSET_CSUM_TYPE(w->data));
sectors = set_blocks(w->data, block_bytes(c)) * c->sb.block_size;
diff --git a/drivers/md/bcache/opts.h b/drivers/md/bcache/opts.h
new file mode 100644
index 000000000000..9e919292a9f3
--- /dev/null
+++ b/drivers/md/bcache/opts.h
@@ -0,0 +1,60 @@
+#ifndef _BCACHE_OPTS_H
+#define _BCACHE_OPTS_H
+
+/*
+ * We store options as signed integers, where -1 means undefined. This means we
+ * can pass the mount options to cache_set_alloc() as a whole struct, and then
+ * only apply the options from that struct that are defined.
+ */
+
+#define CACHE_SET_OPTS() \
+ DEF_CACHE_SET_OPT(read_only, 2) \
+ DEF_CACHE_SET_OPT(on_error_action, 3) \
+ DEF_CACHE_SET_OPT(meta_csum_type, 4) \
+ DEF_CACHE_SET_OPT(data_csum_type, 4) \
+ DEF_CACHE_SET_OPT(compression_type, 4) \
+ DEF_CACHE_SET_OPT(verbose_recovery, 2) \
+ DEF_CACHE_SET_OPT(posix_acl, 2)
+
+struct cache_set_opts {
+#define DEF_CACHE_SET_OPT(opt, bits) int opt:bits;
+ CACHE_SET_OPTS()
+#undef DEF_CACHE_SET_OPT
+};
+
+static inline struct cache_set_opts cache_set_opts_empty(void)
+{
+ struct cache_set_opts ret;
+
+ memset(&ret, 255, sizeof(ret));
+ return ret;
+}
+
+/*
+ * Initial options from superblock - here we don't want any options undefined,
+ * any options the superblock doesn't specify are set to 0:
+ */
+static inline struct cache_set_opts cache_superblock_opts(struct cache_sb *sb)
+{
+ return (struct cache_set_opts) {
+ .read_only = 0,
+ .on_error_action = CACHE_ERROR_ACTION(sb),
+ .meta_csum_type = CACHE_META_PREFERRED_CSUM_TYPE(sb),
+ .data_csum_type = CACHE_DATA_PREFERRED_CSUM_TYPE(sb),
+ .compression_type = CACHE_COMPRESSION_TYPE(sb),
+ .verbose_recovery = 0,
+ };
+}
+
+static inline void cache_set_opts_apply(struct cache_set_opts *dst,
+ struct cache_set_opts src)
+{
+#define DEF_CACHE_SET_OPT(opt, bits) \
+ if (src.opt >= 0) \
+ dst->opt = src.opt;
+
+ CACHE_SET_OPTS()
+#undef DEF_CACHE_SET_OPT
+}
+
+#endif /* _BCACHE_OPTS_H */
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index c7db7faa6e8a..61e17b1d94a6 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -45,6 +45,28 @@
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kent Overstreet <kent.overstreet@gmail.com>");
+const char * const bch_error_actions[] = {
+ "continue",
+ "remount-ro",
+ "panic",
+ NULL
+};
+
+const char * const bch_csum_types[] = {
+ "none",
+ "crc32c",
+ "crc64",
+ NULL
+};
+
+const char * const bch_compression_types[] = {
+ "none",
+ "lzo1x",
+ "gzip",
+ "xz",
+ NULL
+};
+
static const uuid_le invalid_uuid = {
.b = {
0xa0, 0x3e, 0xf8, 0xed, 0x3e, 0xe1, 0xb8, 0x78,
@@ -596,8 +618,7 @@ static void __bcache_write_super(struct cache_set *c)
cache_sb_from_cache_set(c, ca);
- SET_CACHE_SB_CSUM_TYPE(&ca->sb,
- CACHE_META_PREFERRED_CSUM_TYPE(&c->sb));
+ SET_CACHE_SB_CSUM_TYPE(&ca->sb, c->opts.meta_csum_type);
bio_reset(bio);
bio->bi_bdev = ca->disk_sb.bdev;
@@ -989,16 +1010,8 @@ static struct cache_set *bch_cache_set_alloc(struct cache_sb *sb,
scnprintf(c->uuid, sizeof(c->uuid), "%pU", &c->sb.user_uuid);
- c->opts = (struct cache_set_opts) {
- .read_only = 0,
- .on_error_action = CACHE_ERROR_ACTION(&c->sb),
- .verbose_recovery = 0,
- };
-
- if (opts.read_only >= 0)
- c->opts.read_only = opts.read_only;
- if (opts.on_error_action >= 0)
- c->opts.on_error_action = opts.on_error_action;
+ c->opts = cache_superblock_opts(sb);
+ cache_set_opts_apply(&c->opts, opts);
c->minor = -1;
c->block_bits = ilog2(c->sb.block_size);
diff --git a/drivers/md/bcache/super.h b/drivers/md/bcache/super.h
index 15b03c6e54a2..df6489d99f72 100644
--- a/drivers/md/bcache/super.h
+++ b/drivers/md/bcache/super.h
@@ -109,6 +109,10 @@ u64 bch_checksum(unsigned, const void *, size_t);
bch_checksum(type, start, end - start); \
})
+extern const char * const bch_error_actions[];
+extern const char * const bch_csum_types[];
+extern const char * const bch_compression_types[];
+
void bch_check_mark_super_slowpath(struct cache_set *,
const struct bkey_i *, bool);
@@ -158,14 +162,6 @@ void bch_cache_release(struct kobject *);
void bch_cache_set_unregister(struct cache_set *);
void bch_cache_set_stop(struct cache_set *);
-static inline struct cache_set_opts cache_set_opts_empty(void)
-{
- struct cache_set_opts ret;
-
- memset(&ret, 255, sizeof(ret));
- return ret;
-}
-
const char *bch_register_one(const char *path);
const char *bch_register_cache_set(char * const *, unsigned,
struct cache_set_opts,
diff --git a/drivers/md/bcache/super_types.h b/drivers/md/bcache/super_types.h
index 9e110428c2af..d89f780f544f 100644
--- a/drivers/md/bcache/super_types.h
+++ b/drivers/md/bcache/super_types.h
@@ -8,15 +8,4 @@ struct bcache_superblock {
unsigned page_order;
};
-struct cache_set_opts {
- /* For each opt, -1 = undefined */
-
- int read_only:2;
- int on_error_action:3;
-
- /* filesystem options: */
- int posix_acl:2;
- int verbose_recovery:2;
-};
-
#endif /* _BCACHE_SUPER_TYPES_H */
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index 3ef183698fa2..f119f1e851f8 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -22,13 +22,6 @@
#include <linux/blkdev.h>
#include <linux/sort.h>
-static const char * const bch_csum_types[] = {
- "none",
- "crc32c",
- "crc64",
- NULL
-};
-
static const char * const cache_replacement_policies[] = {
"lru",
"fifo",
@@ -46,13 +39,6 @@ static const char * const bch_cache_modes[] = {
NULL
};
-static const char * const error_actions[] = {
- "continue",
- "readonly",
- "panic",
- NULL
-};
-
static const char * const bch_cache_state[] = {
"active",
"readonly",
@@ -655,7 +641,7 @@ SHOW(bch_cache_set)
CACHE_META_PREFERRED_CSUM_TYPE(&c->sb));
if (attr == &sysfs_errors)
- return bch_snprint_string_list(buf, PAGE_SIZE, error_actions,
+ return bch_snprint_string_list(buf, PAGE_SIZE, bch_error_actions,
CACHE_ERROR_ACTION(&c->sb));
/* See count_io_errors for why 88 */
@@ -748,7 +734,7 @@ STORE(__bch_cache_set)
c->congested_write_threshold_us);
if (attr == &sysfs_errors) {
- ssize_t v = bch_read_string_list(buf, error_actions);
+ ssize_t v = bch_read_string_list(buf, bch_error_actions);
if (v < 0)
return v;