aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-cache-metadata.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-03-02 14:44:27 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-03-02 14:44:27 -0500
commit37cae6ad4c484030fa972241533c32730ec79b7d (patch)
treea01a13982af7b326af37c729a5ad83adbe99322d /drivers/md/dm-cache-metadata.c
parent986248993d495aebffcdf0758ce28ab85aa4e9ff (diff)
parent8735a8134786fa4ef36dee65d7fa779b99ba5fe3 (diff)
Merge tag 'dm-3.9-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm
Pull device-mapper update from Alasdair G Kergon: "The main addition here is a long-desired target framework to allow an SSD to be used as a cache in front of a slower device. Cache tuning is delegated to interchangeable policy modules so these can be developed independently of the mechanics needed to shuffle the data around. Other than that, kcopyd users acquire a throttling parameter, ioctl buffer usage gets streamlined, more mempool reliance is reduced and there are a few other bug fixes and tidy-ups." * tag 'dm-3.9-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm: (30 commits) dm cache: add cleaner policy dm cache: add mq policy dm: add cache target dm persistent data: add bitset dm persistent data: add transactional array dm thin: remove cells from stack dm bio prison: pass cell memory in dm persistent data: add btree_walk dm: add target num_write_bios fn dm kcopyd: introduce configurable throttling dm ioctl: allow message to return data dm ioctl: optimize functions without variable params dm ioctl: introduce ioctl_flags dm: merge io_pool and tio_pool dm: remove unused _rq_bio_info_cache dm: fix limits initialization when there are no data devices dm snapshot: add missing module aliases dm persistent data: set some btree fn parms const dm: refactor bio cloning dm: rename bio cloning functions ...
Diffstat (limited to 'drivers/md/dm-cache-metadata.c')
-rw-r--r--drivers/md/dm-cache-metadata.c1146
1 files changed, 1146 insertions, 0 deletions
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
new file mode 100644
index 000000000000..fbd3625f2748
--- /dev/null
+++ b/drivers/md/dm-cache-metadata.c
@@ -0,0 +1,1146 @@
1/*
2 * Copyright (C) 2012 Red Hat, Inc.
3 *
4 * This file is released under the GPL.
5 */
6
7#include "dm-cache-metadata.h"
8
9#include "persistent-data/dm-array.h"
10#include "persistent-data/dm-bitset.h"
11#include "persistent-data/dm-space-map.h"
12#include "persistent-data/dm-space-map-disk.h"
13#include "persistent-data/dm-transaction-manager.h"
14
15#include <linux/device-mapper.h>
16
17/*----------------------------------------------------------------*/
18
19#define DM_MSG_PREFIX "cache metadata"
20
21#define CACHE_SUPERBLOCK_MAGIC 06142003
22#define CACHE_SUPERBLOCK_LOCATION 0
23#define CACHE_VERSION 1
24#define CACHE_METADATA_CACHE_SIZE 64
25
26/*
27 * 3 for btree insert +
28 * 2 for btree lookup used within space map
29 */
30#define CACHE_MAX_CONCURRENT_LOCKS 5
31#define SPACE_MAP_ROOT_SIZE 128
32
33enum superblock_flag_bits {
34 /* for spotting crashes that would invalidate the dirty bitset */
35 CLEAN_SHUTDOWN,
36};
37
38/*
39 * Each mapping from cache block -> origin block carries a set of flags.
40 */
41enum mapping_bits {
42 /*
43 * A valid mapping. Because we're using an array we clear this
44 * flag for an non existant mapping.
45 */
46 M_VALID = 1,
47
48 /*
49 * The data on the cache is different from that on the origin.
50 */
51 M_DIRTY = 2
52};
53
54struct cache_disk_superblock {
55 __le32 csum;
56 __le32 flags;
57 __le64 blocknr;
58
59 __u8 uuid[16];
60 __le64 magic;
61 __le32 version;
62
63 __u8 policy_name[CACHE_POLICY_NAME_SIZE];
64 __le32 policy_hint_size;
65
66 __u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE];
67 __le64 mapping_root;
68 __le64 hint_root;
69
70 __le64 discard_root;
71 __le64 discard_block_size;
72 __le64 discard_nr_blocks;
73
74 __le32 data_block_size;
75 __le32 metadata_block_size;
76 __le32 cache_blocks;
77
78 __le32 compat_flags;
79 __le32 compat_ro_flags;
80 __le32 incompat_flags;
81
82 __le32 read_hits;
83 __le32 read_misses;
84 __le32 write_hits;
85 __le32 write_misses;
86} __packed;
87
88struct dm_cache_metadata {
89 struct block_device *bdev;
90 struct dm_block_manager *bm;
91 struct dm_space_map *metadata_sm;
92 struct dm_transaction_manager *tm;
93
94 struct dm_array_info info;
95 struct dm_array_info hint_info;
96 struct dm_disk_bitset discard_info;
97
98 struct rw_semaphore root_lock;
99 dm_block_t root;
100 dm_block_t hint_root;
101 dm_block_t discard_root;
102
103 sector_t discard_block_size;
104 dm_dblock_t discard_nr_blocks;
105
106 sector_t data_block_size;
107 dm_cblock_t cache_blocks;
108 bool changed:1;
109 bool clean_when_opened:1;
110
111 char policy_name[CACHE_POLICY_NAME_SIZE];
112 size_t policy_hint_size;
113 struct dm_cache_statistics stats;
114};
115
116/*-------------------------------------------------------------------
117 * superblock validator
118 *-----------------------------------------------------------------*/
119
120#define SUPERBLOCK_CSUM_XOR 9031977
121
122static void sb_prepare_for_write(struct dm_block_validator *v,
123 struct dm_block *b,
124 size_t sb_block_size)
125{
126 struct cache_disk_superblock *disk_super = dm_block_data(b);
127
128 disk_super->blocknr = cpu_to_le64(dm_block_location(b));
129 disk_super->csum = cpu_to_le32(dm_bm_checksum(&disk_super->flags,
130 sb_block_size - sizeof(__le32),
131 SUPERBLOCK_CSUM_XOR));
132}
133
134static int sb_check(struct dm_block_validator *v,
135 struct dm_block *b,
136 size_t sb_block_size)
137{
138 struct cache_disk_superblock *disk_super = dm_block_data(b);
139 __le32 csum_le;
140
141 if (dm_block_location(b) != le64_to_cpu(disk_super->blocknr)) {
142 DMERR("sb_check failed: blocknr %llu: wanted %llu",
143 le64_to_cpu(disk_super->blocknr),
144 (unsigned long long)dm_block_location(b));
145 return -ENOTBLK;
146 }
147
148 if (le64_to_cpu(disk_super->magic) != CACHE_SUPERBLOCK_MAGIC) {
149 DMERR("sb_check failed: magic %llu: wanted %llu",
150 le64_to_cpu(disk_super->magic),
151 (unsigned long long)CACHE_SUPERBLOCK_MAGIC);
152 return -EILSEQ;
153 }
154
155 csum_le = cpu_to_le32(dm_bm_checksum(&disk_super->flags,
156 sb_block_size - sizeof(__le32),
157 SUPERBLOCK_CSUM_XOR));
158 if (csum_le != disk_super->csum) {
159 DMERR("sb_check failed: csum %u: wanted %u",
160 le32_to_cpu(csum_le), le32_to_cpu(disk_super->csum));
161 return -EILSEQ;
162 }
163
164 return 0;
165}
166
167static struct dm_block_validator sb_validator = {
168 .name = "superblock",
169 .prepare_for_write = sb_prepare_for_write,
170 .check = sb_check
171};
172
173/*----------------------------------------------------------------*/
174
175static int superblock_read_lock(struct dm_cache_metadata *cmd,
176 struct dm_block **sblock)
177{
178 return dm_bm_read_lock(cmd->bm, CACHE_SUPERBLOCK_LOCATION,
179 &sb_validator, sblock);
180}
181
182static int superblock_lock_zero(struct dm_cache_metadata *cmd,
183 struct dm_block **sblock)
184{
185 return dm_bm_write_lock_zero(cmd->bm, CACHE_SUPERBLOCK_LOCATION,
186 &sb_validator, sblock);
187}
188
189static int superblock_lock(struct dm_cache_metadata *cmd,
190 struct dm_block **sblock)
191{
192 return dm_bm_write_lock(cmd->bm, CACHE_SUPERBLOCK_LOCATION,
193 &sb_validator, sblock);
194}
195
196/*----------------------------------------------------------------*/
197
198static int __superblock_all_zeroes(struct dm_block_manager *bm, int *result)
199{
200 int r;
201 unsigned i;
202 struct dm_block *b;
203 __le64 *data_le, zero = cpu_to_le64(0);
204 unsigned sb_block_size = dm_bm_block_size(bm) / sizeof(__le64);
205
206 /*
207 * We can't use a validator here - it may be all zeroes.
208 */
209 r = dm_bm_read_lock(bm, CACHE_SUPERBLOCK_LOCATION, NULL, &b);
210 if (r)
211 return r;
212
213 data_le = dm_block_data(b);
214 *result = 1;
215 for (i = 0; i < sb_block_size; i++) {
216 if (data_le[i] != zero) {
217 *result = 0;
218 break;
219 }
220 }
221
222 return dm_bm_unlock(b);
223}
224
225static void __setup_mapping_info(struct dm_cache_metadata *cmd)
226{
227 struct dm_btree_value_type vt;
228
229 vt.context = NULL;
230 vt.size = sizeof(__le64);
231 vt.inc = NULL;
232 vt.dec = NULL;
233 vt.equal = NULL;
234 dm_array_info_init(&cmd->info, cmd->tm, &vt);
235
236 if (cmd->policy_hint_size) {
237 vt.size = sizeof(__le32);
238 dm_array_info_init(&cmd->hint_info, cmd->tm, &vt);
239 }
240}
241
242static int __write_initial_superblock(struct dm_cache_metadata *cmd)
243{
244 int r;
245 struct dm_block *sblock;
246 size_t metadata_len;
247 struct cache_disk_superblock *disk_super;
248 sector_t bdev_size = i_size_read(cmd->bdev->bd_inode) >> SECTOR_SHIFT;
249
250 /* FIXME: see if we can lose the max sectors limit */
251 if (bdev_size > DM_CACHE_METADATA_MAX_SECTORS)
252 bdev_size = DM_CACHE_METADATA_MAX_SECTORS;
253
254 r = dm_sm_root_size(cmd->metadata_sm, &metadata_len);
255 if (r < 0)
256 return r;
257
258 r = dm_tm_pre_commit(cmd->tm);
259 if (r < 0)
260 return r;
261
262 r = superblock_lock_zero(cmd, &sblock);
263 if (r)
264 return r;
265
266 disk_super = dm_block_data(sblock);
267 disk_super->flags = 0;
268 memset(disk_super->uuid, 0, sizeof(disk_super->uuid));
269 disk_super->magic = cpu_to_le64(CACHE_SUPERBLOCK_MAGIC);
270 disk_super->version = cpu_to_le32(CACHE_VERSION);
271 memset(disk_super->policy_name, 0, CACHE_POLICY_NAME_SIZE);
272 disk_super->policy_hint_size = 0;
273
274 r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root,
275 metadata_len);
276 if (r < 0)
277 goto bad_locked;
278
279 disk_super->mapping_root = cpu_to_le64(cmd->root);
280 disk_super->hint_root = cpu_to_le64(cmd->hint_root);
281 disk_super->discard_root = cpu_to_le64(cmd->discard_root);
282 disk_super->discard_block_size = cpu_to_le64(cmd->discard_block_size);
283 disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks));
284 disk_super->metadata_block_size = cpu_to_le32(DM_CACHE_METADATA_BLOCK_SIZE >> SECTOR_SHIFT);
285 disk_super->data_block_size = cpu_to_le32(cmd->data_block_size);
286 disk_super->cache_blocks = cpu_to_le32(0);
287 memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name));
288
289 disk_super->read_hits = cpu_to_le32(0);
290 disk_super->read_misses = cpu_to_le32(0);
291 disk_super->write_hits = cpu_to_le32(0);
292 disk_super->write_misses = cpu_to_le32(0);
293
294 return dm_tm_commit(cmd->tm, sblock);
295
296bad_locked:
297 dm_bm_unlock(sblock);
298 return r;
299}
300
301static int __format_metadata(struct dm_cache_metadata *cmd)
302{
303 int r;
304
305 r = dm_tm_create_with_sm(cmd->bm, CACHE_SUPERBLOCK_LOCATION,
306 &cmd->tm, &cmd->metadata_sm);
307 if (r < 0) {
308 DMERR("tm_create_with_sm failed");
309 return r;
310 }
311
312 __setup_mapping_info(cmd);
313
314 r = dm_array_empty(&cmd->info, &cmd->root);
315 if (r < 0)
316 goto bad;
317
318 dm_disk_bitset_init(cmd->tm, &cmd->discard_info);
319
320 r = dm_bitset_empty(&cmd->discard_info, &cmd->discard_root);
321 if (r < 0)
322 goto bad;
323
324 cmd->discard_block_size = 0;
325 cmd->discard_nr_blocks = 0;
326
327 r = __write_initial_superblock(cmd);
328 if (r)
329 goto bad;
330
331 cmd->clean_when_opened = true;
332 return 0;
333
334bad:
335 dm_tm_destroy(cmd->tm);
336 dm_sm_destroy(cmd->metadata_sm);
337
338 return r;
339}
340
341static int __check_incompat_features(struct cache_disk_superblock *disk_super,
342 struct dm_cache_metadata *cmd)
343{
344 uint32_t features;
345
346 features = le32_to_cpu(disk_super->incompat_flags) & ~DM_CACHE_FEATURE_INCOMPAT_SUPP;
347 if (features) {
348 DMERR("could not access metadata due to unsupported optional features (%lx).",
349 (unsigned long)features);
350 return -EINVAL;
351 }
352
353 /*
354 * Check for read-only metadata to skip the following RDWR checks.
355 */
356 if (get_disk_ro(cmd->bdev->bd_disk))
357 return 0;
358
359 features = le32_to_cpu(disk_super->compat_ro_flags) & ~DM_CACHE_FEATURE_COMPAT_RO_SUPP;
360 if (features) {
361 DMERR("could not access metadata RDWR due to unsupported optional features (%lx).",
362 (unsigned long)features);
363 return -EINVAL;
364 }
365
366 return 0;
367}
368
369static int __open_metadata(struct dm_cache_metadata *cmd)
370{
371 int r;
372 struct dm_block *sblock;
373 struct cache_disk_superblock *disk_super;
374 unsigned long sb_flags;
375
376 r = superblock_read_lock(cmd, &sblock);
377 if (r < 0) {
378 DMERR("couldn't read lock superblock");
379 return r;
380 }
381
382 disk_super = dm_block_data(sblock);
383
384 r = __check_incompat_features(disk_super, cmd);
385 if (r < 0)
386 goto bad;
387
388 r = dm_tm_open_with_sm(cmd->bm, CACHE_SUPERBLOCK_LOCATION,
389 disk_super->metadata_space_map_root,
390 sizeof(disk_super->metadata_space_map_root),
391 &cmd->tm, &cmd->metadata_sm);
392 if (r < 0) {
393 DMERR("tm_open_with_sm failed");
394 goto bad;
395 }
396
397 __setup_mapping_info(cmd);
398 dm_disk_bitset_init(cmd->tm, &cmd->discard_info);
399 sb_flags = le32_to_cpu(disk_super->flags);
400 cmd->clean_when_opened = test_bit(CLEAN_SHUTDOWN, &sb_flags);
401 return dm_bm_unlock(sblock);
402
403bad:
404 dm_bm_unlock(sblock);
405 return r;
406}
407
408static int __open_or_format_metadata(struct dm_cache_metadata *cmd,
409 bool format_device)
410{
411 int r, unformatted;
412
413 r = __superblock_all_zeroes(cmd->bm, &unformatted);
414 if (r)
415 return r;
416
417 if (unformatted)
418 return format_device ? __format_metadata(cmd) : -EPERM;
419
420 return __open_metadata(cmd);
421}
422
423static int __create_persistent_data_objects(struct dm_cache_metadata *cmd,
424 bool may_format_device)
425{
426 int r;
427 cmd->bm = dm_block_manager_create(cmd->bdev, DM_CACHE_METADATA_BLOCK_SIZE,
428 CACHE_METADATA_CACHE_SIZE,
429 CACHE_MAX_CONCURRENT_LOCKS);
430 if (IS_ERR(cmd->bm)) {
431 DMERR("could not create block manager");
432 return PTR_ERR(cmd->bm);
433 }
434
435 r = __open_or_format_metadata(cmd, may_format_device);
436 if (r)
437 dm_block_manager_destroy(cmd->bm);
438
439 return r;
440}
441
442static void __destroy_persistent_data_objects(struct dm_cache_metadata *cmd)
443{
444 dm_sm_destroy(cmd->metadata_sm);
445 dm_tm_destroy(cmd->tm);
446 dm_block_manager_destroy(cmd->bm);
447}
448
449typedef unsigned long (*flags_mutator)(unsigned long);
450
451static void update_flags(struct cache_disk_superblock *disk_super,
452 flags_mutator mutator)
453{
454 uint32_t sb_flags = mutator(le32_to_cpu(disk_super->flags));
455 disk_super->flags = cpu_to_le32(sb_flags);
456}
457
458static unsigned long set_clean_shutdown(unsigned long flags)
459{
460 set_bit(CLEAN_SHUTDOWN, &flags);
461 return flags;
462}
463
464static unsigned long clear_clean_shutdown(unsigned long flags)
465{
466 clear_bit(CLEAN_SHUTDOWN, &flags);
467 return flags;
468}
469
470static void read_superblock_fields(struct dm_cache_metadata *cmd,
471 struct cache_disk_superblock *disk_super)
472{
473 cmd->root = le64_to_cpu(disk_super->mapping_root);
474 cmd->hint_root = le64_to_cpu(disk_super->hint_root);
475 cmd->discard_root = le64_to_cpu(disk_super->discard_root);
476 cmd->discard_block_size = le64_to_cpu(disk_super->discard_block_size);
477 cmd->discard_nr_blocks = to_dblock(le64_to_cpu(disk_super->discard_nr_blocks));
478 cmd->data_block_size = le32_to_cpu(disk_super->data_block_size);
479 cmd->cache_blocks = to_cblock(le32_to_cpu(disk_super->cache_blocks));
480 strncpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name));
481 cmd->policy_hint_size = le32_to_cpu(disk_super->policy_hint_size);
482
483 cmd->stats.read_hits = le32_to_cpu(disk_super->read_hits);
484 cmd->stats.read_misses = le32_to_cpu(disk_super->read_misses);
485 cmd->stats.write_hits = le32_to_cpu(disk_super->write_hits);
486 cmd->stats.write_misses = le32_to_cpu(disk_super->write_misses);
487
488 cmd->changed = false;
489}
490
491/*
492 * The mutator updates the superblock flags.
493 */
494static int __begin_transaction_flags(struct dm_cache_metadata *cmd,
495 flags_mutator mutator)
496{
497 int r;
498 struct cache_disk_superblock *disk_super;
499 struct dm_block *sblock;
500
501 r = superblock_lock(cmd, &sblock);
502 if (r)
503 return r;
504
505 disk_super = dm_block_data(sblock);
506 update_flags(disk_super, mutator);
507 read_superblock_fields(cmd, disk_super);
508
509 return dm_bm_flush_and_unlock(cmd->bm, sblock);
510}
511
512static int __begin_transaction(struct dm_cache_metadata *cmd)
513{
514 int r;
515 struct cache_disk_superblock *disk_super;
516 struct dm_block *sblock;
517
518 /*
519 * We re-read the superblock every time. Shouldn't need to do this
520 * really.
521 */
522 r = superblock_read_lock(cmd, &sblock);
523 if (r)
524 return r;
525
526 disk_super = dm_block_data(sblock);
527 read_superblock_fields(cmd, disk_super);
528 dm_bm_unlock(sblock);
529
530 return 0;
531}
532
533static int __commit_transaction(struct dm_cache_metadata *cmd,
534 flags_mutator mutator)
535{
536 int r;
537 size_t metadata_len;
538 struct cache_disk_superblock *disk_super;
539 struct dm_block *sblock;
540
541 /*
542 * We need to know if the cache_disk_superblock exceeds a 512-byte sector.
543 */
544 BUILD_BUG_ON(sizeof(struct cache_disk_superblock) > 512);
545
546 r = dm_bitset_flush(&cmd->discard_info, cmd->discard_root,
547 &cmd->discard_root);
548 if (r)
549 return r;
550
551 r = dm_tm_pre_commit(cmd->tm);
552 if (r < 0)
553 return r;
554
555 r = dm_sm_root_size(cmd->metadata_sm, &metadata_len);
556 if (r < 0)
557 return r;
558
559 r = superblock_lock(cmd, &sblock);
560 if (r)
561 return r;
562
563 disk_super = dm_block_data(sblock);
564
565 if (mutator)
566 update_flags(disk_super, mutator);
567
568 disk_super->mapping_root = cpu_to_le64(cmd->root);
569 disk_super->hint_root = cpu_to_le64(cmd->hint_root);
570 disk_super->discard_root = cpu_to_le64(cmd->discard_root);
571 disk_super->discard_block_size = cpu_to_le64(cmd->discard_block_size);
572 disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks));
573 disk_super->cache_blocks = cpu_to_le32(from_cblock(cmd->cache_blocks));
574 strncpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name));
575
576 disk_super->read_hits = cpu_to_le32(cmd->stats.read_hits);
577 disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses);
578 disk_super->write_hits = cpu_to_le32(cmd->stats.write_hits);
579 disk_super->write_misses = cpu_to_le32(cmd->stats.write_misses);
580
581 r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root,
582 metadata_len);
583 if (r < 0) {
584 dm_bm_unlock(sblock);
585 return r;
586 }
587
588 return dm_tm_commit(cmd->tm, sblock);
589}
590
591/*----------------------------------------------------------------*/
592
593/*
594 * The mappings are held in a dm-array that has 64-bit values stored in
595 * little-endian format. The index is the cblock, the high 48bits of the
596 * value are the oblock and the low 16 bit the flags.
597 */
598#define FLAGS_MASK ((1 << 16) - 1)
599
600static __le64 pack_value(dm_oblock_t block, unsigned flags)
601{
602 uint64_t value = from_oblock(block);
603 value <<= 16;
604 value = value | (flags & FLAGS_MASK);
605 return cpu_to_le64(value);
606}
607
608static void unpack_value(__le64 value_le, dm_oblock_t *block, unsigned *flags)
609{
610 uint64_t value = le64_to_cpu(value_le);
611 uint64_t b = value >> 16;
612 *block = to_oblock(b);
613 *flags = value & FLAGS_MASK;
614}
615
616/*----------------------------------------------------------------*/
617
618struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev,
619 sector_t data_block_size,
620 bool may_format_device,
621 size_t policy_hint_size)
622{
623 int r;
624 struct dm_cache_metadata *cmd;
625
626 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
627 if (!cmd) {
628 DMERR("could not allocate metadata struct");
629 return NULL;
630 }
631
632 init_rwsem(&cmd->root_lock);
633 cmd->bdev = bdev;
634 cmd->data_block_size = data_block_size;
635 cmd->cache_blocks = 0;
636 cmd->policy_hint_size = policy_hint_size;
637 cmd->changed = true;
638
639 r = __create_persistent_data_objects(cmd, may_format_device);
640 if (r) {
641 kfree(cmd);
642 return ERR_PTR(r);
643 }
644
645 r = __begin_transaction_flags(cmd, clear_clean_shutdown);
646 if (r < 0) {
647 dm_cache_metadata_close(cmd);
648 return ERR_PTR(r);
649 }
650
651 return cmd;
652}
653
654void dm_cache_metadata_close(struct dm_cache_metadata *cmd)
655{
656 __destroy_persistent_data_objects(cmd);
657 kfree(cmd);
658}
659
660int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size)
661{
662 int r;
663 __le64 null_mapping = pack_value(0, 0);
664
665 down_write(&cmd->root_lock);
666 __dm_bless_for_disk(&null_mapping);
667 r = dm_array_resize(&cmd->info, cmd->root, from_cblock(cmd->cache_blocks),
668 from_cblock(new_cache_size),
669 &null_mapping, &cmd->root);
670 if (!r)
671 cmd->cache_blocks = new_cache_size;
672 cmd->changed = true;
673 up_write(&cmd->root_lock);
674
675 return r;
676}
677
678int dm_cache_discard_bitset_resize(struct dm_cache_metadata *cmd,
679 sector_t discard_block_size,
680 dm_dblock_t new_nr_entries)
681{
682 int r;
683
684 down_write(&cmd->root_lock);
685 r = dm_bitset_resize(&cmd->discard_info,
686 cmd->discard_root,
687 from_dblock(cmd->discard_nr_blocks),
688 from_dblock(new_nr_entries),
689 false, &cmd->discard_root);
690 if (!r) {
691 cmd->discard_block_size = discard_block_size;
692 cmd->discard_nr_blocks = new_nr_entries;
693 }
694
695 cmd->changed = true;
696 up_write(&cmd->root_lock);
697
698 return r;
699}
700
701static int __set_discard(struct dm_cache_metadata *cmd, dm_dblock_t b)
702{
703 return dm_bitset_set_bit(&cmd->discard_info, cmd->discard_root,
704 from_dblock(b), &cmd->discard_root);
705}
706
707static int __clear_discard(struct dm_cache_metadata *cmd, dm_dblock_t b)
708{
709 return dm_bitset_clear_bit(&cmd->discard_info, cmd->discard_root,
710 from_dblock(b), &cmd->discard_root);
711}
712
713static int __is_discarded(struct dm_cache_metadata *cmd, dm_dblock_t b,
714 bool *is_discarded)
715{
716 return dm_bitset_test_bit(&cmd->discard_info, cmd->discard_root,
717 from_dblock(b), &cmd->discard_root,
718 is_discarded);
719}
720
721static int __discard(struct dm_cache_metadata *cmd,
722 dm_dblock_t dblock, bool discard)
723{
724 int r;
725
726 r = (discard ? __set_discard : __clear_discard)(cmd, dblock);
727 if (r)
728 return r;
729
730 cmd->changed = true;
731 return 0;
732}
733
734int dm_cache_set_discard(struct dm_cache_metadata *cmd,
735 dm_dblock_t dblock, bool discard)
736{
737 int r;
738
739 down_write(&cmd->root_lock);
740 r = __discard(cmd, dblock, discard);
741 up_write(&cmd->root_lock);
742
743 return r;
744}
745
746static int __load_discards(struct dm_cache_metadata *cmd,
747 load_discard_fn fn, void *context)
748{
749 int r = 0;
750 dm_block_t b;
751 bool discard;
752
753 for (b = 0; b < from_dblock(cmd->discard_nr_blocks); b++) {
754 dm_dblock_t dblock = to_dblock(b);
755
756 if (cmd->clean_when_opened) {
757 r = __is_discarded(cmd, dblock, &discard);
758 if (r)
759 return r;
760 } else
761 discard = false;
762
763 r = fn(context, cmd->discard_block_size, dblock, discard);
764 if (r)
765 break;
766 }
767
768 return r;
769}
770
771int dm_cache_load_discards(struct dm_cache_metadata *cmd,
772 load_discard_fn fn, void *context)
773{
774 int r;
775
776 down_read(&cmd->root_lock);
777 r = __load_discards(cmd, fn, context);
778 up_read(&cmd->root_lock);
779
780 return r;
781}
782
783dm_cblock_t dm_cache_size(struct dm_cache_metadata *cmd)
784{
785 dm_cblock_t r;
786
787 down_read(&cmd->root_lock);
788 r = cmd->cache_blocks;
789 up_read(&cmd->root_lock);
790
791 return r;
792}
793
794static int __remove(struct dm_cache_metadata *cmd, dm_cblock_t cblock)
795{
796 int r;
797 __le64 value = pack_value(0, 0);
798
799 __dm_bless_for_disk(&value);
800 r = dm_array_set_value(&cmd->info, cmd->root, from_cblock(cblock),
801 &value, &cmd->root);
802 if (r)
803 return r;
804
805 cmd->changed = true;
806 return 0;
807}
808
809int dm_cache_remove_mapping(struct dm_cache_metadata *cmd, dm_cblock_t cblock)
810{
811 int r;
812
813 down_write(&cmd->root_lock);
814 r = __remove(cmd, cblock);
815 up_write(&cmd->root_lock);
816
817 return r;
818}
819
820static int __insert(struct dm_cache_metadata *cmd,
821 dm_cblock_t cblock, dm_oblock_t oblock)
822{
823 int r;
824 __le64 value = pack_value(oblock, M_VALID);
825 __dm_bless_for_disk(&value);
826
827 r = dm_array_set_value(&cmd->info, cmd->root, from_cblock(cblock),
828 &value, &cmd->root);
829 if (r)
830 return r;
831
832 cmd->changed = true;
833 return 0;
834}
835
836int dm_cache_insert_mapping(struct dm_cache_metadata *cmd,
837 dm_cblock_t cblock, dm_oblock_t oblock)
838{
839 int r;
840
841 down_write(&cmd->root_lock);
842 r = __insert(cmd, cblock, oblock);
843 up_write(&cmd->root_lock);
844
845 return r;
846}
847
848struct thunk {
849 load_mapping_fn fn;
850 void *context;
851
852 struct dm_cache_metadata *cmd;
853 bool respect_dirty_flags;
854 bool hints_valid;
855};
856
857static bool hints_array_initialized(struct dm_cache_metadata *cmd)
858{
859 return cmd->hint_root && cmd->policy_hint_size;
860}
861
862static bool hints_array_available(struct dm_cache_metadata *cmd,
863 const char *policy_name)
864{
865 bool policy_names_match = !strncmp(cmd->policy_name, policy_name,
866 sizeof(cmd->policy_name));
867
868 return cmd->clean_when_opened && policy_names_match &&
869 hints_array_initialized(cmd);
870}
871
872static int __load_mapping(void *context, uint64_t cblock, void *leaf)
873{
874 int r = 0;
875 bool dirty;
876 __le64 value;
877 __le32 hint_value = 0;
878 dm_oblock_t oblock;
879 unsigned flags;
880 struct thunk *thunk = context;
881 struct dm_cache_metadata *cmd = thunk->cmd;
882
883 memcpy(&value, leaf, sizeof(value));
884 unpack_value(value, &oblock, &flags);
885
886 if (flags & M_VALID) {
887 if (thunk->hints_valid) {
888 r = dm_array_get_value(&cmd->hint_info, cmd->hint_root,
889 cblock, &hint_value);
890 if (r && r != -ENODATA)
891 return r;
892 }
893
894 dirty = thunk->respect_dirty_flags ? (flags & M_DIRTY) : true;
895 r = thunk->fn(thunk->context, oblock, to_cblock(cblock),
896 dirty, le32_to_cpu(hint_value), thunk->hints_valid);
897 }
898
899 return r;
900}
901
902static int __load_mappings(struct dm_cache_metadata *cmd, const char *policy_name,
903 load_mapping_fn fn, void *context)
904{
905 struct thunk thunk;
906
907 thunk.fn = fn;
908 thunk.context = context;
909
910 thunk.cmd = cmd;
911 thunk.respect_dirty_flags = cmd->clean_when_opened;
912 thunk.hints_valid = hints_array_available(cmd, policy_name);
913
914 return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk);
915}
916
917int dm_cache_load_mappings(struct dm_cache_metadata *cmd, const char *policy_name,
918 load_mapping_fn fn, void *context)
919{
920 int r;
921
922 down_read(&cmd->root_lock);
923 r = __load_mappings(cmd, policy_name, fn, context);
924 up_read(&cmd->root_lock);
925
926 return r;
927}
928
929static int __dump_mapping(void *context, uint64_t cblock, void *leaf)
930{
931 int r = 0;
932 __le64 value;
933 dm_oblock_t oblock;
934 unsigned flags;
935
936 memcpy(&value, leaf, sizeof(value));
937 unpack_value(value, &oblock, &flags);
938
939 return r;
940}
941
942static int __dump_mappings(struct dm_cache_metadata *cmd)
943{
944 return dm_array_walk(&cmd->info, cmd->root, __dump_mapping, NULL);
945}
946
947void dm_cache_dump(struct dm_cache_metadata *cmd)
948{
949 down_read(&cmd->root_lock);
950 __dump_mappings(cmd);
951 up_read(&cmd->root_lock);
952}
953
954int dm_cache_changed_this_transaction(struct dm_cache_metadata *cmd)
955{
956 int r;
957
958 down_read(&cmd->root_lock);
959 r = cmd->changed;
960 up_read(&cmd->root_lock);
961
962 return r;
963}
964
965static int __dirty(struct dm_cache_metadata *cmd, dm_cblock_t cblock, bool dirty)
966{
967 int r;
968 unsigned flags;
969 dm_oblock_t oblock;
970 __le64 value;
971
972 r = dm_array_get_value(&cmd->info, cmd->root, from_cblock(cblock), &value);
973 if (r)
974 return r;
975
976 unpack_value(value, &oblock, &flags);
977
978 if (((flags & M_DIRTY) && dirty) || (!(flags & M_DIRTY) && !dirty))
979 /* nothing to be done */
980 return 0;
981
982 value = pack_value(oblock, flags | (dirty ? M_DIRTY : 0));
983 __dm_bless_for_disk(&value);
984
985 r = dm_array_set_value(&cmd->info, cmd->root, from_cblock(cblock),
986 &value, &cmd->root);
987 if (r)
988 return r;
989
990 cmd->changed = true;
991 return 0;
992
993}
994
995int dm_cache_set_dirty(struct dm_cache_metadata *cmd,
996 dm_cblock_t cblock, bool dirty)
997{
998 int r;
999
1000 down_write(&cmd->root_lock);
1001 r = __dirty(cmd, cblock, dirty);
1002 up_write(&cmd->root_lock);
1003
1004 return r;
1005}
1006
1007void dm_cache_metadata_get_stats(struct dm_cache_metadata *cmd,
1008 struct dm_cache_statistics *stats)
1009{
1010 down_read(&cmd->root_lock);
1011 memcpy(stats, &cmd->stats, sizeof(*stats));
1012 up_read(&cmd->root_lock);
1013}
1014
1015void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd,
1016 struct dm_cache_statistics *stats)
1017{
1018 down_write(&cmd->root_lock);
1019 memcpy(&cmd->stats, stats, sizeof(*stats));
1020 up_write(&cmd->root_lock);
1021}
1022
1023int dm_cache_commit(struct dm_cache_metadata *cmd, bool clean_shutdown)
1024{
1025 int r;
1026 flags_mutator mutator = (clean_shutdown ? set_clean_shutdown :
1027 clear_clean_shutdown);
1028
1029 down_write(&cmd->root_lock);
1030 r = __commit_transaction(cmd, mutator);
1031 if (r)
1032 goto out;
1033
1034 r = __begin_transaction(cmd);
1035
1036out:
1037 up_write(&cmd->root_lock);
1038 return r;
1039}
1040
1041int dm_cache_get_free_metadata_block_count(struct dm_cache_metadata *cmd,
1042 dm_block_t *result)
1043{
1044 int r = -EINVAL;
1045
1046 down_read(&cmd->root_lock);
1047 r = dm_sm_get_nr_free(cmd->metadata_sm, result);
1048 up_read(&cmd->root_lock);
1049
1050 return r;
1051}
1052
1053int dm_cache_get_metadata_dev_size(struct dm_cache_metadata *cmd,
1054 dm_block_t *result)
1055{
1056 int r = -EINVAL;
1057
1058 down_read(&cmd->root_lock);
1059 r = dm_sm_get_nr_blocks(cmd->metadata_sm, result);
1060 up_read(&cmd->root_lock);
1061
1062 return r;
1063}
1064
1065/*----------------------------------------------------------------*/
1066
1067static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy)
1068{
1069 int r;
1070 __le32 value;
1071 size_t hint_size;
1072 const char *policy_name = dm_cache_policy_get_name(policy);
1073
1074 if (!policy_name[0] ||
1075 (strlen(policy_name) > sizeof(cmd->policy_name) - 1))
1076 return -EINVAL;
1077
1078 if (strcmp(cmd->policy_name, policy_name)) {
1079 strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name));
1080
1081 hint_size = dm_cache_policy_get_hint_size(policy);
1082 if (!hint_size)
1083 return 0; /* short-circuit hints initialization */
1084 cmd->policy_hint_size = hint_size;
1085
1086 if (cmd->hint_root) {
1087 r = dm_array_del(&cmd->hint_info, cmd->hint_root);
1088 if (r)
1089 return r;
1090 }
1091
1092 r = dm_array_empty(&cmd->hint_info, &cmd->hint_root);
1093 if (r)
1094 return r;
1095
1096 value = cpu_to_le32(0);
1097 __dm_bless_for_disk(&value);
1098 r = dm_array_resize(&cmd->hint_info, cmd->hint_root, 0,
1099 from_cblock(cmd->cache_blocks),
1100 &value, &cmd->hint_root);
1101 if (r)
1102 return r;
1103 }
1104
1105 return 0;
1106}
1107
1108int dm_cache_begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy)
1109{
1110 int r;
1111
1112 down_write(&cmd->root_lock);
1113 r = begin_hints(cmd, policy);
1114 up_write(&cmd->root_lock);
1115
1116 return r;
1117}
1118
1119static int save_hint(struct dm_cache_metadata *cmd, dm_cblock_t cblock,
1120 uint32_t hint)
1121{
1122 int r;
1123 __le32 value = cpu_to_le32(hint);
1124 __dm_bless_for_disk(&value);
1125
1126 r = dm_array_set_value(&cmd->hint_info, cmd->hint_root,
1127 from_cblock(cblock), &value, &cmd->hint_root);
1128 cmd->changed = true;
1129
1130 return r;
1131}
1132
1133int dm_cache_save_hint(struct dm_cache_metadata *cmd, dm_cblock_t cblock,
1134 uint32_t hint)
1135{
1136 int r;
1137
1138 if (!hints_array_initialized(cmd))
1139 return 0;
1140
1141 down_write(&cmd->root_lock);
1142 r = save_hint(cmd, cblock, hint);
1143 up_write(&cmd->root_lock);
1144
1145 return r;
1146}