summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2016-01-11 19:39:35 -0900
committerKent Overstreet <kent.overstreet@gmail.com>2016-10-07 12:35:18 -0800
commit0139a886248d71d2f0b58871fe18d277d5bf8a25 (patch)
tree838dbb2a35e1ff484081f378caf677465bda464f
parent95b4e5d76753b4ace59bf118ece188bf1696a467 (diff)
bcache: split off backingdev_sb
The superblock formats are diverging too much
-rw-r--r--drivers/md/bcache/blockdev.c62
-rw-r--r--drivers/md/bcache/blockdev_types.h2
-rw-r--r--drivers/md/bcache/request.c2
-rw-r--r--drivers/md/bcache/super.c74
-rw-r--r--drivers/md/bcache/super.h5
-rw-r--r--include/uapi/linux/bcache.h81
6 files changed, 146 insertions, 80 deletions
diff --git a/drivers/md/bcache/blockdev.c b/drivers/md/bcache/blockdev.c
index 178eb1f04a3b..d0666bafa943 100644
--- a/drivers/md/bcache/blockdev.c
+++ b/drivers/md/bcache/blockdev.c
@@ -34,6 +34,7 @@ static void bch_write_bdev_super_unlock(struct closure *cl)
void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent)
{
+ struct backingdev_sb *sb = &dc->sb, *out = (void *) dc->disk_sb.sb;
struct closure *cl = &dc->sb_write;
struct bio *bio = dc->disk_sb.bio;
@@ -45,7 +46,23 @@ void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent)
bio->bi_private = dc;
closure_get(cl);
- __write_super(dc->disk.c, &dc->disk_sb, &dc->sb);
+
+ 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->data_offset = cpu_to_le64(sb->data_offset);
+ out->last_mount = cpu_to_le32(sb->last_mount);
+
+ out->flags = cpu_to_le64(sb->flags);
+ out->u64s = cpu_to_le16(sb->u64s);
+ out->csum = csum_set(out, BCH_CSUM_CRC64);
+ __write_super(dc->disk.c, &dc->disk_sb);
closure_return_with_destructor(cl, bch_write_bdev_super_unlock);
}
@@ -549,7 +566,7 @@ static int cached_dev_init(struct cached_dev *dc, unsigned block_size)
ret = bcache_device_init(&dc->disk, block_size,
dc->disk_sb.bdev->bd_part->nr_sects -
- dc->sb.bdev_data_offset);
+ dc->sb.data_offset);
if (ret)
return ret;
@@ -567,6 +584,45 @@ static int cached_dev_init(struct cached_dev *dc, unsigned block_size)
/* Cached device - bcache superblock */
+static const char *bdev_validate_super(struct bcache_superblock *disk_sb,
+ struct backingdev_sb *sb)
+{
+ struct backingdev_sb *s = (void *) disk_sb->sb;
+
+ sb->offset = le64_to_cpu(s->offset);
+ sb->version = le64_to_cpu(s->version);
+ sb->seq = le64_to_cpu(s->seq);
+
+ 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);
+
+ sb->flags = le64_to_cpu(s->flags);
+ sb->block_size = le16_to_cpu(s->block_size);
+ sb->u64s = le16_to_cpu(s->u64s);
+
+ switch (sb->version) {
+ case BCACHE_SB_VERSION_BDEV:
+ sb->data_offset = BDEV_DATA_START_DEFAULT;
+ break;
+ case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
+ sb->data_offset = le64_to_cpu(s->data_offset);
+
+ if (sb->data_offset < BDEV_DATA_START_DEFAULT)
+ return "Bad data offset";
+
+ break;
+ default:
+ return"Unsupported superblock version";
+ }
+
+ sb->last_mount = get_seconds();
+
+ return NULL;
+}
+
const char *bch_backing_dev_register(struct bcache_superblock *sb)
{
char name[BDEVNAME_SIZE];
@@ -593,7 +649,7 @@ const char *bch_backing_dev_register(struct bcache_superblock *sb)
dc->disk_sb.bdev->bd_holder = dc;
memset(sb, 0, sizeof(*sb));
- err = validate_super(&dc->disk_sb, &dc->sb);
+ err = bdev_validate_super(&dc->disk_sb, &dc->sb);
if (err)
goto err;
diff --git a/drivers/md/bcache/blockdev_types.h b/drivers/md/bcache/blockdev_types.h
index da997046e937..072519103e7c 100644
--- a/drivers/md/bcache/blockdev_types.h
+++ b/drivers/md/bcache/blockdev_types.h
@@ -53,7 +53,7 @@ struct cached_dev {
struct list_head list;
struct bcache_device disk;
- struct cache_sb sb;
+ struct backingdev_sb sb;
struct bcache_superblock disk_sb;
struct closure sb_write;
struct semaphore sb_write_mutex;
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 3d13be017275..df87500b737b 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -576,7 +576,7 @@ static void __cached_dev_make_request(struct request_queue *q, struct bio *bio)
generic_start_io_acct(rw, bio_sectors(bio), &d->disk->part0);
bio->bi_bdev = dc->disk_sb.bdev;
- bio->bi_iter.bi_sector += dc->sb.bdev_data_offset;
+ bio->bi_iter.bi_sector += dc->sb.data_offset;
if (cached_dev_get(dc)) {
s = search_alloc(bio, d);
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 89fa87cb12e0..cd35f072ea29 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -202,8 +202,8 @@ static const char *validate_cache_member(struct cache_sb *sb,
return NULL;
}
-const char *validate_super(struct bcache_superblock *disk_sb,
- struct cache_sb *sb)
+static const char *validate_super(struct bcache_superblock *disk_sb,
+ struct cache_sb *sb)
{
const char *err;
struct cache_sb *s = disk_sb->sb;
@@ -223,21 +223,6 @@ const char *validate_super(struct bcache_superblock *disk_sb,
sb->u64s = le16_to_cpu(s->u64s);
switch (sb->version) {
- case BCACHE_SB_VERSION_BDEV:
- sb->bdev_data_offset = BDEV_DATA_START_DEFAULT;
- sb->bdev_last_mount = le32_to_cpu(s->bdev_last_mount);
- sb->bdev_last_mount = get_seconds();
- break;
- case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
- sb->bdev_data_offset = le64_to_cpu(s->bdev_data_offset);
- sb->bdev_last_mount = le32_to_cpu(s->bdev_last_mount);
- /* hrm. */
- sb->bdev_last_mount = get_seconds();
-
- if (sb->bdev_data_offset < BDEV_DATA_START_DEFAULT)
- return "Bad data offset";
-
- break;
case BCACHE_SB_VERSION_CDEV_V0:
case BCACHE_SB_VERSION_CDEV_WITH_UUID:
case BCACHE_SB_VERSION_CDEV_V2:
@@ -445,10 +430,9 @@ err:
return err;
}
-void __write_super(struct cache_set *c, struct bcache_superblock *disk_sb,
- struct cache_sb *sb)
+void __write_super(struct cache_set *c, struct bcache_superblock *disk_sb)
{
- struct cache_sb *out = disk_sb->sb;
+ struct cache_sb *sb = disk_sb->sb;
struct bio *bio = disk_sb->bio;
bio->bi_bdev = disk_sb->bdev;
@@ -457,34 +441,12 @@ void __write_super(struct cache_set *c, struct bcache_superblock *disk_sb,
roundup(set_bytes(sb),
bdev_logical_block_size(disk_sb->bdev));
bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_SYNC|REQ_META);
- bch_bio_map(bio, out);
-
- 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);
-
- if (__SB_IS_BDEV(sb->version)) {
- out->bdev_data_offset = cpu_to_le64(sb->bdev_data_offset);
- out->bdev_last_mount = cpu_to_le32(sb->bdev_last_mount);
- } else {
- 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, sb->version < BCACHE_SB_VERSION_CDEV_V3
- ? BCH_CSUM_CRC64
- : CACHE_SB_CSUM_TYPE(sb));
+ bch_bio_map(bio, sb);
pr_debug("ver %llu, flags %llu, seq %llu",
- sb->version, sb->flags, sb->seq);
+ le64_to_cpu(sb->version),
+ le64_to_cpu(sb->flags),
+ le64_to_cpu(sb->seq));
bch_generic_make_request(bio, c);
}
@@ -595,12 +557,30 @@ 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 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));
+
bio_reset(bio);
bio->bi_bdev = ca->disk_sb.bdev;
bio->bi_end_io = write_super_endio;
@@ -608,7 +588,7 @@ static void __bcache_write_super(struct cache_set *c)
closure_get(cl);
percpu_ref_get(&ca->ref);
- __write_super(c, &ca->disk_sb, &ca->sb);
+ __write_super(c, &ca->disk_sb);
}
closure_return_with_destructor(cl, bcache_write_super_unlock);
diff --git a/drivers/md/bcache/super.h b/drivers/md/bcache/super.h
index 2654a814391c..a2c9e3d273bb 100644
--- a/drivers/md/bcache/super.h
+++ b/drivers/md/bcache/super.h
@@ -146,10 +146,7 @@ static inline void bch_check_mark_super(struct cache_set *c,
void free_super(struct bcache_superblock *);
int bch_super_realloc(struct bcache_superblock *, unsigned);
void bcache_write_super(struct cache_set *);
-void __write_super(struct cache_set *, struct bcache_superblock *,
- struct cache_sb *);
-
-const char *validate_super(struct bcache_superblock *, struct cache_sb *);
+void __write_super(struct cache_set *, struct bcache_superblock *);
void bch_cache_member_info_update(struct cache *);
diff --git a/include/uapi/linux/bcache.h b/include/uapi/linux/bcache.h
index ed88a0cc7cde..0996ce289bc0 100644
--- a/include/uapi/linux/bcache.h
+++ b/include/uapi/linux/bcache.h
@@ -623,32 +623,21 @@ struct cache_sb {
* to change:
*/
uuid_le user_uuid;
- __u64 pad[6];
+ __u64 pad1[6];
- union {
- struct {
- /* Cache devices */
-
- /* Number of cache_member entries: */
- __u8 nr_in_set;
-
- /*
- * Index of this device - for PTR_DEV(), and also this device's
- * slot in the cache_member array:
- */
- __u8 nr_this_dev;
- };
- struct {
- /* Backing devices */
- __u64 bdev_data_offset;
- };
- };
+ /* Number of cache_member entries: */
+ __u8 nr_in_set;
- __u16 block_size; /* sectors */
+ /*
+ * Index of this device - for PTR_DEV(), and also this device's
+ * slot in the cache_member array:
+ */
+ __u8 nr_this_dev;
__u16 pad2[3];
- __u32 bdev_last_mount; /* time_t */
- __u16 pad3;
+ __le16 block_size; /* sectors */
+ __u16 pad3[6];
+
__u16 u64s; /* size of variable length portion */
union {
@@ -762,13 +751,57 @@ enum {
/* backing device specific stuff: */
-BITMASK(BDEV_CACHE_MODE, struct cache_sb, flags, 0, 4);
+struct backingdev_sb {
+ __u64 csum;
+ __u64 offset; /* sector where this sb was written */
+ __u64 version; /* of on disk format */
+
+ uuid_le magic; /* bcache superblock UUID */
+
+ uuid_le disk_uuid;
+
+ /*
+ * Internal cache set UUID - xored with various magic numbers and thus
+ * must never change:
+ */
+ union {
+ uuid_le set_uuid;
+ __u64 set_magic;
+ };
+ __u8 label[SB_LABEL_SIZE];
+
+ __u64 flags;
+
+ /* Incremented each time superblock is written: */
+ __u64 seq;
+
+ /*
+ * User visible UUID for identifying the cache set the user is allowed
+ * to change:
+ *
+ * XXX hooked up?
+ */
+ uuid_le user_uuid;
+ __u64 pad1[6];
+
+ __u64 data_offset;
+ __u16 block_size; /* sectors */
+ __u16 pad2[3];
+
+ __u32 last_mount; /* time_t */
+ __u16 pad3;
+ /* size of variable length portion - always 0 for backingdev superblock */
+ __u16 u64s;
+ __u64 _data[0];
+};
+
+BITMASK(BDEV_CACHE_MODE, struct backingdev_sb, flags, 0, 4);
#define CACHE_MODE_WRITETHROUGH 0U
#define CACHE_MODE_WRITEBACK 1U
#define CACHE_MODE_WRITEAROUND 2U
#define CACHE_MODE_NONE 3U
-BITMASK(BDEV_STATE, struct cache_sb, flags, 61, 63);
+BITMASK(BDEV_STATE, struct backingdev_sb, flags, 61, 63);
#define BDEV_STATE_NONE 0U
#define BDEV_STATE_CLEAN 1U
#define BDEV_STATE_DIRTY 2U