summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-01-11 20:01:31 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2016-10-07 12:35:18 -0800
commit81cab3bb9f95290dcea18b583a2f707e76133516 (patch)
tree6f36ecb0aa909fdf7bba73e30929933a5955534d
parent0139a886248d71d2f0b58871fe18d277d5bf8a25 (diff)
bcache: Drop ca->sb
Refactoring to make it possible to check endianness correctness with sparse: currently, we're storing the various fields in struct cache_sb in both little endian and native endianness - after this patch, the fields in cache_sb are always in little endian.
-rw-r--r--drivers/md/bcache/bcache.h4
-rw-r--r--drivers/md/bcache/btree_gc.c2
-rw-r--r--drivers/md/bcache/journal.c22
-rw-r--r--drivers/md/bcache/journal.h2
-rw-r--r--drivers/md/bcache/movinggc.c2
-rw-r--r--drivers/md/bcache/notify.c2
-rw-r--r--drivers/md/bcache/super.c273
-rw-r--r--drivers/md/bcache/sysfs.c7
-rw-r--r--include/trace/events/bcache.h12
-rw-r--r--include/uapi/linux/bcache.h2
10 files changed, 146 insertions, 182 deletions
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index 297f57ed952c..8469b4bde672 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -318,7 +318,6 @@ struct cache {
unsigned long flags;
struct cache_set *set;
- struct cache_sb sb;
struct cache_group self;
@@ -326,6 +325,9 @@ struct cache {
* Cached version of this device's member info from superblock
* Committed by write_super()
*/
+ struct {
+ u8 nr_this_dev;
+ } sb;
struct cache_member mi;
struct bcache_superblock disk_sb;
diff --git a/drivers/md/bcache/btree_gc.c b/drivers/md/bcache/btree_gc.c
index 3fda4b5cf434..4eae4e2ade74 100644
--- a/drivers/md/bcache/btree_gc.c
+++ b/drivers/md/bcache/btree_gc.c
@@ -303,7 +303,7 @@ static void bch_mark_metadata(struct cache_set *c)
unsigned j;
u64 *i;
- for (j = 0; j < bch_nr_journal_buckets(&ca->sb); j++)
+ for (j = 0; j < bch_nr_journal_buckets(ca->disk_sb.sb); j++)
bch_mark_metadata_bucket(ca,
&ca->buckets[journal_bucket(ca, j)],
true);
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 1fc270c81872..41f9a70f2a7c 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -484,9 +484,9 @@ reread:
blocks = set_blocks(j, block_bytes(c));
pr_debug("next");
- bucket_offset += blocks * ca->sb.block_size;
- sectors_read -= blocks * ca->sb.block_size;
- j = ((void *) j) + blocks * block_bytes(ca);
+ bucket_offset += blocks * c->sb.block_size;
+ sectors_read -= blocks * c->sb.block_size;
+ j = ((void *) j) + blocks * block_bytes(c);
}
}
out:
@@ -522,7 +522,7 @@ static void bch_journal_read_device(struct closure *cl)
container_of(cl->parent, struct journal_list, cl);
struct request_queue *q = bdev_get_queue(ca->disk_sb.bdev);
- unsigned nr_buckets = bch_nr_journal_buckets(&ca->sb);
+ unsigned nr_buckets = bch_nr_journal_buckets(ca->disk_sb.sb);
DECLARE_BITMAP(bitmap, nr_buckets);
unsigned i, l, r;
u64 seq = 0;
@@ -1021,7 +1021,7 @@ err:
static int bch_set_nr_journal_buckets(struct cache *ca, unsigned nr)
{
- unsigned u64s = bch_journal_buckets_offset(&ca->sb) + nr;
+ unsigned u64s = bch_journal_buckets_offset(ca->disk_sb.sb) + nr;
u64 *p;
int ret;
@@ -1036,7 +1036,7 @@ static int bch_set_nr_journal_buckets(struct cache *ca, unsigned nr)
return -ENOMEM;
ca->journal.bucket_seq = p;
- ca->sb.u64s = u64s;
+ ca->disk_sb.sb->u64s = cpu_to_le16(u64s);
return 0;
}
@@ -1060,7 +1060,7 @@ int bch_cache_journal_alloc(struct cache *ca)
if (ret)
return ret;
- for (i = 0; i < bch_nr_journal_buckets(&ca->sb); i++) {
+ for (i = 0; i < bch_nr_journal_buckets(ca->disk_sb.sb); i++) {
unsigned long r = ca->mi.first_bucket + i;
bch_mark_metadata_bucket(ca, &ca->buckets[r], true);
@@ -1130,7 +1130,7 @@ static void journal_reclaim_work(struct work_struct *work)
*/
group_for_each_cache(ca, &c->cache_tiers[0], iter) {
struct journal_device *ja = &ca->journal;
- unsigned nr = bch_nr_journal_buckets(&ca->sb),
+ unsigned nr = bch_nr_journal_buckets(ca->disk_sb.sb),
cur_idx, bucket_to_flush;
spin_lock(&j->lock);
@@ -1251,7 +1251,7 @@ static void journal_next_bucket(struct cache_set *c)
group_for_each_cache_rcu(ca, &c->cache_tiers[0], iter) {
struct journal_device *ja = &ca->journal;
unsigned next, remaining, nr_buckets =
- bch_nr_journal_buckets(&ca->sb);
+ bch_nr_journal_buckets(ca->disk_sb.sb);
if (replicas >= c->opts.metadata_replicas)
break;
@@ -2029,7 +2029,7 @@ ssize_t bch_journal_print_debug(struct journal *j, char *buf)
"\tnr\t\t%u\n"
"\tcur_idx\t\t%u (seq %llu)\n"
"\tlast_idx\t%u (seq %llu)\n",
- iter, bch_nr_journal_buckets(&ca->sb),
+ iter, bch_nr_journal_buckets(ca->disk_sb.sb),
ja->cur_idx, ja->bucket_seq[ja->cur_idx],
ja->last_idx, ja->bucket_seq[ja->last_idx]);
}
@@ -2107,7 +2107,7 @@ int bch_journal_move(struct cache *ca)
last_flushed_seq = last_seq(j);
spin_unlock(&j->lock);
- nr_buckets = bch_nr_journal_buckets(&ca->sb);
+ nr_buckets = bch_nr_journal_buckets(ca->disk_sb.sb);
for (i = 0; i < nr_buckets; i += 1)
BUG_ON(ca->journal.bucket_seq[i] > last_flushed_seq);
diff --git a/drivers/md/bcache/journal.h b/drivers/md/bcache/journal.h
index 70174232a6b7..1b960b0bddf4 100644
--- a/drivers/md/bcache/journal.h
+++ b/drivers/md/bcache/journal.h
@@ -252,7 +252,7 @@ int bch_cache_journal_alloc(struct cache *);
static inline u64 *__journal_buckets(struct cache *ca)
{
- return ca->disk_sb.sb->_data + bch_journal_buckets_offset(&ca->sb);
+ return ca->disk_sb.sb->_data + bch_journal_buckets_offset(ca->disk_sb.sb);
}
static inline u64 journal_bucket(struct cache *ca, unsigned nr)
diff --git a/drivers/md/bcache/movinggc.c b/drivers/md/bcache/movinggc.c
index 7eb3af4aa385..7e4d9b354fc4 100644
--- a/drivers/md/bcache/movinggc.c
+++ b/drivers/md/bcache/movinggc.c
@@ -171,7 +171,7 @@ static bool bch_moving_gc(struct cache *ca)
(fifo_used(&ca->free[RESERVE_MOVINGGC]) - NUM_GC_GENS);
spin_unlock(&ca->freelist_lock);
- if (reserve_sectors < (int) ca->sb.block_size) {
+ if (reserve_sectors < (int) c->sb.block_size) {
trace_bcache_moving_gc_reserve_empty(ca);
return false;
}
diff --git a/drivers/md/bcache/notify.c b/drivers/md/bcache/notify.c
index ee194a59b547..17180f9af486 100644
--- a/drivers/md/bcache/notify.c
+++ b/drivers/md/bcache/notify.c
@@ -34,7 +34,7 @@ static void notify_get_cache(struct cache *ca)
char buf[BDEVNAME_SIZE];
notify_get(c);
- notify_var(c, "UUID=%pU", ca->sb.disk_uuid.b);
+ notify_var(c, "UUID=%pU", ca->disk_sb.sb->disk_uuid.b);
notify_var(c, "BLOCKDEV=%s", bdevname(ca->disk_sb.bdev, buf));
}
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index cd35f072ea29..1e7a67d22e8a 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -185,114 +185,108 @@ static int bch_congested_fn(void *data, int bdi_bits)
/* Superblock */
-static const char *validate_cache_member(struct cache_sb *sb,
- struct cache_member *mi)
+static const char *validate_cache_super(struct cache_set *c, struct cache *ca)
{
- if (mi->nbuckets > LONG_MAX)
- return "Too many buckets";
+ struct cache_sb *sb = ca->disk_sb.sb;
+ u16 block_size;
+ unsigned i;
- if (mi->nbuckets < 1 << 8)
- return "Not enough buckets";
+ switch (sb->version) {
+ case BCACHE_SB_VERSION_CDEV_V0:
+ case BCACHE_SB_VERSION_CDEV_WITH_UUID:
+ case BCACHE_SB_VERSION_CDEV_V2:
+ case BCACHE_SB_VERSION_CDEV_V3:
+ break;
+ default:
+ return"Unsupported superblock version";
+ }
- if (!is_power_of_2(mi->bucket_size) ||
- mi->bucket_size < PAGE_SECTORS ||
- mi->bucket_size < sb->block_size)
- return "Bad bucket size";
+ if (CACHE_SYNC(sb) &&
+ sb->version != BCACHE_SB_VERSION_CDEV_V3)
+ return "Unsupported superblock version";
- return NULL;
-}
+ block_size = le16_to_cpu(sb->block_size);
-static const char *validate_super(struct bcache_superblock *disk_sb,
- struct cache_sb *sb)
-{
- const char *err;
- struct cache_sb *s = disk_sb->sb;
+ if (!is_power_of_2(block_size) ||
+ block_size > PAGE_SECTORS)
+ return "Bad block size";
- sb->offset = le64_to_cpu(s->offset);
- sb->version = le64_to_cpu(s->version);
- sb->seq = le64_to_cpu(s->seq);
+ if (bch_is_zero(sb->disk_uuid.b, sizeof(uuid_le)))
+ return "Bad disk UUID";
- sb->magic = s->magic;
- sb->disk_uuid = s->disk_uuid;
- sb->user_uuid = s->user_uuid;
- sb->set_uuid = s->set_uuid;
- memcpy(sb->label, s->label, SB_LABEL_SIZE);
+ if (bch_is_zero(sb->user_uuid.b, sizeof(uuid_le)))
+ return "Bad user UUID";
- sb->flags = le64_to_cpu(s->flags);
- sb->block_size = le16_to_cpu(s->block_size);
- sb->u64s = le16_to_cpu(s->u64s);
+ if (bch_is_zero(sb->set_uuid.b, sizeof(uuid_le)))
+ return "Bad set UUID";
- switch (sb->version) {
- case BCACHE_SB_VERSION_CDEV_V0:
- case BCACHE_SB_VERSION_CDEV_WITH_UUID:
- case BCACHE_SB_VERSION_CDEV_V2:
- case BCACHE_SB_VERSION_CDEV_V3:
- sb->nr_in_set = le16_to_cpu(s->nr_in_set);
- sb->nr_this_dev = le16_to_cpu(s->nr_this_dev);
+ if (!sb->nr_in_set ||
+ sb->nr_in_set <= sb->nr_this_dev ||
+ sb->nr_in_set > MAX_CACHES_PER_SET)
+ return "Bad cache device number in set";
- if (CACHE_SYNC(sb) &&
- sb->version != BCACHE_SB_VERSION_CDEV_V3)
- return "Unsupported superblock version";
+ if (!CACHE_SET_META_REPLICAS_WANT(sb) ||
+ CACHE_SET_META_REPLICAS_WANT(sb) >= BCH_REPLICAS_MAX)
+ return "Invalid number of metadata replicas";
- if (!is_power_of_2(sb->block_size) ||
- sb->block_size > PAGE_SECTORS)
- return "Bad block size";
+ if (!CACHE_SET_META_REPLICAS_HAVE(sb) ||
+ CACHE_SET_META_REPLICAS_HAVE(sb) >
+ CACHE_SET_META_REPLICAS_WANT(sb))
+ return "Invalid number of metadata replicas";
- if (bch_is_zero(sb->disk_uuid.b, sizeof(uuid_le)))
- return "Bad disk UUID";
+ if (!CACHE_SET_DATA_REPLICAS_WANT(sb) ||
+ CACHE_SET_DATA_REPLICAS_WANT(sb) >= BCH_REPLICAS_MAX)
+ return "Invalid number of data replicas";
- if (bch_is_zero(sb->user_uuid.b, sizeof(uuid_le)))
- return "Bad user UUID";
+ if (!CACHE_SET_DATA_REPLICAS_HAVE(sb) ||
+ CACHE_SET_DATA_REPLICAS_HAVE(sb) >
+ CACHE_SET_DATA_REPLICAS_WANT(sb))
+ return "Invalid number of data replicas";
- if (bch_is_zero(sb->set_uuid.b, sizeof(uuid_le)))
- return "Bad set UUID";
+ if (CACHE_SB_CSUM_TYPE(sb) >= BCH_CSUM_NR)
+ return "Invalid checksum type";
- if (!sb->nr_in_set ||
- sb->nr_in_set <= sb->nr_this_dev ||
- sb->nr_in_set > MAX_CACHES_PER_SET)
- return "Bad cache device number in set";
+ if (!CACHE_BTREE_NODE_SIZE(sb))
+ return "Btree node size not set";
- if (!CACHE_SET_META_REPLICAS_WANT(sb) ||
- CACHE_SET_META_REPLICAS_WANT(sb) >= BCH_REPLICAS_MAX)
- return "Invalid number of metadata replicas";
+ if (!is_power_of_2(CACHE_BTREE_NODE_SIZE(sb)))
+ return "Btree node size not a power of two";
- if (!CACHE_SET_META_REPLICAS_HAVE(sb) ||
- CACHE_SET_META_REPLICAS_HAVE(sb) >
- CACHE_SET_META_REPLICAS_WANT(sb))
- return "Invalid number of metadata replicas";
+ if (CACHE_BTREE_NODE_SIZE(sb) > BTREE_NODE_SIZE_MAX)
+ return "Btree node size too large";
- if (!CACHE_SET_DATA_REPLICAS_WANT(sb) ||
- CACHE_SET_DATA_REPLICAS_WANT(sb) >= BCH_REPLICAS_MAX)
- return "Invalid number of data replicas";
+ if (le16_to_cpu(sb->u64s) < bch_journal_buckets_offset(sb))
+ return "Invalid superblock: member info area missing";
- if (!CACHE_SET_DATA_REPLICAS_HAVE(sb) ||
- CACHE_SET_DATA_REPLICAS_HAVE(sb) >
- CACHE_SET_DATA_REPLICAS_WANT(sb))
- return "Invalid number of data replicas";
+ ca->mi = sb->members[sb->nr_this_dev];
- if (CACHE_SB_CSUM_TYPE(sb) >= BCH_CSUM_NR)
- return "Invalid checksum type";
+ if (ca->mi.nbuckets > LONG_MAX)
+ return "Too many buckets";
- if (!CACHE_BTREE_NODE_SIZE(sb))
- return "Btree node size not set";
+ if (ca->mi.nbuckets < 1 << 8)
+ return "Not enough buckets";
- if (!is_power_of_2(CACHE_BTREE_NODE_SIZE(sb)))
- return "Btree node size not a power of two";
+ if (!is_power_of_2(ca->mi.bucket_size) ||
+ ca->mi.bucket_size < PAGE_SECTORS ||
+ ca->mi.bucket_size < sb->block_size)
+ return "Bad bucket size";
- if (CACHE_BTREE_NODE_SIZE(sb) > BTREE_NODE_SIZE_MAX)
- return "Btree node size too large";
+ ca->bucket_bits = ilog2(ca->mi.bucket_size);
- if (sb->u64s < bch_journal_buckets_offset(sb))
- return "Invalid superblock: member info area missing";
+ if (get_capacity(ca->disk_sb.bdev->bd_disk) <
+ ca->mi.bucket_size * ca->mi.nbuckets)
+ return "Invalid superblock: device too small";
- if ((err = validate_cache_member(sb, s->members +
- sb->nr_this_dev)))
- return err;
+ if (le64_to_cpu(sb->offset) +
+ (__set_blocks(sb, le16_to_cpu(sb->u64s),
+ block_bytes(c)) << c->block_bits) >
+ ca->mi.first_bucket << ca->bucket_bits)
+ return "Invalid superblock: first bucket comes before end of super";
- break;
- default:
- return"Unsupported superblock version";
- }
+ for (i = 0; i < bch_nr_journal_buckets(sb); i++)
+ if (journal_bucket(ca, i) < ca->mi.first_bucket ||
+ journal_bucket(ca, i) >= ca->mi.nbuckets)
+ return "bad journal bucket";
return NULL;
}
@@ -472,10 +466,11 @@ static void bcache_write_super_unlock(struct closure *cl)
up(&c->sb_write_mutex);
}
-static int cache_sb_to_cache_set(struct cache_set *c, struct cache_sb *sb)
+static int cache_sb_to_cache_set(struct cache_set *c, struct cache_sb *src)
{
struct cache_member_rcu *new, *old;
- unsigned nr_in_set = le16_to_cpu(sb->nr_in_set);
+ struct cache_sb *dst = &c->sb;
+ unsigned nr_in_set = le16_to_cpu(src->nr_in_set);
new = kzalloc(sizeof(struct cache_member_rcu) +
sizeof(struct cache_member) * nr_in_set,
@@ -484,7 +479,7 @@ static int cache_sb_to_cache_set(struct cache_set *c, struct cache_sb *sb)
return -ENOMEM;
new->nr_in_set = nr_in_set;
- memcpy(&new->m, sb->members,
+ memcpy(&new->m, src->members,
nr_in_set * sizeof(new->m[0]));
old = rcu_dereference_protected(c->members,
@@ -494,38 +489,43 @@ static int cache_sb_to_cache_set(struct cache_set *c, struct cache_sb *sb)
if (old)
kfree_rcu(old, rcu);
- c->sb.version = le64_to_cpu(sb->version);
- c->sb.seq = le64_to_cpu(sb->seq);
- c->sb.user_uuid = sb->user_uuid;
- c->sb.set_uuid = sb->set_uuid;
- memcpy(c->sb.label, sb->label, SB_LABEL_SIZE);
- c->sb.nr_in_set = le16_to_cpu(sb->nr_in_set);
- c->sb.flags = le64_to_cpu(sb->flags);
- c->sb.block_size = le16_to_cpu(sb->block_size);
+ dst->version = src->version;
+ dst->seq = src->seq;
+ dst->user_uuid = src->user_uuid;
+ dst->set_uuid = src->set_uuid;
+ memcpy(dst->label, src->label, SB_LABEL_SIZE);
+ dst->nr_in_set = src->nr_in_set;
+ dst->flags = src->flags;
+ dst->block_size = src->block_size;
- pr_debug("set version = %llu", c->sb.version);
+ pr_debug("set version = %llu", le64_to_cpu(c->sb.version));
return 0;
}
static int cache_sb_from_cache_set(struct cache_set *c, struct cache *ca)
{
+ struct cache_sb *src = &c->sb, *dst = ca->disk_sb.sb;
struct cache_member_rcu *mi;
- if (ca->sb.nr_in_set != c->sb.nr_in_set) {
- unsigned old_offset = bch_journal_buckets_offset(&ca->sb);
- unsigned u64s = bch_journal_buckets_offset(&c->sb)
- + bch_nr_journal_buckets(&ca->sb);
+ if (src->nr_in_set != dst->nr_in_set) {
+ /*
+ * We have to preserve the list of journal buckets on the
+ * cache's superblock:
+ */
+ unsigned old_offset = bch_journal_buckets_offset(dst);
+ unsigned u64s = bch_journal_buckets_offset(src)
+ + bch_nr_journal_buckets(dst);
int ret = bch_super_realloc(&ca->disk_sb, u64s);
if (ret)
return ret;
- ca->sb.nr_in_set = c->sb.nr_in_set;
- ca->sb.u64s = u64s;
+ dst->nr_in_set = src->nr_in_set;
+ dst->u64s = cpu_to_le16(u64s);
- memmove(__journal_buckets(ca),
- ca->disk_sb.sb->_data + old_offset,
- bch_nr_journal_buckets(&ca->sb) * sizeof(u64));
+ memmove(dst->_data + bch_journal_buckets_offset(dst),
+ dst->_data + old_offset,
+ bch_nr_journal_buckets(dst) * sizeof(u64));
}
mi = cache_member_info_get(c);
@@ -535,13 +535,13 @@ static int cache_sb_from_cache_set(struct cache_set *c, struct cache *ca)
mi->nr_in_set * sizeof(mi->m[0]));
cache_member_info_put();
- ca->sb.version = BCACHE_SB_VERSION_CDEV;
- ca->sb.seq = c->sb.seq;
- ca->sb.user_uuid = c->sb.user_uuid;
- ca->sb.set_uuid = c->sb.set_uuid;
- memcpy(ca->sb.label, c->sb.label, SB_LABEL_SIZE);
- ca->sb.nr_in_set = c->sb.nr_in_set;
- ca->sb.flags = c->sb.flags;
+ dst->version = BCACHE_SB_VERSION_CDEV;
+ dst->seq = src->seq;
+ dst->user_uuid = src->user_uuid;
+ dst->set_uuid = src->set_uuid;
+ memcpy(dst->label, src->label, SB_LABEL_SIZE);
+ dst->nr_in_set = src->nr_in_set;
+ dst->flags = src->flags;
return 0;
}
@@ -557,29 +557,13 @@ static void __bcache_write_super(struct cache_set *c)
c->sb.seq++;
for_each_cache(ca, c, i) {
- struct cache_sb *sb = &ca->sb, *out = ca->disk_sb.sb;
+ struct cache_sb *sb = ca->disk_sb.sb;
struct bio *bio = ca->disk_sb.bio;
cache_sb_from_cache_set(c, ca);
- SET_CACHE_SB_CSUM_TYPE(&ca->sb, c->opts.metadata_checksum);
-
- out->offset = cpu_to_le64(sb->offset);
- out->version = cpu_to_le64(sb->version);
- out->seq = cpu_to_le64(sb->seq);
-
- out->disk_uuid = sb->disk_uuid;
- out->user_uuid = sb->user_uuid;
- out->set_uuid = sb->set_uuid;
- memcpy(out->label, sb->label, SB_LABEL_SIZE);
-
- out->nr_in_set = cpu_to_le16(sb->nr_in_set);
- out->nr_this_dev = cpu_to_le16(sb->nr_this_dev);
-
- out->flags = cpu_to_le64(sb->flags);
- out->u64s = cpu_to_le16(sb->u64s);
-
- out->csum = csum_set(out, CACHE_SB_CSUM_TYPE(sb));
+ SET_CACHE_SB_CSUM_TYPE(sb, c->opts.metadata_checksum);
+ sb->csum = cpu_to_le64(csum_set(sb, CACHE_SB_CSUM_TYPE(sb)));
bio_reset(bio);
bio->bi_bdev = ca->disk_sb.bdev;
@@ -1816,7 +1800,6 @@ static const char *cache_alloc(struct bcache_superblock *sb,
struct cache_set *c,
struct cache **ret)
{
- struct cache_member_rcu *mi;
size_t reserve_none, movinggc_reserve, free_inc_reserve, total_reserve;
size_t heap_size;
unsigned i;
@@ -1841,6 +1824,7 @@ static const char *cache_alloc(struct bcache_superblock *sb,
seqcount_init(&ca->self.lock);
ca->self.nr_devices = 1;
rcu_assign_pointer(ca->self.devices[0], ca);
+ ca->sb.nr_this_dev = sb->sb->nr_this_dev;
INIT_WORK(&ca->free_work, bch_cache_free_work);
INIT_WORK(&ca->remove_work, bch_cache_remove_work);
@@ -1861,33 +1845,10 @@ static const char *cache_alloc(struct bcache_superblock *sb,
if (cache_set_init_fault("cache_alloc"))
goto err;
- err = validate_super(&ca->disk_sb, &ca->sb);
+ err = validate_cache_super(c, ca);
if (err)
goto err;
- mi = cache_member_info_get(c);
- ca->mi = mi->m[ca->sb.nr_this_dev];
- cache_member_info_put();
-
- ca->bucket_bits = ilog2(ca->mi.bucket_size);
-
- err = "Invalid superblock: device too small";
- if (get_capacity(ca->disk_sb.bdev->bd_disk) <
- ca->mi.bucket_size * ca->mi.nbuckets)
- goto err;
-
- err = "Invalid superblock: first bucket comes before end of super";
- if (ca->sb.offset +
- (set_blocks(&ca->sb, block_bytes(c)) << c->block_bits) >
- ca->mi.first_bucket << ca->bucket_bits)
- goto err;
-
- err = "bad journal bucket";
- for (i = 0; i < bch_nr_journal_buckets(&ca->sb); i++)
- if (journal_bucket(ca, i) < ca->mi.first_bucket ||
- journal_bucket(ca, i) >= ca->mi.nbuckets)
- goto err;
-
/* XXX: tune these */
movinggc_reserve = max_t(size_t, NUM_GC_GENS * 2,
ca->mi.nbuckets >> 7);
@@ -1910,7 +1871,7 @@ static const char *cache_alloc(struct bcache_superblock *sb,
2, GFP_KERNEL)) ||
!(ca->disk_buckets = alloc_bucket_pages(GFP_KERNEL, ca)) ||
!(ca->bucket_stats_percpu = alloc_percpu(struct bucket_stats)) ||
- !(ca->journal.bucket_seq = kcalloc(bch_nr_journal_buckets(&ca->sb),
+ !(ca->journal.bucket_seq = kcalloc(bch_nr_journal_buckets(ca->disk_sb.sb),
sizeof(u64), GFP_KERNEL)) ||
!(ca->bio_prio = bio_kmalloc(GFP_NOIO, bucket_pages(ca))) ||
bioset_init(&ca->replica_set, 4,
@@ -1943,7 +1904,7 @@ static const char *cache_alloc(struct bcache_superblock *sb,
bch_moving_init_cache(ca);
bch_tiering_init_cache(ca);
- if (ca->sb.seq > c->sb.seq)
+ if (le64_to_cpu(ca->disk_sb.sb->seq) > le64_to_cpu(c->sb.seq))
cache_sb_to_cache_set(c, ca->disk_sb.sb);
err = "error creating kobject";
diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c
index 202d6bb64d56..c9a9a86d98b8 100644
--- a/drivers/md/bcache/sysfs.c
+++ b/drivers/md/bcache/sysfs.c
@@ -1159,14 +1159,15 @@ static ssize_t show_cache_alloc_debug(struct cache *ca, char *buf)
SHOW(bch_cache)
{
struct cache *ca = container_of(kobj, struct cache, kobj);
+ struct cache_set *c = ca->set;
struct bucket_stats stats = bch_bucket_stats_read(ca);
- sysfs_printf(uuid, "%pU\n", ca->sb.disk_uuid.b);
+ sysfs_printf(uuid, "%pU\n", ca->disk_sb.sb->disk_uuid.b);
sysfs_hprint(bucket_size, bucket_bytes(ca));
sysfs_print(bucket_size_bytes, bucket_bytes(ca));
- sysfs_hprint(block_size, block_bytes(ca));
- sysfs_print(block_size_bytes, block_bytes(ca));
+ sysfs_hprint(block_size, block_bytes(c));
+ sysfs_print(block_size_bytes, block_bytes(c));
sysfs_print(first_bucket, ca->mi.first_bucket);
sysfs_print(nbuckets, ca->mi.nbuckets);
sysfs_print(discard, CACHE_DISCARD(&ca->mi));
diff --git a/include/trace/events/bcache.h b/include/trace/events/bcache.h
index 5ab862b002dc..fc2be7639032 100644
--- a/include/trace/events/bcache.h
+++ b/include/trace/events/bcache.h
@@ -290,7 +290,7 @@ TRACE_EVENT(bcache_journal_next_bucket,
),
TP_fast_assign(
- memcpy(__entry->uuid, ca->sb.disk_uuid.b, 16);
+ memcpy(__entry->uuid, ca->disk_sb.sb->disk_uuid.b, 16);
__entry->cur_idx = cur_idx;
__entry->last_idx = last_idx;
),
@@ -373,7 +373,7 @@ DECLARE_EVENT_CLASS(cache,
),
TP_fast_assign(
- memcpy(__entry->uuid, ca->sb.disk_uuid.b, 16);
+ memcpy(__entry->uuid, ca->disk_sb.sb->disk_uuid.b, 16);
__entry->tier = CACHE_TIER(&ca->mi);
),
@@ -829,7 +829,7 @@ TRACE_EVENT(bcache_mark_bucket,
),
TP_fast_assign(
- memcpy(__entry->uuid, ca->sb.disk_uuid.b, 16);
+ memcpy(__entry->uuid, ca->disk_sb.sb->disk_uuid.b, 16);
__entry->inode = k->p.inode;
__entry->offset = k->p.offset;
__entry->sectors = sectors;
@@ -855,7 +855,7 @@ TRACE_EVENT(bcache_alloc_batch,
),
TP_fast_assign(
- memcpy(__entry->uuid, ca->sb.disk_uuid.b, 16);
+ memcpy(__entry->uuid, ca->disk_sb.sb->disk_uuid.b, 16);
__entry->free = free;
__entry->total = total;
),
@@ -930,7 +930,7 @@ DECLARE_EVENT_CLASS(cache_bucket_alloc,
),
TP_fast_assign(
- memcpy(__entry->uuid, ca->sb.disk_uuid.b, 16);
+ memcpy(__entry->uuid, ca->disk_sb.sb->disk_uuid.b, 16);
__entry->reserve = reserve;
),
@@ -1153,7 +1153,7 @@ TRACE_EVENT(bcache_moving_gc_end,
),
TP_fast_assign(
- memcpy(__entry->uuid, ca->sb.disk_uuid.b, 16);
+ memcpy(__entry->uuid, ca->disk_sb.sb->disk_uuid.b, 16);
__entry->sectors_moved = sectors_moved;
__entry->keys_moved = keys_moved;
__entry->buckets_moved = buckets_moved;
diff --git a/include/uapi/linux/bcache.h b/include/uapi/linux/bcache.h
index 0996ce289bc0..d06fdeb8900c 100644
--- a/include/uapi/linux/bcache.h
+++ b/include/uapi/linux/bcache.h
@@ -814,7 +814,7 @@ static inline unsigned bch_journal_buckets_offset(struct cache_sb *sb)
static inline unsigned bch_nr_journal_buckets(struct cache_sb *sb)
{
- return sb->u64s - bch_journal_buckets_offset(sb);
+ return le16_to_cpu(sb->u64s) - bch_journal_buckets_offset(sb);
}
static inline _Bool __SB_IS_BDEV(__u64 version)