Skip to content

Commit d721a43

Browse files
Coly Liaxboe
authored andcommitted
bcache: increase super block version for cache device and backing device
The new added super block version BCACHE_SB_VERSION_BDEV_WITH_FEATURES (5) BCACHE_SB_VERSION_CDEV_WITH_FEATURES value (6), is for the feature set bits. Devices have super block version equal to the new version will have three new members for feature set bits in the on-disk super block, __le64 feature_compat; __le64 feature_incompat; __le64 feature_ro_compat; They are used for further new features which may introduce on-disk format change, and avoid unncessary super block version increase. The very basic features handling code skeleton is also initialized in this patch. Signed-off-by: Coly Li <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 117f636 commit d721a43

File tree

3 files changed

+128
-11
lines changed

3 files changed

+128
-11
lines changed

drivers/md/bcache/features.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2+
#ifndef _BCACHE_FEATURES_H
3+
#define _BCACHE_FEATURES_H
4+
5+
#include <linux/bcache.h>
6+
#include <linux/kernel.h>
7+
#include <linux/types.h>
8+
9+
#define BCH_FEATURE_COMPAT 0
10+
#define BCH_FEATURE_RO_COMPAT 1
11+
#define BCH_FEATURE_INCOMPAT 2
12+
#define BCH_FEATURE_TYPE_MASK 0x03
13+
14+
#define BCH_FEATURE_COMPAT_SUUP 0
15+
#define BCH_FEATURE_RO_COMPAT_SUUP 0
16+
#define BCH_FEATURE_INCOMPAT_SUUP 0
17+
18+
#define BCH_HAS_COMPAT_FEATURE(sb, mask) \
19+
((sb)->feature_compat & (mask))
20+
#define BCH_HAS_RO_COMPAT_FEATURE(sb, mask) \
21+
((sb)->feature_ro_compat & (mask))
22+
#define BCH_HAS_INCOMPAT_FEATURE(sb, mask) \
23+
((sb)->feature_incompat & (mask))
24+
25+
/* Feature set definition */
26+
27+
#define BCH_FEATURE_COMPAT_FUNCS(name, flagname) \
28+
static inline int bch_has_feature_##name(struct cache_sb *sb) \
29+
{ \
30+
return (((sb)->feature_compat & \
31+
BCH##_FEATURE_COMPAT_##flagname) != 0); \
32+
} \
33+
static inline void bch_set_feature_##name(struct cache_sb *sb) \
34+
{ \
35+
(sb)->feature_compat |= \
36+
BCH##_FEATURE_COMPAT_##flagname; \
37+
} \
38+
static inline void bch_clear_feature_##name(struct cache_sb *sb) \
39+
{ \
40+
(sb)->feature_compat &= \
41+
~BCH##_FEATURE_COMPAT_##flagname; \
42+
}
43+
44+
#define BCH_FEATURE_RO_COMPAT_FUNCS(name, flagname) \
45+
static inline int bch_has_feature_##name(struct cache_sb *sb) \
46+
{ \
47+
return (((sb)->feature_ro_compat & \
48+
BCH##_FEATURE_RO_COMPAT_##flagname) != 0); \
49+
} \
50+
static inline void bch_set_feature_##name(struct cache_sb *sb) \
51+
{ \
52+
(sb)->feature_ro_compat |= \
53+
BCH##_FEATURE_RO_COMPAT_##flagname; \
54+
} \
55+
static inline void bch_clear_feature_##name(struct cache_sb *sb) \
56+
{ \
57+
(sb)->feature_ro_compat &= \
58+
~BCH##_FEATURE_RO_COMPAT_##flagname; \
59+
}
60+
61+
#define BCH_FEATURE_INCOMPAT_FUNCS(name, flagname) \
62+
static inline int bch_has_feature_##name(struct cache_sb *sb) \
63+
{ \
64+
return (((sb)->feature_incompat & \
65+
BCH##_FEATURE_INCOMPAT_##flagname) != 0); \
66+
} \
67+
static inline void bch_set_feature_##name(struct cache_sb *sb) \
68+
{ \
69+
(sb)->feature_incompat |= \
70+
BCH##_FEATURE_INCOMPAT_##flagname; \
71+
} \
72+
static inline void bch_clear_feature_##name(struct cache_sb *sb) \
73+
{ \
74+
(sb)->feature_incompat &= \
75+
~BCH##_FEATURE_INCOMPAT_##flagname; \
76+
}
77+
78+
#endif

drivers/md/bcache/super.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "extents.h"
1414
#include "request.h"
1515
#include "writeback.h"
16+
#include "features.h"
1617

1718
#include <linux/blkdev.h>
1819
#include <linux/debugfs.h>
@@ -194,6 +195,7 @@ static const char *read_super(struct cache_sb *sb, struct block_device *bdev,
194195
sb->data_offset = BDEV_DATA_START_DEFAULT;
195196
break;
196197
case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
198+
case BCACHE_SB_VERSION_BDEV_WITH_FEATURES:
197199
sb->data_offset = le64_to_cpu(s->data_offset);
198200

199201
err = "Bad data offset";
@@ -207,6 +209,14 @@ static const char *read_super(struct cache_sb *sb, struct block_device *bdev,
207209
if (err)
208210
goto err;
209211
break;
212+
case BCACHE_SB_VERSION_CDEV_WITH_FEATURES:
213+
err = read_super_common(sb, bdev, s);
214+
if (err)
215+
goto err;
216+
sb->feature_compat = le64_to_cpu(s->feature_compat);
217+
sb->feature_incompat = le64_to_cpu(s->feature_incompat);
218+
sb->feature_ro_compat = le64_to_cpu(s->feature_ro_compat);
219+
break;
210220
default:
211221
err = "Unsupported superblock version";
212222
goto err;
@@ -241,7 +251,6 @@ static void __write_super(struct cache_sb *sb, struct cache_sb_disk *out,
241251
offset_in_page(out));
242252

243253
out->offset = cpu_to_le64(sb->offset);
244-
out->version = cpu_to_le64(sb->version);
245254

246255
memcpy(out->uuid, sb->uuid, 16);
247256
memcpy(out->set_uuid, sb->set_uuid, 16);
@@ -257,6 +266,13 @@ static void __write_super(struct cache_sb *sb, struct cache_sb_disk *out,
257266
for (i = 0; i < sb->keys; i++)
258267
out->d[i] = cpu_to_le64(sb->d[i]);
259268

269+
if (sb->version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES) {
270+
out->feature_compat = cpu_to_le64(sb->feature_compat);
271+
out->feature_incompat = cpu_to_le64(sb->feature_incompat);
272+
out->feature_ro_compat = cpu_to_le64(sb->feature_ro_compat);
273+
}
274+
275+
out->version = cpu_to_le64(sb->version);
260276
out->csum = csum_set(out);
261277

262278
pr_debug("ver %llu, flags %llu, seq %llu\n",
@@ -313,17 +329,20 @@ void bcache_write_super(struct cache_set *c)
313329
{
314330
struct closure *cl = &c->sb_write;
315331
struct cache *ca;
316-
unsigned int i;
332+
unsigned int i, version = BCACHE_SB_VERSION_CDEV_WITH_UUID;
317333

318334
down(&c->sb_write_mutex);
319335
closure_init(cl, &c->cl);
320336

321337
c->sb.seq++;
322338

339+
if (c->sb.version > version)
340+
version = c->sb.version;
341+
323342
for_each_cache(ca, c, i) {
324343
struct bio *bio = &ca->sb_bio;
325344

326-
ca->sb.version = BCACHE_SB_VERSION_CDEV_WITH_UUID;
345+
ca->sb.version = version;
327346
ca->sb.seq = c->sb.seq;
328347
ca->sb.last_mount = c->sb.last_mount;
329348

@@ -1839,6 +1858,13 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
18391858
c->sb.bucket_size = sb->bucket_size;
18401859
c->sb.nr_in_set = sb->nr_in_set;
18411860
c->sb.last_mount = sb->last_mount;
1861+
c->sb.version = sb->version;
1862+
if (c->sb.version >= BCACHE_SB_VERSION_CDEV_WITH_FEATURES) {
1863+
c->sb.feature_compat = sb->feature_compat;
1864+
c->sb.feature_ro_compat = sb->feature_ro_compat;
1865+
c->sb.feature_incompat = sb->feature_incompat;
1866+
}
1867+
18421868
c->bucket_bits = ilog2(sb->bucket_size);
18431869
c->block_bits = ilog2(sb->block_size);
18441870
c->nr_uuids = bucket_bytes(c) / sizeof(struct uuid_entry);

include/uapi/linux/bcache.h

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,13 @@ static inline struct bkey *bkey_idx(const struct bkey *k, unsigned int nr_keys)
141141
* Version 3: Cache device with new UUID format
142142
* Version 4: Backing device with data offset
143143
*/
144-
#define BCACHE_SB_VERSION_CDEV 0
145-
#define BCACHE_SB_VERSION_BDEV 1
146-
#define BCACHE_SB_VERSION_CDEV_WITH_UUID 3
147-
#define BCACHE_SB_VERSION_BDEV_WITH_OFFSET 4
148-
#define BCACHE_SB_MAX_VERSION 4
144+
#define BCACHE_SB_VERSION_CDEV 0
145+
#define BCACHE_SB_VERSION_BDEV 1
146+
#define BCACHE_SB_VERSION_CDEV_WITH_UUID 3
147+
#define BCACHE_SB_VERSION_BDEV_WITH_OFFSET 4
148+
#define BCACHE_SB_VERSION_CDEV_WITH_FEATURES 5
149+
#define BCACHE_SB_VERSION_BDEV_WITH_FEATURES 6
150+
#define BCACHE_SB_MAX_VERSION 6
149151

150152
#define SB_SECTOR 8
151153
#define SB_OFFSET (SB_SECTOR << SECTOR_SHIFT)
@@ -173,7 +175,12 @@ struct cache_sb_disk {
173175

174176
__le64 flags;
175177
__le64 seq;
176-
__le64 pad[8];
178+
179+
__le64 feature_compat;
180+
__le64 feature_incompat;
181+
__le64 feature_ro_compat;
182+
183+
__le64 pad[5];
177184

178185
union {
179186
struct {
@@ -224,7 +231,12 @@ struct cache_sb {
224231

225232
__u64 flags;
226233
__u64 seq;
227-
__u64 pad[8];
234+
235+
__u64 feature_compat;
236+
__u64 feature_incompat;
237+
__u64 feature_ro_compat;
238+
239+
__u64 pad[5];
228240

229241
union {
230242
struct {
@@ -262,7 +274,8 @@ struct cache_sb {
262274
static inline _Bool SB_IS_BDEV(const struct cache_sb *sb)
263275
{
264276
return sb->version == BCACHE_SB_VERSION_BDEV
265-
|| sb->version == BCACHE_SB_VERSION_BDEV_WITH_OFFSET;
277+
|| sb->version == BCACHE_SB_VERSION_BDEV_WITH_OFFSET
278+
|| sb->version == BCACHE_SB_VERSION_BDEV_WITH_FEATURES;
266279
}
267280

268281
BITMASK(CACHE_SYNC, struct cache_sb, flags, 0, 1);

0 commit comments

Comments
 (0)