aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorKent Overstreet <koverstreet@google.com>2013-04-11 18:14:35 -0400
committerKent Overstreet <koverstreet@google.com>2013-04-20 20:56:12 -0400
commit2903381fce71004a7ce24d40fad53ba8236a3921 (patch)
treef493d51bdf17b2376e3f79fe0aecc8a7a9e37263 /drivers/md
parentcef5279735d3f6f0243e626963e6d5c84efade0a (diff)
bcache: Take data offset from the bdev superblock.
Add a new superblock version, and consolidate related defines. Signed-off-by: Gabriel de Perthuis <g2p.code+bcache@gmail.com> Signed-off-by: Kent Overstreet <koverstreet@google.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/bcache/bcache.h47
-rw-r--r--drivers/md/bcache/request.c2
-rw-r--r--drivers/md/bcache/super.c108
3 files changed, 100 insertions, 57 deletions
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index f05723565f17..340146d7c17f 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -223,11 +223,17 @@ struct bkey {
223#define BKEY_PADDED(key) \ 223#define BKEY_PADDED(key) \
224 union { struct bkey key; uint64_t key ## _pad[BKEY_PAD]; } 224 union { struct bkey key; uint64_t key ## _pad[BKEY_PAD]; }
225 225
226/* Version 1: Backing device 226/* Version 0: Cache device
227 * Version 1: Backing device
227 * Version 2: Seed pointer into btree node checksum 228 * Version 2: Seed pointer into btree node checksum
228 * Version 3: New UUID format 229 * Version 3: Cache device with new UUID format
230 * Version 4: Backing device with data offset
229 */ 231 */
230#define BCACHE_SB_VERSION 3 232#define BCACHE_SB_VERSION_CDEV 0
233#define BCACHE_SB_VERSION_BDEV 1
234#define BCACHE_SB_VERSION_CDEV_WITH_UUID 3
235#define BCACHE_SB_VERSION_BDEV_WITH_OFFSET 4
236#define BCACHE_SB_MAX_VERSION 4
231 237
232#define SB_SECTOR 8 238#define SB_SECTOR 8
233#define SB_SIZE 4096 239#define SB_SIZE 4096
@@ -236,13 +242,12 @@ struct bkey {
236/* SB_JOURNAL_BUCKETS must be divisible by BITS_PER_LONG */ 242/* SB_JOURNAL_BUCKETS must be divisible by BITS_PER_LONG */
237#define MAX_CACHES_PER_SET 8 243#define MAX_CACHES_PER_SET 8
238 244
239#define BDEV_DATA_START 16 /* sectors */ 245#define BDEV_DATA_START_DEFAULT 16 /* sectors */
240 246
241struct cache_sb { 247struct cache_sb {
242 uint64_t csum; 248 uint64_t csum;
243 uint64_t offset; /* sector where this sb was written */ 249 uint64_t offset; /* sector where this sb was written */
244 uint64_t version; 250 uint64_t version;
245#define CACHE_BACKING_DEV 1
246 251
247 uint8_t magic[16]; 252 uint8_t magic[16];
248 253
@@ -257,12 +262,28 @@ struct cache_sb {
257 uint64_t seq; 262 uint64_t seq;
258 uint64_t pad[8]; 263 uint64_t pad[8];
259 264
260 uint64_t nbuckets; /* device size */ 265 union {
261 uint16_t block_size; /* sectors */ 266 struct {
262 uint16_t bucket_size; /* sectors */ 267 /* Cache devices */
268 uint64_t nbuckets; /* device size */
269
270 uint16_t block_size; /* sectors */
271 uint16_t bucket_size; /* sectors */
263 272
264 uint16_t nr_in_set; 273 uint16_t nr_in_set;
265 uint16_t nr_this_dev; 274 uint16_t nr_this_dev;
275 };
276 struct {
277 /* Backing devices */
278 uint64_t data_offset;
279
280 /*
281 * block_size from the cache device section is still used by
282 * backing devices, so don't add anything here until we fix
283 * things to not need it for backing devices anymore
284 */
285 };
286 };
266 287
267 uint32_t last_mount; /* time_t */ 288 uint32_t last_mount; /* time_t */
268 289
@@ -861,6 +882,12 @@ static inline bool key_merging_disabled(struct cache_set *c)
861#endif 882#endif
862} 883}
863 884
885static inline bool SB_IS_BDEV(const struct cache_sb *sb)
886{
887 return sb->version == BCACHE_SB_VERSION_BDEV
888 || sb->version == BCACHE_SB_VERSION_BDEV_WITH_OFFSET;
889}
890
864struct bbio { 891struct bbio {
865 unsigned submit_time_us; 892 unsigned submit_time_us;
866 union { 893 union {
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 83731dc36f34..e5ff12e52d5b 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -1220,7 +1220,7 @@ static void cached_dev_make_request(struct request_queue *q, struct bio *bio)
1220 part_stat_unlock(); 1220 part_stat_unlock();
1221 1221
1222 bio->bi_bdev = dc->bdev; 1222 bio->bi_bdev = dc->bdev;
1223 bio->bi_sector += BDEV_DATA_START; 1223 bio->bi_sector += dc->sb.data_offset;
1224 1224
1225 if (cached_dev_get(dc)) { 1225 if (cached_dev_get(dc)) {
1226 s = search_alloc(bio, d); 1226 s = search_alloc(bio, d);
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index 5fa3cd2d9ff0..f1e69f2fad37 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -110,15 +110,7 @@ static const char *read_super(struct cache_sb *sb, struct block_device *bdev,
110 110
111 sb->flags = le64_to_cpu(s->flags); 111 sb->flags = le64_to_cpu(s->flags);
112 sb->seq = le64_to_cpu(s->seq); 112 sb->seq = le64_to_cpu(s->seq);
113
114 sb->nbuckets = le64_to_cpu(s->nbuckets);
115 sb->block_size = le16_to_cpu(s->block_size);
116 sb->bucket_size = le16_to_cpu(s->bucket_size);
117
118 sb->nr_in_set = le16_to_cpu(s->nr_in_set);
119 sb->nr_this_dev = le16_to_cpu(s->nr_this_dev);
120 sb->last_mount = le32_to_cpu(s->last_mount); 113 sb->last_mount = le32_to_cpu(s->last_mount);
121
122 sb->first_bucket = le16_to_cpu(s->first_bucket); 114 sb->first_bucket = le16_to_cpu(s->first_bucket);
123 sb->keys = le16_to_cpu(s->keys); 115 sb->keys = le16_to_cpu(s->keys);
124 116
@@ -147,53 +139,77 @@ static const char *read_super(struct cache_sb *sb, struct block_device *bdev,
147 if (bch_is_zero(sb->uuid, 16)) 139 if (bch_is_zero(sb->uuid, 16))
148 goto err; 140 goto err;
149 141
150 err = "Unsupported superblock version"; 142 switch (sb->version) {
151 if (sb->version > BCACHE_SB_VERSION) 143 case BCACHE_SB_VERSION_BDEV:
152 goto err; 144 sb->block_size = le16_to_cpu(s->block_size);
145 sb->data_offset = BDEV_DATA_START_DEFAULT;
146 break;
147 case BCACHE_SB_VERSION_BDEV_WITH_OFFSET:
148 sb->block_size = le16_to_cpu(s->block_size);
149 sb->data_offset = le64_to_cpu(s->data_offset);
150
151 err = "Bad data offset";
152 if (sb->data_offset < BDEV_DATA_START_DEFAULT)
153 goto err;
153 154
154 err = "Bad block/bucket size"; 155 break;
155 if (!is_power_of_2(sb->block_size) || sb->block_size > PAGE_SECTORS || 156 case BCACHE_SB_VERSION_CDEV:
156 !is_power_of_2(sb->bucket_size) || sb->bucket_size < PAGE_SECTORS) 157 case BCACHE_SB_VERSION_CDEV_WITH_UUID:
157 goto err; 158 sb->nbuckets = le64_to_cpu(s->nbuckets);
159 sb->block_size = le16_to_cpu(s->block_size);
160 sb->bucket_size = le16_to_cpu(s->bucket_size);
158 161
159 err = "Too many buckets"; 162 sb->nr_in_set = le16_to_cpu(s->nr_in_set);
160 if (sb->nbuckets > LONG_MAX) 163 sb->nr_this_dev = le16_to_cpu(s->nr_this_dev);
161 goto err;
162 164
163 err = "Not enough buckets"; 165 err = "Too many buckets";
164 if (sb->nbuckets < 1 << 7) 166 if (sb->nbuckets > LONG_MAX)
165 goto err; 167 goto err;
166 168
167 err = "Invalid superblock: device too small"; 169 err = "Not enough buckets";
168 if (get_capacity(bdev->bd_disk) < sb->bucket_size * sb->nbuckets) 170 if (sb->nbuckets < 1 << 7)
169 goto err; 171 goto err;
170 172
171 if (sb->version == CACHE_BACKING_DEV) 173 err = "Bad block/bucket size";
172 goto out; 174 if (!is_power_of_2(sb->block_size) ||
175 sb->block_size > PAGE_SECTORS ||
176 !is_power_of_2(sb->bucket_size) ||
177 sb->bucket_size < PAGE_SECTORS)
178 goto err;
173 179
174 err = "Bad UUID"; 180 err = "Invalid superblock: device too small";
175 if (bch_is_zero(sb->set_uuid, 16)) 181 if (get_capacity(bdev->bd_disk) < sb->bucket_size * sb->nbuckets)
176 goto err; 182 goto err;
177 183
178 err = "Bad cache device number in set"; 184 err = "Bad UUID";
179 if (!sb->nr_in_set || 185 if (bch_is_zero(sb->set_uuid, 16))
180 sb->nr_in_set <= sb->nr_this_dev || 186 goto err;
181 sb->nr_in_set > MAX_CACHES_PER_SET)
182 goto err;
183 187
184 err = "Journal buckets not sequential"; 188 err = "Bad cache device number in set";
185 for (i = 0; i < sb->keys; i++) 189 if (!sb->nr_in_set ||
186 if (sb->d[i] != sb->first_bucket + i) 190 sb->nr_in_set <= sb->nr_this_dev ||
191 sb->nr_in_set > MAX_CACHES_PER_SET)
187 goto err; 192 goto err;
188 193
189 err = "Too many journal buckets"; 194 err = "Journal buckets not sequential";
190 if (sb->first_bucket + sb->keys > sb->nbuckets) 195 for (i = 0; i < sb->keys; i++)
191 goto err; 196 if (sb->d[i] != sb->first_bucket + i)
197 goto err;
192 198
193 err = "Invalid superblock: first bucket comes before end of super"; 199 err = "Too many journal buckets";
194 if (sb->first_bucket * sb->bucket_size < 16) 200 if (sb->first_bucket + sb->keys > sb->nbuckets)
201 goto err;
202
203 err = "Invalid superblock: first bucket comes before end of super";
204 if (sb->first_bucket * sb->bucket_size < 16)
205 goto err;
206
207 break;
208 default:
209 err = "Unsupported superblock version";
195 goto err; 210 goto err;
196out: 211 }
212
197 sb->last_mount = get_seconds(); 213 sb->last_mount = get_seconds();
198 err = NULL; 214 err = NULL;
199 215
@@ -286,7 +302,7 @@ void bcache_write_super(struct cache_set *c)
286 for_each_cache(ca, c, i) { 302 for_each_cache(ca, c, i) {
287 struct bio *bio = &ca->sb_bio; 303 struct bio *bio = &ca->sb_bio;
288 304
289 ca->sb.version = BCACHE_SB_VERSION; 305 ca->sb.version = BCACHE_SB_VERSION_CDEV_WITH_UUID;
290 ca->sb.seq = c->sb.seq; 306 ca->sb.seq = c->sb.seq;
291 ca->sb.last_mount = c->sb.last_mount; 307 ca->sb.last_mount = c->sb.last_mount;
292 308
@@ -1049,7 +1065,7 @@ static const char *register_bdev(struct cache_sb *sb, struct page *sb_page,
1049 1065
1050 g = dc->disk.disk; 1066 g = dc->disk.disk;
1051 1067
1052 set_capacity(g, dc->bdev->bd_part->nr_sects - 16); 1068 set_capacity(g, dc->bdev->bd_part->nr_sects - dc->sb.data_offset);
1053 1069
1054 bch_cached_dev_request_init(dc); 1070 bch_cached_dev_request_init(dc);
1055 1071
@@ -1802,7 +1818,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr,
1802 if (err) 1818 if (err)
1803 goto err_close; 1819 goto err_close;
1804 1820
1805 if (sb->version == CACHE_BACKING_DEV) { 1821 if (SB_IS_BDEV(sb)) {
1806 struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL); 1822 struct cached_dev *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
1807 1823
1808 err = register_bdev(sb, sb_page, bdev, dc); 1824 err = register_bdev(sb, sb_page, bdev, dc);