summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-cache-metadata.c
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2016-09-22 06:15:21 -0400
committerMike Snitzer <snitzer@redhat.com>2017-02-16 13:12:47 -0500
commit629d0a8a1a104187db8fbf966e4cc5cfb6aa9a3c (patch)
treedf900a59355073aca34dd8de83d4ca631428cd6e /drivers/md/dm-cache-metadata.c
parentae4a46a1f60942263d6fd119fe1da49bb16d2bd5 (diff)
dm cache metadata: add "metadata2" feature
If "metadata2" is provided as a table argument when creating/loading a cache target a more compact metadata format, with separate dirty bits, is used. "metadata2" improves speed of shutting down a cache target. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-cache-metadata.c')
-rw-r--r--drivers/md/dm-cache-metadata.c278
1 files changed, 245 insertions, 33 deletions
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c
index 9364a02e1646..0610be7846dc 100644
--- a/drivers/md/dm-cache-metadata.c
+++ b/drivers/md/dm-cache-metadata.c
@@ -25,7 +25,7 @@
25 * defines a range of metadata versions that this module can handle. 25 * defines a range of metadata versions that this module can handle.
26 */ 26 */
27#define MIN_CACHE_VERSION 1 27#define MIN_CACHE_VERSION 1
28#define MAX_CACHE_VERSION 1 28#define MAX_CACHE_VERSION 2
29 29
30#define CACHE_METADATA_CACHE_SIZE 64 30#define CACHE_METADATA_CACHE_SIZE 64
31 31
@@ -55,6 +55,7 @@ enum mapping_bits {
55 55
56 /* 56 /*
57 * The data on the cache is different from that on the origin. 57 * The data on the cache is different from that on the origin.
58 * This flag is only used by metadata format 1.
58 */ 59 */
59 M_DIRTY = 2 60 M_DIRTY = 2
60}; 61};
@@ -93,12 +94,18 @@ struct cache_disk_superblock {
93 __le32 write_misses; 94 __le32 write_misses;
94 95
95 __le32 policy_version[CACHE_POLICY_VERSION_SIZE]; 96 __le32 policy_version[CACHE_POLICY_VERSION_SIZE];
97
98 /*
99 * Metadata format 2 fields.
100 */
101 __le64 dirty_root;
96} __packed; 102} __packed;
97 103
98struct dm_cache_metadata { 104struct dm_cache_metadata {
99 atomic_t ref_count; 105 atomic_t ref_count;
100 struct list_head list; 106 struct list_head list;
101 107
108 unsigned version;
102 struct block_device *bdev; 109 struct block_device *bdev;
103 struct dm_block_manager *bm; 110 struct dm_block_manager *bm;
104 struct dm_space_map *metadata_sm; 111 struct dm_space_map *metadata_sm;
@@ -142,11 +149,18 @@ struct dm_cache_metadata {
142 bool fail_io:1; 149 bool fail_io:1;
143 150
144 /* 151 /*
152 * Metadata format 2 fields.
153 */
154 dm_block_t dirty_root;
155 struct dm_disk_bitset dirty_info;
156
157 /*
145 * These structures are used when loading metadata. They're too 158 * These structures are used when loading metadata. They're too
146 * big to put on the stack. 159 * big to put on the stack.
147 */ 160 */
148 struct dm_array_cursor mapping_cursor; 161 struct dm_array_cursor mapping_cursor;
149 struct dm_array_cursor hint_cursor; 162 struct dm_array_cursor hint_cursor;
163 struct dm_bitset_cursor dirty_cursor;
150}; 164};
151 165
152/*------------------------------------------------------------------- 166/*-------------------------------------------------------------------
@@ -170,6 +184,7 @@ static void sb_prepare_for_write(struct dm_block_validator *v,
170static int check_metadata_version(struct cache_disk_superblock *disk_super) 184static int check_metadata_version(struct cache_disk_superblock *disk_super)
171{ 185{
172 uint32_t metadata_version = le32_to_cpu(disk_super->version); 186 uint32_t metadata_version = le32_to_cpu(disk_super->version);
187
173 if (metadata_version < MIN_CACHE_VERSION || metadata_version > MAX_CACHE_VERSION) { 188 if (metadata_version < MIN_CACHE_VERSION || metadata_version > MAX_CACHE_VERSION) {
174 DMERR("Cache metadata version %u found, but only versions between %u and %u supported.", 189 DMERR("Cache metadata version %u found, but only versions between %u and %u supported.",
175 metadata_version, MIN_CACHE_VERSION, MAX_CACHE_VERSION); 190 metadata_version, MIN_CACHE_VERSION, MAX_CACHE_VERSION);
@@ -310,6 +325,11 @@ static void __copy_sm_root(struct dm_cache_metadata *cmd,
310 sizeof(cmd->metadata_space_map_root)); 325 sizeof(cmd->metadata_space_map_root));
311} 326}
312 327
328static bool separate_dirty_bits(struct dm_cache_metadata *cmd)
329{
330 return cmd->version >= 2;
331}
332
313static int __write_initial_superblock(struct dm_cache_metadata *cmd) 333static int __write_initial_superblock(struct dm_cache_metadata *cmd)
314{ 334{
315 int r; 335 int r;
@@ -341,7 +361,7 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
341 disk_super->flags = 0; 361 disk_super->flags = 0;
342 memset(disk_super->uuid, 0, sizeof(disk_super->uuid)); 362 memset(disk_super->uuid, 0, sizeof(disk_super->uuid));
343 disk_super->magic = cpu_to_le64(CACHE_SUPERBLOCK_MAGIC); 363 disk_super->magic = cpu_to_le64(CACHE_SUPERBLOCK_MAGIC);
344 disk_super->version = cpu_to_le32(MAX_CACHE_VERSION); 364 disk_super->version = cpu_to_le32(cmd->version);
345 memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name)); 365 memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name));
346 memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version)); 366 memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version));
347 disk_super->policy_hint_size = 0; 367 disk_super->policy_hint_size = 0;
@@ -362,6 +382,9 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd)
362 disk_super->write_hits = cpu_to_le32(0); 382 disk_super->write_hits = cpu_to_le32(0);
363 disk_super->write_misses = cpu_to_le32(0); 383 disk_super->write_misses = cpu_to_le32(0);
364 384
385 if (separate_dirty_bits(cmd))
386 disk_super->dirty_root = cpu_to_le64(cmd->dirty_root);
387
365 return dm_tm_commit(cmd->tm, sblock); 388 return dm_tm_commit(cmd->tm, sblock);
366} 389}
367 390
@@ -382,6 +405,13 @@ static int __format_metadata(struct dm_cache_metadata *cmd)
382 if (r < 0) 405 if (r < 0)
383 goto bad; 406 goto bad;
384 407
408 if (separate_dirty_bits(cmd)) {
409 dm_disk_bitset_init(cmd->tm, &cmd->dirty_info);
410 r = dm_bitset_empty(&cmd->dirty_info, &cmd->dirty_root);
411 if (r < 0)
412 goto bad;
413 }
414
385 dm_disk_bitset_init(cmd->tm, &cmd->discard_info); 415 dm_disk_bitset_init(cmd->tm, &cmd->discard_info);
386 r = dm_bitset_empty(&cmd->discard_info, &cmd->discard_root); 416 r = dm_bitset_empty(&cmd->discard_info, &cmd->discard_root);
387 if (r < 0) 417 if (r < 0)
@@ -407,9 +437,10 @@ bad:
407static int __check_incompat_features(struct cache_disk_superblock *disk_super, 437static int __check_incompat_features(struct cache_disk_superblock *disk_super,
408 struct dm_cache_metadata *cmd) 438 struct dm_cache_metadata *cmd)
409{ 439{
410 uint32_t features; 440 uint32_t incompat_flags, features;
411 441
412 features = le32_to_cpu(disk_super->incompat_flags) & ~DM_CACHE_FEATURE_INCOMPAT_SUPP; 442 incompat_flags = le32_to_cpu(disk_super->incompat_flags);
443 features = incompat_flags & ~DM_CACHE_FEATURE_INCOMPAT_SUPP;
413 if (features) { 444 if (features) {
414 DMERR("could not access metadata due to unsupported optional features (%lx).", 445 DMERR("could not access metadata due to unsupported optional features (%lx).",
415 (unsigned long)features); 446 (unsigned long)features);
@@ -470,6 +501,7 @@ static int __open_metadata(struct dm_cache_metadata *cmd)
470 } 501 }
471 502
472 __setup_mapping_info(cmd); 503 __setup_mapping_info(cmd);
504 dm_disk_bitset_init(cmd->tm, &cmd->dirty_info);
473 dm_disk_bitset_init(cmd->tm, &cmd->discard_info); 505 dm_disk_bitset_init(cmd->tm, &cmd->discard_info);
474 sb_flags = le32_to_cpu(disk_super->flags); 506 sb_flags = le32_to_cpu(disk_super->flags);
475 cmd->clean_when_opened = test_bit(CLEAN_SHUTDOWN, &sb_flags); 507 cmd->clean_when_opened = test_bit(CLEAN_SHUTDOWN, &sb_flags);
@@ -548,6 +580,7 @@ static unsigned long clear_clean_shutdown(unsigned long flags)
548static void read_superblock_fields(struct dm_cache_metadata *cmd, 580static void read_superblock_fields(struct dm_cache_metadata *cmd,
549 struct cache_disk_superblock *disk_super) 581 struct cache_disk_superblock *disk_super)
550{ 582{
583 cmd->version = le32_to_cpu(disk_super->version);
551 cmd->flags = le32_to_cpu(disk_super->flags); 584 cmd->flags = le32_to_cpu(disk_super->flags);
552 cmd->root = le64_to_cpu(disk_super->mapping_root); 585 cmd->root = le64_to_cpu(disk_super->mapping_root);
553 cmd->hint_root = le64_to_cpu(disk_super->hint_root); 586 cmd->hint_root = le64_to_cpu(disk_super->hint_root);
@@ -567,6 +600,9 @@ static void read_superblock_fields(struct dm_cache_metadata *cmd,
567 cmd->stats.write_hits = le32_to_cpu(disk_super->write_hits); 600 cmd->stats.write_hits = le32_to_cpu(disk_super->write_hits);
568 cmd->stats.write_misses = le32_to_cpu(disk_super->write_misses); 601 cmd->stats.write_misses = le32_to_cpu(disk_super->write_misses);
569 602
603 if (separate_dirty_bits(cmd))
604 cmd->dirty_root = le64_to_cpu(disk_super->dirty_root);
605
570 cmd->changed = false; 606 cmd->changed = false;
571} 607}
572 608
@@ -625,6 +661,13 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
625 */ 661 */
626 BUILD_BUG_ON(sizeof(struct cache_disk_superblock) > 512); 662 BUILD_BUG_ON(sizeof(struct cache_disk_superblock) > 512);
627 663
664 if (separate_dirty_bits(cmd)) {
665 r = dm_bitset_flush(&cmd->dirty_info, cmd->dirty_root,
666 &cmd->dirty_root);
667 if (r)
668 return r;
669 }
670
628 r = dm_bitset_flush(&cmd->discard_info, cmd->discard_root, 671 r = dm_bitset_flush(&cmd->discard_info, cmd->discard_root,
629 &cmd->discard_root); 672 &cmd->discard_root);
630 if (r) 673 if (r)
@@ -649,6 +692,8 @@ static int __commit_transaction(struct dm_cache_metadata *cmd,
649 update_flags(disk_super, mutator); 692 update_flags(disk_super, mutator);
650 693
651 disk_super->mapping_root = cpu_to_le64(cmd->root); 694 disk_super->mapping_root = cpu_to_le64(cmd->root);
695 if (separate_dirty_bits(cmd))
696 disk_super->dirty_root = cpu_to_le64(cmd->dirty_root);
652 disk_super->hint_root = cpu_to_le64(cmd->hint_root); 697 disk_super->hint_root = cpu_to_le64(cmd->hint_root);
653 disk_super->discard_root = cpu_to_le64(cmd->discard_root); 698 disk_super->discard_root = cpu_to_le64(cmd->discard_root);
654 disk_super->discard_block_size = cpu_to_le64(cmd->discard_block_size); 699 disk_super->discard_block_size = cpu_to_le64(cmd->discard_block_size);
@@ -698,7 +743,8 @@ static void unpack_value(__le64 value_le, dm_oblock_t *block, unsigned *flags)
698static struct dm_cache_metadata *metadata_open(struct block_device *bdev, 743static struct dm_cache_metadata *metadata_open(struct block_device *bdev,
699 sector_t data_block_size, 744 sector_t data_block_size,
700 bool may_format_device, 745 bool may_format_device,
701 size_t policy_hint_size) 746 size_t policy_hint_size,
747 unsigned metadata_version)
702{ 748{
703 int r; 749 int r;
704 struct dm_cache_metadata *cmd; 750 struct dm_cache_metadata *cmd;
@@ -709,6 +755,7 @@ static struct dm_cache_metadata *metadata_open(struct block_device *bdev,
709 return ERR_PTR(-ENOMEM); 755 return ERR_PTR(-ENOMEM);
710 } 756 }
711 757
758 cmd->version = metadata_version;
712 atomic_set(&cmd->ref_count, 1); 759 atomic_set(&cmd->ref_count, 1);
713 init_rwsem(&cmd->root_lock); 760 init_rwsem(&cmd->root_lock);
714 cmd->bdev = bdev; 761 cmd->bdev = bdev;
@@ -757,7 +804,8 @@ static struct dm_cache_metadata *lookup(struct block_device *bdev)
757static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev, 804static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev,
758 sector_t data_block_size, 805 sector_t data_block_size,
759 bool may_format_device, 806 bool may_format_device,
760 size_t policy_hint_size) 807 size_t policy_hint_size,
808 unsigned metadata_version)
761{ 809{
762 struct dm_cache_metadata *cmd, *cmd2; 810 struct dm_cache_metadata *cmd, *cmd2;
763 811
@@ -768,7 +816,8 @@ static struct dm_cache_metadata *lookup_or_open(struct block_device *bdev,
768 if (cmd) 816 if (cmd)
769 return cmd; 817 return cmd;
770 818
771 cmd = metadata_open(bdev, data_block_size, may_format_device, policy_hint_size); 819 cmd = metadata_open(bdev, data_block_size, may_format_device,
820 policy_hint_size, metadata_version);
772 if (!IS_ERR(cmd)) { 821 if (!IS_ERR(cmd)) {
773 mutex_lock(&table_lock); 822 mutex_lock(&table_lock);
774 cmd2 = lookup(bdev); 823 cmd2 = lookup(bdev);
@@ -800,10 +849,11 @@ static bool same_params(struct dm_cache_metadata *cmd, sector_t data_block_size)
800struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev, 849struct dm_cache_metadata *dm_cache_metadata_open(struct block_device *bdev,
801 sector_t data_block_size, 850 sector_t data_block_size,
802 bool may_format_device, 851 bool may_format_device,
803 size_t policy_hint_size) 852 size_t policy_hint_size,
853 unsigned metadata_version)
804{ 854{
805 struct dm_cache_metadata *cmd = lookup_or_open(bdev, data_block_size, 855 struct dm_cache_metadata *cmd = lookup_or_open(bdev, data_block_size, may_format_device,
806 may_format_device, policy_hint_size); 856 policy_hint_size, metadata_version);
807 857
808 if (!IS_ERR(cmd) && !same_params(cmd, data_block_size)) { 858 if (!IS_ERR(cmd) && !same_params(cmd, data_block_size)) {
809 dm_cache_metadata_close(cmd); 859 dm_cache_metadata_close(cmd);
@@ -829,8 +879,8 @@ void dm_cache_metadata_close(struct dm_cache_metadata *cmd)
829/* 879/*
830 * Checks that the given cache block is either unmapped or clean. 880 * Checks that the given cache block is either unmapped or clean.
831 */ 881 */
832static int block_unmapped_or_clean(struct dm_cache_metadata *cmd, dm_cblock_t b, 882static int block_clean_combined_dirty(struct dm_cache_metadata *cmd, dm_cblock_t b,
833 bool *result) 883 bool *result)
834{ 884{
835 int r; 885 int r;
836 __le64 value; 886 __le64 value;
@@ -838,10 +888,8 @@ static int block_unmapped_or_clean(struct dm_cache_metadata *cmd, dm_cblock_t b,
838 unsigned flags; 888 unsigned flags;
839 889
840 r = dm_array_get_value(&cmd->info, cmd->root, from_cblock(b), &value); 890 r = dm_array_get_value(&cmd->info, cmd->root, from_cblock(b), &value);
841 if (r) { 891 if (r)
842 DMERR("block_unmapped_or_clean failed");
843 return r; 892 return r;
844 }
845 893
846 unpack_value(value, &ob, &flags); 894 unpack_value(value, &ob, &flags);
847 *result = !((flags & M_VALID) && (flags & M_DIRTY)); 895 *result = !((flags & M_VALID) && (flags & M_DIRTY));
@@ -849,17 +897,19 @@ static int block_unmapped_or_clean(struct dm_cache_metadata *cmd, dm_cblock_t b,
849 return 0; 897 return 0;
850} 898}
851 899
852static int blocks_are_unmapped_or_clean(struct dm_cache_metadata *cmd, 900static int blocks_are_clean_combined_dirty(struct dm_cache_metadata *cmd,
853 dm_cblock_t begin, dm_cblock_t end, 901 dm_cblock_t begin, dm_cblock_t end,
854 bool *result) 902 bool *result)
855{ 903{
856 int r; 904 int r;
857 *result = true; 905 *result = true;
858 906
859 while (begin != end) { 907 while (begin != end) {
860 r = block_unmapped_or_clean(cmd, begin, result); 908 r = block_clean_combined_dirty(cmd, begin, result);
861 if (r) 909 if (r) {
910 DMERR("block_clean_combined_dirty failed");
862 return r; 911 return r;
912 }
863 913
864 if (!*result) { 914 if (!*result) {
865 DMERR("cache block %llu is dirty", 915 DMERR("cache block %llu is dirty",
@@ -873,6 +923,48 @@ static int blocks_are_unmapped_or_clean(struct dm_cache_metadata *cmd,
873 return 0; 923 return 0;
874} 924}
875 925
926static int blocks_are_clean_separate_dirty(struct dm_cache_metadata *cmd,
927 dm_cblock_t begin, dm_cblock_t end,
928 bool *result)
929{
930 int r;
931 bool dirty_flag;
932 *result = true;
933
934 // FIXME: use a cursor so we can benefit from preloading metadata.
935 while (begin != end) {
936 /*
937 * We assume that unmapped blocks have their dirty bit
938 * cleared.
939 */
940 r = dm_bitset_test_bit(&cmd->dirty_info, cmd->dirty_root,
941 from_cblock(begin), &cmd->dirty_root, &dirty_flag);
942 if (r)
943 return r;
944
945 if (dirty_flag) {
946 DMERR("cache block %llu is dirty",
947 (unsigned long long) from_cblock(begin));
948 *result = false;
949 return 0;
950 }
951
952 begin = to_cblock(from_cblock(begin) + 1);
953 }
954
955 return 0;
956}
957
958static int blocks_are_unmapped_or_clean(struct dm_cache_metadata *cmd,
959 dm_cblock_t begin, dm_cblock_t end,
960 bool *result)
961{
962 if (separate_dirty_bits(cmd))
963 return blocks_are_clean_separate_dirty(cmd, begin, end, result);
964 else
965 return blocks_are_clean_combined_dirty(cmd, begin, end, result);
966}
967
876static bool cmd_write_lock(struct dm_cache_metadata *cmd) 968static bool cmd_write_lock(struct dm_cache_metadata *cmd)
877{ 969{
878 down_write(&cmd->root_lock); 970 down_write(&cmd->root_lock);
@@ -950,8 +1042,18 @@ int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size)
950 r = dm_array_resize(&cmd->info, cmd->root, from_cblock(cmd->cache_blocks), 1042 r = dm_array_resize(&cmd->info, cmd->root, from_cblock(cmd->cache_blocks),
951 from_cblock(new_cache_size), 1043 from_cblock(new_cache_size),
952 &null_mapping, &cmd->root); 1044 &null_mapping, &cmd->root);
953 if (!r) 1045 if (r)
954 cmd->cache_blocks = new_cache_size; 1046 goto out;
1047
1048 if (separate_dirty_bits(cmd)) {
1049 r = dm_bitset_resize(&cmd->dirty_info, cmd->dirty_root,
1050 from_cblock(cmd->cache_blocks), from_cblock(new_cache_size),
1051 false, &cmd->dirty_root);
1052 if (r)
1053 goto out;
1054 }
1055
1056 cmd->cache_blocks = new_cache_size;
955 cmd->changed = true; 1057 cmd->changed = true;
956 1058
957out: 1059out:
@@ -1185,11 +1287,11 @@ static bool hints_array_available(struct dm_cache_metadata *cmd,
1185 hints_array_initialized(cmd); 1287 hints_array_initialized(cmd);
1186} 1288}
1187 1289
1188static int __load_mapping(struct dm_cache_metadata *cmd, 1290static int __load_mapping_v1(struct dm_cache_metadata *cmd,
1189 uint64_t cb, bool hints_valid, 1291 uint64_t cb, bool hints_valid,
1190 struct dm_array_cursor *mapping_cursor, 1292 struct dm_array_cursor *mapping_cursor,
1191 struct dm_array_cursor *hint_cursor, 1293 struct dm_array_cursor *hint_cursor,
1192 load_mapping_fn fn, void *context) 1294 load_mapping_fn fn, void *context)
1193{ 1295{
1194 int r = 0; 1296 int r = 0;
1195 1297
@@ -1221,6 +1323,45 @@ static int __load_mapping(struct dm_cache_metadata *cmd,
1221 return r; 1323 return r;
1222} 1324}
1223 1325
1326static int __load_mapping_v2(struct dm_cache_metadata *cmd,
1327 uint64_t cb, bool hints_valid,
1328 struct dm_array_cursor *mapping_cursor,
1329 struct dm_array_cursor *hint_cursor,
1330 struct dm_bitset_cursor *dirty_cursor,
1331 load_mapping_fn fn, void *context)
1332{
1333 int r = 0;
1334
1335 __le64 mapping;
1336 __le32 hint = 0;
1337
1338 __le64 *mapping_value_le;
1339 __le32 *hint_value_le;
1340
1341 dm_oblock_t oblock;
1342 unsigned flags;
1343 bool dirty;
1344
1345 dm_array_cursor_get_value(mapping_cursor, (void **) &mapping_value_le);
1346 memcpy(&mapping, mapping_value_le, sizeof(mapping));
1347 unpack_value(mapping, &oblock, &flags);
1348
1349 if (flags & M_VALID) {
1350 if (hints_valid) {
1351 dm_array_cursor_get_value(hint_cursor, (void **) &hint_value_le);
1352 memcpy(&hint, hint_value_le, sizeof(hint));
1353 }
1354
1355 dirty = dm_bitset_cursor_get_value(dirty_cursor);
1356 r = fn(context, oblock, to_cblock(cb), dirty,
1357 le32_to_cpu(hint), hints_valid);
1358 if (r)
1359 DMERR("policy couldn't load cblock");
1360 }
1361
1362 return r;
1363}
1364
1224static int __load_mappings(struct dm_cache_metadata *cmd, 1365static int __load_mappings(struct dm_cache_metadata *cmd,
1225 struct dm_cache_policy *policy, 1366 struct dm_cache_policy *policy,
1226 load_mapping_fn fn, void *context) 1367 load_mapping_fn fn, void *context)
@@ -1246,10 +1387,28 @@ static int __load_mappings(struct dm_cache_metadata *cmd,
1246 } 1387 }
1247 } 1388 }
1248 1389
1390 if (separate_dirty_bits(cmd)) {
1391 r = dm_bitset_cursor_begin(&cmd->dirty_info, cmd->dirty_root,
1392 from_cblock(cmd->cache_blocks),
1393 &cmd->dirty_cursor);
1394 if (r) {
1395 dm_array_cursor_end(&cmd->hint_cursor);
1396 dm_array_cursor_end(&cmd->mapping_cursor);
1397 return r;
1398 }
1399 }
1400
1249 for (cb = 0; ; cb++) { 1401 for (cb = 0; ; cb++) {
1250 r = __load_mapping(cmd, cb, hints_valid, 1402 if (separate_dirty_bits(cmd))
1251 &cmd->mapping_cursor, &cmd->hint_cursor, 1403 r = __load_mapping_v2(cmd, cb, hints_valid,
1252 fn, context); 1404 &cmd->mapping_cursor,
1405 &cmd->hint_cursor,
1406 &cmd->dirty_cursor,
1407 fn, context);
1408 else
1409 r = __load_mapping_v1(cmd, cb, hints_valid,
1410 &cmd->mapping_cursor, &cmd->hint_cursor,
1411 fn, context);
1253 if (r) 1412 if (r)
1254 goto out; 1413 goto out;
1255 1414
@@ -1272,12 +1431,23 @@ static int __load_mappings(struct dm_cache_metadata *cmd,
1272 goto out; 1431 goto out;
1273 } 1432 }
1274 } 1433 }
1434
1435 if (separate_dirty_bits(cmd)) {
1436 r = dm_bitset_cursor_next(&cmd->dirty_cursor);
1437 if (r) {
1438 DMERR("dm_bitset_cursor_next for dirty failed");
1439 goto out;
1440 }
1441 }
1275 } 1442 }
1276out: 1443out:
1277 dm_array_cursor_end(&cmd->mapping_cursor); 1444 dm_array_cursor_end(&cmd->mapping_cursor);
1278 if (hints_valid) 1445 if (hints_valid)
1279 dm_array_cursor_end(&cmd->hint_cursor); 1446 dm_array_cursor_end(&cmd->hint_cursor);
1280 1447
1448 if (separate_dirty_bits(cmd))
1449 dm_bitset_cursor_end(&cmd->dirty_cursor);
1450
1281 return r; 1451 return r;
1282} 1452}
1283 1453
@@ -1360,13 +1530,55 @@ static int __dirty(struct dm_cache_metadata *cmd, dm_cblock_t cblock, bool dirty
1360 1530
1361} 1531}
1362 1532
1363int dm_cache_set_dirty(struct dm_cache_metadata *cmd, 1533static int __set_dirty_bits_v1(struct dm_cache_metadata *cmd, unsigned nr_bits, unsigned long *bits)
1364 dm_cblock_t cblock, bool dirty) 1534{
1535 int r;
1536 unsigned i;
1537 for (i = 0; i < nr_bits; i++) {
1538 r = __dirty(cmd, to_cblock(i), test_bit(i, bits));
1539 if (r)
1540 return r;
1541 }
1542
1543 return 0;
1544}
1545
1546static int __set_dirty_bits_v2(struct dm_cache_metadata *cmd, unsigned nr_bits, unsigned long *bits)
1547{
1548 int r = 0;
1549 unsigned i;
1550
1551 /* nr_bits is really just a sanity check */
1552 if (nr_bits != from_cblock(cmd->cache_blocks)) {
1553 DMERR("dirty bitset is wrong size");
1554 return -EINVAL;
1555 }
1556
1557 for (i = 0; i < nr_bits; i++) {
1558 if (test_bit(i, bits))
1559 r = dm_bitset_set_bit(&cmd->dirty_info, cmd->dirty_root, i, &cmd->dirty_root);
1560 else
1561 r = dm_bitset_clear_bit(&cmd->dirty_info, cmd->dirty_root, i, &cmd->dirty_root);
1562
1563 if (r)
1564 return r;
1565 }
1566
1567 cmd->changed = true;
1568 return dm_bitset_flush(&cmd->dirty_info, cmd->dirty_root, &cmd->dirty_root);
1569}
1570
1571int dm_cache_set_dirty_bits(struct dm_cache_metadata *cmd,
1572 unsigned nr_bits,
1573 unsigned long *bits)
1365{ 1574{
1366 int r; 1575 int r;
1367 1576
1368 WRITE_LOCK(cmd); 1577 WRITE_LOCK(cmd);
1369 r = __dirty(cmd, cblock, dirty); 1578 if (separate_dirty_bits(cmd))
1579 r = __set_dirty_bits_v2(cmd, nr_bits, bits);
1580 else
1581 r = __set_dirty_bits_v1(cmd, nr_bits, bits);
1370 WRITE_UNLOCK(cmd); 1582 WRITE_UNLOCK(cmd);
1371 1583
1372 return r; 1584 return r;