summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-06-08 06:45:49 -0800
committerKent Overstreet <kent.overstreet@gmail.com>2017-01-18 21:39:39 -0900
commit7cad968c98615968528b7afc54e42214937ab0f8 (patch)
treed4360ed15f2ea79d0e554e64f6e83a640a8997e5
parentc0a7b10abb0915d6ab361fd53f9efc8fe9ce078f (diff)
bcache: Add options for gc, root user reserves
-rw-r--r--drivers/md/bcache/alloc.c2
-rw-r--r--drivers/md/bcache/bcache.h5
-rw-r--r--drivers/md/bcache/super.c38
-rw-r--r--drivers/md/bcache/sysfs.c10
-rw-r--r--include/uapi/linux/bcache.h40
5 files changed, 56 insertions, 39 deletions
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c
index 5bea5472a6be..0fedca0e2a0a 100644
--- a/drivers/md/bcache/alloc.c
+++ b/drivers/md/bcache/alloc.c
@@ -1555,7 +1555,7 @@ static void bch_recalc_capacity(struct cache_set *c)
total_capacity = capacity;
- capacity *= (100 - c->sector_reserve_percent);
+ capacity *= (100 - c->opts.gc_reserve_percent);
capacity = div64_u64(capacity, 100);
BUG_ON(capacity + reserved_sectors > total_capacity);
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 52f6ab20aee2..6903ab40ac6f 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -809,11 +809,6 @@ struct cache_set {
* buckets is below this percentage
*/
unsigned foreground_target_percent;
- /*
- * foreground writes will fail when the number of free sectors is
- * below this percentage
- */
- unsigned sector_reserve_percent;
#define BCH_DEBUG_PARAM(name, description) bool name;
BCH_DEBUG_PARAMS_ALL()
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 99aff0b5879e..c9f2978a23bb 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -220,7 +220,7 @@ static const char *validate_cache_super(struct bcache_superblock *disk_sb)
return"Unsupported superblock version";
}
- if (CACHE_SYNC(sb) &&
+ if (CACHE_SET_SYNC(sb) &&
le64_to_cpu(sb->version) != BCACHE_SB_VERSION_CDEV_V3)
return "Unsupported superblock version";
@@ -265,15 +265,22 @@ static const char *validate_cache_super(struct bcache_superblock *disk_sb)
if (CACHE_SB_CSUM_TYPE(sb) >= BCH_CSUM_NR)
return "Invalid checksum type";
- if (!CACHE_BTREE_NODE_SIZE(sb))
+ if (!CACHE_SET_BTREE_NODE_SIZE(sb))
return "Btree node size not set";
- if (!is_power_of_2(CACHE_BTREE_NODE_SIZE(sb)))
+ if (!is_power_of_2(CACHE_SET_BTREE_NODE_SIZE(sb)))
return "Btree node size not a power of two";
- if (CACHE_BTREE_NODE_SIZE(sb) > BTREE_NODE_SIZE_MAX)
+ if (CACHE_SET_BTREE_NODE_SIZE(sb) > BTREE_NODE_SIZE_MAX)
return "Btree node size too large";
+ /* Default value, for old filesystems: */
+ if (!CACHE_SET_GC_RESERVE(sb))
+ SET_CACHE_SET_GC_RESERVE(sb, 10);
+
+ if (CACHE_SET_GC_RESERVE(sb) < 5)
+ return "gc reserve percentage too small";
+
if (le16_to_cpu(sb->u64s) < bch_journal_buckets_offset(sb))
return "Invalid superblock: member info area missing";
@@ -560,7 +567,7 @@ static int cache_sb_to_cache_set(struct cache_set *c, struct cache_sb *src)
dst->block_size = src->block_size;
c->sb.block_size = le16_to_cpu(src->block_size);
- c->sb.btree_node_size = CACHE_BTREE_NODE_SIZE(src);
+ c->sb.btree_node_size = CACHE_SET_BTREE_NODE_SIZE(src);
c->sb.nr_in_set = src->nr_in_set;
@@ -1129,7 +1136,6 @@ static struct cache_set *bch_cache_set_alloc(struct cache_sb *sb,
c->tiering_percent = 10;
c->foreground_target_percent = 20;
- c->sector_reserve_percent = 20;
c->journal.write_time = &c->journal_write_time;
c->journal.delay_time = &c->journal_delay_time;
@@ -1282,12 +1288,12 @@ static const char *run_cache_set(struct cache_set *c)
cache_sb_from_cache_set(c, ca);
/*
- * CACHE_SYNC is true if the cache set has already been run
+ * CACHE_SET_SYNC is true if the cache set has already been run
* and potentially has data.
* It is false if it is the first time it is run.
*/
- if (CACHE_SYNC(&c->disk_sb)) {
+ if (CACHE_SET_SYNC(&c->disk_sb)) {
LIST_HEAD(journal);
struct jset *j;
@@ -1424,7 +1430,7 @@ static const char *run_cache_set(struct cache_set *c)
goto err;
/* Mark cache set as initialized: */
- SET_CACHE_SYNC(&c->disk_sb, true);
+ SET_CACHE_SET_SYNC(&c->disk_sb, true);
}
if (c->opts.read_only) {
@@ -1477,7 +1483,7 @@ static const char *can_add_cache(struct cache_sb *sb,
return "mismatched block size";
if (le16_to_cpu(sb->members[sb->nr_this_dev].bucket_size) <
- CACHE_BTREE_NODE_SIZE(&c->disk_sb))
+ CACHE_SET_BTREE_NODE_SIZE(&c->disk_sb))
return "new cache bucket_size is too small";
return NULL;
@@ -1879,10 +1885,6 @@ static const char *cache_alloc(struct bcache_superblock *sb,
if (c->sb.nr_in_set == 1)
bdevname(sb->bdev, c->name);
- err = validate_cache_super(sb);
- if (err)
- return err;
-
if (cache_set_init_fault("cache_alloc"))
return err;
@@ -2023,6 +2025,10 @@ static const char *register_cache(struct bcache_superblock *sb,
const char *err = "cannot allocate memory";
struct cache_set *c;
+ err = validate_cache_super(sb);
+ if (err)
+ return err;
+
bdevname(sb->bdev, name);
c = cache_set_lookup(sb->sb->set_uuid);
@@ -2234,6 +2240,10 @@ const char *bch_register_cache_set(char * const *devices, unsigned nr_devices,
err = "attempting to register backing device";
if (__SB_IS_BDEV(le64_to_cpu(sb[i].sb->version)))
goto err_unlock;
+
+ err = validate_cache_super(sb);
+ if (err)
+ return err;
}
err = "cache set already registered";
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index 61d01bfd66a6..596d43571641 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -153,7 +153,6 @@ rw_attribute(btree_flush_delay);
rw_attribute(pd_controllers_update_seconds);
rw_attribute(foreground_target_percent);
-rw_attribute(sector_reserve_percent);
rw_attribute(size);
read_attribute(meta_replicas_have);
@@ -647,10 +646,8 @@ SHOW(bch_cache_set)
sysfs_hprint(block_size, block_bytes(c));
sysfs_print(block_size_bytes, block_bytes(c));
- sysfs_hprint(btree_node_size,
- CACHE_BTREE_NODE_SIZE(&c->disk_sb) << 9);
- sysfs_print(btree_node_size_bytes,
- CACHE_BTREE_NODE_SIZE(&c->disk_sb) << 9);
+ sysfs_hprint(btree_node_size, c->sb.btree_node_size << 9);
+ sysfs_print(btree_node_size_bytes, c->sb.btree_node_size << 9);
sysfs_hprint(btree_cache_size, bch_cache_size(c));
sysfs_print(cache_available_percent, bch_cache_available_percent(c));
@@ -691,7 +688,6 @@ SHOW(bch_cache_set)
sysfs_print(pd_controllers_update_seconds,
c->pd_controllers_update_seconds);
sysfs_print(foreground_target_percent, c->foreground_target_percent);
- sysfs_print(sector_reserve_percent, c->sector_reserve_percent);
sysfs_printf(tiering_enabled, "%i", c->tiering_enabled);
sysfs_print(tiering_percent, c->tiering_percent);
@@ -808,7 +804,6 @@ STORE(__bch_cache_set)
sysfs_strtoul(pd_controllers_update_seconds,
c->pd_controllers_update_seconds);
sysfs_strtoul(foreground_target_percent, c->foreground_target_percent);
- sysfs_strtoul(sector_reserve_percent, c->sector_reserve_percent);
sysfs_strtoul(tiering_percent, c->tiering_percent);
sysfs_pd_controller_store(tiering, &c->tiering_pd);
@@ -903,7 +898,6 @@ static struct attribute *bch_cache_set_files[] = {
&sysfs_btree_flush_delay,
&sysfs_foreground_target_percent,
- &sysfs_sector_reserve_percent,
&sysfs_tiering_percent,
&sysfs_journal_flush,
diff --git a/include/uapi/linux/bcache.h b/include/uapi/linux/bcache.h
index 0b04508c0a7b..efc4271f8428 100644
--- a/include/uapi/linux/bcache.h
+++ b/include/uapi/linux/bcache.h
@@ -705,7 +705,9 @@ struct cache_sb {
* to change:
*/
uuid_le user_uuid;
- __le64 pad1[6];
+
+ __le64 flags2;
+ __le64 pad1[5];
/* Number of cache_member entries: */
__u8 nr_in_set;
@@ -732,9 +734,11 @@ struct cache_sb {
};
};
-LE64_BITMASK(CACHE_SYNC, struct cache_sb, flags, 0, 1);
+/* XXX: rename CACHE_SET -> BCH_FS or something? */
-LE64_BITMASK(CACHE_ERROR_ACTION, struct cache_sb, flags, 1, 4);
+LE64_BITMASK(CACHE_SET_SYNC, struct cache_sb, flags, 0, 1);
+
+LE64_BITMASK(CACHE_SET_ERROR_ACTION, struct cache_sb, flags, 1, 4);
#define BCH_ON_ERROR_CONTINUE 0U
#define BCH_ON_ERROR_RO 1U
#define BCH_ON_ERROR_PANIC 2U
@@ -747,13 +751,13 @@ LE64_BITMASK(CACHE_SET_DATA_REPLICAS_WANT,struct cache_sb, flags, 8, 12);
LE64_BITMASK(CACHE_SB_CSUM_TYPE, struct cache_sb, flags, 12, 16);
-LE64_BITMASK(CACHE_META_PREFERRED_CSUM_TYPE,struct cache_sb, flags, 16, 20);
+LE64_BITMASK(CACHE_SET_META_PREFERRED_CSUM_TYPE,struct cache_sb, flags, 16, 20);
#define BCH_CSUM_NONE 0U
#define BCH_CSUM_CRC32C 1U
#define BCH_CSUM_CRC64 2U
#define BCH_CSUM_NR 3U
-LE64_BITMASK(CACHE_BTREE_NODE_SIZE, struct cache_sb, flags, 20, 36);
+LE64_BITMASK(CACHE_SET_BTREE_NODE_SIZE, struct cache_sb, flags, 20, 36);
LE64_BITMASK(CACHE_SET_META_REPLICAS_HAVE,struct cache_sb, flags, 36, 40);
LE64_BITMASK(CACHE_SET_DATA_REPLICAS_HAVE,struct cache_sb, flags, 40, 44);
@@ -768,9 +772,9 @@ enum bch_str_hash_type {
#define BCH_STR_HASH_NR 4
-LE64_BITMASK(CACHE_DATA_PREFERRED_CSUM_TYPE, struct cache_sb, flags, 48, 52);
+LE64_BITMASK(CACHE_SET_DATA_PREFERRED_CSUM_TYPE, struct cache_sb, flags, 48, 52);
-LE64_BITMASK(CACHE_COMPRESSION_TYPE, struct cache_sb, flags, 52, 56);
+LE64_BITMASK(CACHE_SET_COMPRESSION_TYPE, struct cache_sb, flags, 52, 56);
enum {
BCH_COMPRESSION_NONE = 0,
BCH_COMPRESSION_LZ4 = 1,
@@ -782,6 +786,10 @@ enum {
/* Limit inode numbers to 32 bits: */
LE64_BITMASK(CACHE_INODE_32BIT, struct cache_sb, flags, 56, 57);
+LE64_BITMASK(CACHE_SET_GC_RESERVE, struct cache_sb, flags, 57, 63);
+
+LE64_BITMASK(CACHE_SET_ROOT_RESERVE, struct cache_sb, flags2, 0, 6);
+
/* options: */
/**
@@ -807,7 +815,7 @@ LE64_BITMASK(CACHE_INODE_32BIT, struct cache_sb, flags, 56, 57);
CACHE_SET_OPT(errors, \
bch_error_actions, \
0, BCH_NR_ERROR_ACTIONS, \
- CACHE_ERROR_ACTION, \
+ CACHE_SET_ERROR_ACTION, \
true) \
CACHE_SET_OPT(metadata_replicas, \
bch_uint_opt, \
@@ -822,17 +830,17 @@ LE64_BITMASK(CACHE_INODE_32BIT, struct cache_sb, flags, 56, 57);
CACHE_SET_OPT(metadata_checksum, \
bch_csum_types, \
0, BCH_CSUM_NR, \
- CACHE_META_PREFERRED_CSUM_TYPE, \
+ CACHE_SET_META_PREFERRED_CSUM_TYPE, \
true) \
CACHE_SET_OPT(data_checksum, \
bch_csum_types, \
0, BCH_CSUM_NR, \
- CACHE_DATA_PREFERRED_CSUM_TYPE, \
+ CACHE_SET_DATA_PREFERRED_CSUM_TYPE, \
true) \
CACHE_SET_OPT(compression, \
bch_compression_types, \
0, BCH_COMPRESSION_NR, \
- CACHE_COMPRESSION_TYPE, \
+ CACHE_SET_COMPRESSION_TYPE, \
true) \
CACHE_SET_OPT(str_hash, \
bch_str_hash_types, \
@@ -843,6 +851,16 @@ LE64_BITMASK(CACHE_INODE_32BIT, struct cache_sb, flags, 56, 57);
bch_bool_opt, 0, 2, \
CACHE_INODE_32BIT, \
true) \
+ CACHE_SET_OPT(gc_reserve_percent, \
+ bch_uint_opt, \
+ 5, 21, \
+ CACHE_SET_GC_RESERVE, \
+ false) \
+ CACHE_SET_OPT(root_reserve_percent, \
+ bch_uint_opt, \
+ 0, 21, \
+ CACHE_SET_ROOT_RESERVE, \
+ false)
/* backing device specific stuff: */