diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-01-11 19:39:35 -0900 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-07 12:35:18 -0800 |
commit | 0139a886248d71d2f0b58871fe18d277d5bf8a25 (patch) | |
tree | 838dbb2a35e1ff484081f378caf677465bda464f | |
parent | 95b4e5d76753b4ace59bf118ece188bf1696a467 (diff) |
bcache: split off backingdev_sb
The superblock formats are diverging too much
-rw-r--r-- | drivers/md/bcache/blockdev.c | 62 | ||||
-rw-r--r-- | drivers/md/bcache/blockdev_types.h | 2 | ||||
-rw-r--r-- | drivers/md/bcache/request.c | 2 | ||||
-rw-r--r-- | drivers/md/bcache/super.c | 74 | ||||
-rw-r--r-- | drivers/md/bcache/super.h | 5 | ||||
-rw-r--r-- | include/uapi/linux/bcache.h | 81 |
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 |