Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

dm cache: add fail io mode and needs_check flag

If a cache metadata operation fails (e.g. transaction commit) the
cache's metadata device will abort the current transaction, set a new
needs_check flag, and the cache will transition to "read-only" mode. If
aborting the transaction or setting the needs_check flag fails the cache
will transition to "fail-io" mode.

Once needs_check is set the cache device will not be allowed to
activate. Activation requires write access to metadata. Future work is
needed to add proper support for running the cache in read-only mode.

Once in fail-io mode the cache will report a status of "Fail".

Also, add commit() wrapper that will disallow commits if in read_only or
fail mode.

Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>

authored by

Joe Thornber and committed by
Mike Snitzer
028ae9f7 88bf5184

+320 -58
+7 -2
Documentation/device-mapper/cache.txt
··· 221 221 <#read hits> <#read misses> <#write hits> <#write misses> 222 222 <#demotions> <#promotions> <#dirty> <#features> <features>* 223 223 <#core args> <core args>* <policy name> <#policy args> <policy args>* 224 + <cache metadata mode> 224 225 225 226 metadata block size : Fixed block size for each metadata block in 226 227 sectors ··· 252 251 e.g. migration_threshold 253 252 policy name : Name of the policy 254 253 #policy args : Number of policy arguments to follow (must be even) 255 - policy args : Key/value pairs 256 - e.g. sequential_threshold 254 + policy args : Key/value pairs e.g. sequential_threshold 255 + cache metadata mode : ro if read-only, rw if read-write 256 + In serious cases where even a read-only mode is deemed unsafe 257 + no further I/O will be permitted and the status will just 258 + contain the string 'Fail'. The userspace recovery tools 259 + should then be used. 257 260 258 261 Messages 259 262 --------
+114 -19
drivers/md/dm-cache-metadata.c
··· 39 39 enum superblock_flag_bits { 40 40 /* for spotting crashes that would invalidate the dirty bitset */ 41 41 CLEAN_SHUTDOWN, 42 + /* metadata must be checked using the tools */ 43 + NEEDS_CHECK, 42 44 }; 43 45 44 46 /* ··· 109 107 struct dm_disk_bitset discard_info; 110 108 111 109 struct rw_semaphore root_lock; 110 + unsigned long flags; 112 111 dm_block_t root; 113 112 dm_block_t hint_root; 114 113 dm_block_t discard_root; ··· 132 129 * buffer before the superblock is locked and updated. 133 130 */ 134 131 __u8 metadata_space_map_root[SPACE_MAP_ROOT_SIZE]; 132 + 133 + /* 134 + * Set if a transaction has to be aborted but the attempt to roll 135 + * back to the previous (good) transaction failed. The only 136 + * metadata operation permissible in this state is the closing of 137 + * the device. 138 + */ 139 + bool fail_io:1; 135 140 }; 136 141 137 142 /*------------------------------------------------------------------- ··· 538 527 static void read_superblock_fields(struct dm_cache_metadata *cmd, 539 528 struct cache_disk_superblock *disk_super) 540 529 { 530 + cmd->flags = le32_to_cpu(disk_super->flags); 541 531 cmd->root = le64_to_cpu(disk_super->mapping_root); 542 532 cmd->hint_root = le64_to_cpu(disk_super->hint_root); 543 533 cmd->discard_root = le64_to_cpu(disk_super->discard_root); ··· 637 625 if (mutator) 638 626 update_flags(disk_super, mutator); 639 627 628 + disk_super->flags = cpu_to_le32(cmd->flags); 640 629 disk_super->mapping_root = cpu_to_le64(cmd->root); 641 630 disk_super->hint_root = cpu_to_le64(cmd->hint_root); 642 631 disk_super->discard_root = cpu_to_le64(cmd->discard_root); ··· 706 693 cmd->cache_blocks = 0; 707 694 cmd->policy_hint_size = policy_hint_size; 708 695 cmd->changed = true; 696 + cmd->fail_io = false; 709 697 710 698 r = __create_persistent_data_objects(cmd, may_format_device); 711 699 if (r) { ··· 810 796 list_del(&cmd->list); 811 797 mutex_unlock(&table_lock); 812 798 813 - __destroy_persistent_data_objects(cmd); 799 + if (!cmd->fail_io) 800 + __destroy_persistent_data_objects(cmd); 814 801 kfree(cmd); 815 802 } 816 803 } ··· 863 848 return 0; 864 849 } 865 850 851 + #define WRITE_LOCK(cmd) \ 852 + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \ 853 + return -EINVAL; \ 854 + down_write(&cmd->root_lock) 855 + 856 + #define WRITE_LOCK_VOID(cmd) \ 857 + if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \ 858 + return; \ 859 + down_write(&cmd->root_lock) 860 + 861 + #define WRITE_UNLOCK(cmd) \ 862 + up_write(&cmd->root_lock) 863 + 866 864 int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size) 867 865 { 868 866 int r; 869 867 bool clean; 870 868 __le64 null_mapping = pack_value(0, 0); 871 869 872 - down_write(&cmd->root_lock); 870 + WRITE_LOCK(cmd); 873 871 __dm_bless_for_disk(&null_mapping); 874 872 875 873 if (from_cblock(new_cache_size) < from_cblock(cmd->cache_blocks)) { ··· 908 880 cmd->changed = true; 909 881 910 882 out: 911 - up_write(&cmd->root_lock); 883 + WRITE_UNLOCK(cmd); 912 884 913 885 return r; 914 886 } ··· 919 891 { 920 892 int r; 921 893 922 - down_write(&cmd->root_lock); 894 + WRITE_LOCK(cmd); 923 895 r = dm_bitset_resize(&cmd->discard_info, 924 896 cmd->discard_root, 925 897 from_dblock(cmd->discard_nr_blocks), ··· 931 903 } 932 904 933 905 cmd->changed = true; 934 - up_write(&cmd->root_lock); 906 + WRITE_UNLOCK(cmd); 935 907 936 908 return r; 937 909 } ··· 974 946 { 975 947 int r; 976 948 977 - down_write(&cmd->root_lock); 949 + WRITE_LOCK(cmd); 978 950 r = __discard(cmd, dblock, discard); 979 - up_write(&cmd->root_lock); 951 + WRITE_UNLOCK(cmd); 980 952 981 953 return r; 982 954 } ··· 1048 1020 { 1049 1021 int r; 1050 1022 1051 - down_write(&cmd->root_lock); 1023 + WRITE_LOCK(cmd); 1052 1024 r = __remove(cmd, cblock); 1053 - up_write(&cmd->root_lock); 1025 + WRITE_UNLOCK(cmd); 1054 1026 1055 1027 return r; 1056 1028 } ··· 1076 1048 { 1077 1049 int r; 1078 1050 1079 - down_write(&cmd->root_lock); 1051 + WRITE_LOCK(cmd); 1080 1052 r = __insert(cmd, cblock, oblock); 1081 - up_write(&cmd->root_lock); 1053 + WRITE_UNLOCK(cmd); 1082 1054 1083 1055 return r; 1084 1056 } ··· 1262 1234 { 1263 1235 int r; 1264 1236 1265 - down_write(&cmd->root_lock); 1237 + WRITE_LOCK(cmd); 1266 1238 r = __dirty(cmd, cblock, dirty); 1267 - up_write(&cmd->root_lock); 1239 + WRITE_UNLOCK(cmd); 1268 1240 1269 1241 return r; 1270 1242 } ··· 1280 1252 void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd, 1281 1253 struct dm_cache_statistics *stats) 1282 1254 { 1283 - down_write(&cmd->root_lock); 1255 + WRITE_LOCK_VOID(cmd); 1284 1256 cmd->stats = *stats; 1285 - up_write(&cmd->root_lock); 1257 + WRITE_UNLOCK(cmd); 1286 1258 } 1287 1259 1288 1260 int dm_cache_commit(struct dm_cache_metadata *cmd, bool clean_shutdown) ··· 1291 1263 flags_mutator mutator = (clean_shutdown ? set_clean_shutdown : 1292 1264 clear_clean_shutdown); 1293 1265 1294 - down_write(&cmd->root_lock); 1266 + WRITE_LOCK(cmd); 1295 1267 r = __commit_transaction(cmd, mutator); 1296 1268 if (r) 1297 1269 goto out; ··· 1299 1271 r = __begin_transaction(cmd); 1300 1272 1301 1273 out: 1302 - up_write(&cmd->root_lock); 1274 + WRITE_UNLOCK(cmd); 1303 1275 return r; 1304 1276 } 1305 1277 ··· 1404 1376 { 1405 1377 int r; 1406 1378 1407 - down_write(&cmd->root_lock); 1379 + WRITE_LOCK(cmd); 1408 1380 r = write_hints(cmd, policy); 1409 - up_write(&cmd->root_lock); 1381 + WRITE_UNLOCK(cmd); 1410 1382 1411 1383 return r; 1412 1384 } ··· 1414 1386 int dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result) 1415 1387 { 1416 1388 return blocks_are_unmapped_or_clean(cmd, 0, cmd->cache_blocks, result); 1389 + } 1390 + 1391 + void dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd) 1392 + { 1393 + WRITE_LOCK_VOID(cmd); 1394 + dm_bm_set_read_only(cmd->bm); 1395 + WRITE_UNLOCK(cmd); 1396 + } 1397 + 1398 + void dm_cache_metadata_set_read_write(struct dm_cache_metadata *cmd) 1399 + { 1400 + WRITE_LOCK_VOID(cmd); 1401 + dm_bm_set_read_write(cmd->bm); 1402 + WRITE_UNLOCK(cmd); 1403 + } 1404 + 1405 + int dm_cache_metadata_set_needs_check(struct dm_cache_metadata *cmd) 1406 + { 1407 + int r; 1408 + struct dm_block *sblock; 1409 + struct cache_disk_superblock *disk_super; 1410 + 1411 + /* 1412 + * We ignore fail_io for this function. 1413 + */ 1414 + down_write(&cmd->root_lock); 1415 + set_bit(NEEDS_CHECK, &cmd->flags); 1416 + 1417 + r = superblock_lock(cmd, &sblock); 1418 + if (r) { 1419 + DMERR("couldn't read superblock"); 1420 + goto out; 1421 + } 1422 + 1423 + disk_super = dm_block_data(sblock); 1424 + disk_super->flags = cpu_to_le32(cmd->flags); 1425 + 1426 + dm_bm_unlock(sblock); 1427 + 1428 + out: 1429 + up_write(&cmd->root_lock); 1430 + return r; 1431 + } 1432 + 1433 + bool dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd) 1434 + { 1435 + bool needs_check; 1436 + 1437 + down_read(&cmd->root_lock); 1438 + needs_check = !!test_bit(NEEDS_CHECK, &cmd->flags); 1439 + up_read(&cmd->root_lock); 1440 + 1441 + return needs_check; 1442 + } 1443 + 1444 + int dm_cache_metadata_abort(struct dm_cache_metadata *cmd) 1445 + { 1446 + int r; 1447 + 1448 + WRITE_LOCK(cmd); 1449 + __destroy_persistent_data_objects(cmd); 1450 + r = __create_persistent_data_objects(cmd, false); 1451 + if (r) 1452 + cmd->fail_io = true; 1453 + WRITE_UNLOCK(cmd); 1454 + 1455 + return r; 1417 1456 }
+10
drivers/md/dm-cache-metadata.h
··· 102 102 103 103 void dm_cache_metadata_get_stats(struct dm_cache_metadata *cmd, 104 104 struct dm_cache_statistics *stats); 105 + 106 + /* 107 + * 'void' because it's no big deal if it fails. 108 + */ 105 109 void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd, 106 110 struct dm_cache_statistics *stats); 107 111 ··· 136 132 * Query method. Are all the blocks in the cache clean? 137 133 */ 138 134 int dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result); 135 + 136 + bool dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd); 137 + int dm_cache_metadata_set_needs_check(struct dm_cache_metadata *cmd); 138 + void dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd); 139 + void dm_cache_metadata_set_read_write(struct dm_cache_metadata *cmd); 140 + int dm_cache_metadata_abort(struct dm_cache_metadata *cmd); 139 141 140 142 /*----------------------------------------------------------------*/ 141 143
+6 -4
drivers/md/dm-cache-policy-internal.h
··· 89 89 return p->tick(p); 90 90 } 91 91 92 - static inline int policy_emit_config_values(struct dm_cache_policy *p, char *result, unsigned maxlen) 92 + static inline int policy_emit_config_values(struct dm_cache_policy *p, char *result, 93 + unsigned maxlen, ssize_t *sz_ptr) 93 94 { 94 - ssize_t sz = 0; 95 + ssize_t sz = *sz_ptr; 95 96 if (p->emit_config_values) 96 - return p->emit_config_values(p, result, maxlen); 97 + return p->emit_config_values(p, result, maxlen, sz_ptr); 97 98 98 - DMEMIT("0"); 99 + DMEMIT("0 "); 100 + *sz_ptr = sz; 99 101 return 0; 100 102 } 101 103
+5 -3
drivers/md/dm-cache-policy-mq.c
··· 1323 1323 return 0; 1324 1324 } 1325 1325 1326 - static int mq_emit_config_values(struct dm_cache_policy *p, char *result, unsigned maxlen) 1326 + static int mq_emit_config_values(struct dm_cache_policy *p, char *result, 1327 + unsigned maxlen, ssize_t *sz_ptr) 1327 1328 { 1328 - ssize_t sz = 0; 1329 + ssize_t sz = *sz_ptr; 1329 1330 struct mq_policy *mq = to_mq_policy(p); 1330 1331 1331 1332 DMEMIT("10 random_threshold %u " 1332 1333 "sequential_threshold %u " 1333 1334 "discard_promote_adjustment %u " 1334 1335 "read_promote_adjustment %u " 1335 - "write_promote_adjustment %u", 1336 + "write_promote_adjustment %u ", 1336 1337 mq->tracker.thresholds[PATTERN_RANDOM], 1337 1338 mq->tracker.thresholds[PATTERN_SEQUENTIAL], 1338 1339 mq->discard_promote_adjustment, 1339 1340 mq->read_promote_adjustment, 1340 1341 mq->write_promote_adjustment); 1341 1342 1343 + *sz_ptr = sz; 1342 1344 return 0; 1343 1345 } 1344 1346
+2 -2
drivers/md/dm-cache-policy.h
··· 208 208 /* 209 209 * Configuration. 210 210 */ 211 - int (*emit_config_values)(struct dm_cache_policy *p, 212 - char *result, unsigned maxlen); 211 + int (*emit_config_values)(struct dm_cache_policy *p, char *result, 212 + unsigned maxlen, ssize_t *sz_ptr); 213 213 int (*set_config_value)(struct dm_cache_policy *p, 214 214 const char *key, const char *value); 215 215
+176 -28
drivers/md/dm-cache-target.c
··· 150 150 #define DATA_DEV_BLOCK_SIZE_MIN_SECTORS (32 * 1024 >> SECTOR_SHIFT) 151 151 #define DATA_DEV_BLOCK_SIZE_MAX_SECTORS (1024 * 1024 * 1024 >> SECTOR_SHIFT) 152 152 153 - /* 154 - * FIXME: the cache is read/write for the time being. 155 - */ 156 153 enum cache_metadata_mode { 157 154 CM_WRITE, /* metadata may be changed */ 158 155 CM_READ_ONLY, /* metadata may not be changed */ 156 + CM_FAIL 159 157 }; 160 158 161 159 enum cache_io_mode { ··· 382 384 struct dm_bio_prison_cell *cell1; 383 385 struct dm_bio_prison_cell *cell2; 384 386 }; 387 + 388 + static enum cache_metadata_mode get_cache_mode(struct cache *cache); 385 389 386 390 static void wake_worker(struct cache *cache) 387 391 { ··· 699 699 { 700 700 struct dm_cache_statistics stats; 701 701 702 + if (get_cache_mode(cache) >= CM_READ_ONLY) 703 + return; 704 + 702 705 stats.read_hits = atomic_read(&cache->stats.read_hit); 703 706 stats.read_misses = atomic_read(&cache->stats.read_miss); 704 707 stats.write_hits = atomic_read(&cache->stats.write_hit); ··· 961 958 } 962 959 963 960 /*---------------------------------------------------------------- 961 + * Failure modes 962 + *--------------------------------------------------------------*/ 963 + static enum cache_metadata_mode get_cache_mode(struct cache *cache) 964 + { 965 + return cache->features.mode; 966 + } 967 + 968 + static void notify_mode_switch(struct cache *cache, enum cache_metadata_mode mode) 969 + { 970 + const char *descs[] = { 971 + "write", 972 + "read-only", 973 + "fail" 974 + }; 975 + 976 + dm_table_event(cache->ti->table); 977 + DMINFO("switching cache to %s mode", descs[(int)mode]); 978 + } 979 + 980 + static void set_cache_mode(struct cache *cache, enum cache_metadata_mode new_mode) 981 + { 982 + bool needs_check = dm_cache_metadata_needs_check(cache->cmd); 983 + enum cache_metadata_mode old_mode = get_cache_mode(cache); 984 + 985 + if (new_mode == CM_WRITE && needs_check) { 986 + DMERR("unable to switch cache to write mode until repaired."); 987 + if (old_mode != new_mode) 988 + new_mode = old_mode; 989 + else 990 + new_mode = CM_READ_ONLY; 991 + } 992 + 993 + /* Never move out of fail mode */ 994 + if (old_mode == CM_FAIL) 995 + new_mode = CM_FAIL; 996 + 997 + switch (new_mode) { 998 + case CM_FAIL: 999 + case CM_READ_ONLY: 1000 + dm_cache_metadata_set_read_only(cache->cmd); 1001 + break; 1002 + 1003 + case CM_WRITE: 1004 + dm_cache_metadata_set_read_write(cache->cmd); 1005 + break; 1006 + } 1007 + 1008 + cache->features.mode = new_mode; 1009 + 1010 + if (new_mode != old_mode) 1011 + notify_mode_switch(cache, new_mode); 1012 + } 1013 + 1014 + static void abort_transaction(struct cache *cache) 1015 + { 1016 + if (get_cache_mode(cache) >= CM_READ_ONLY) 1017 + return; 1018 + 1019 + if (dm_cache_metadata_set_needs_check(cache->cmd)) { 1020 + DMERR("failed to set 'needs_check' flag in metadata"); 1021 + set_cache_mode(cache, CM_FAIL); 1022 + } 1023 + 1024 + DMERR_LIMIT("aborting current metadata transaction"); 1025 + if (dm_cache_metadata_abort(cache->cmd)) { 1026 + DMERR("failed to abort metadata transaction"); 1027 + set_cache_mode(cache, CM_FAIL); 1028 + } 1029 + } 1030 + 1031 + static void metadata_operation_failed(struct cache *cache, const char *op, int r) 1032 + { 1033 + DMERR_LIMIT("metadata operation '%s' failed: error = %d", op, r); 1034 + abort_transaction(cache); 1035 + set_cache_mode(cache, CM_READ_ONLY); 1036 + } 1037 + 1038 + /*---------------------------------------------------------------- 964 1039 * Migration processing 965 1040 * 966 1041 * Migration covers moving data from the origin device to the cache, or ··· 1144 1063 1145 1064 static void migration_success_pre_commit(struct dm_cache_migration *mg) 1146 1065 { 1066 + int r; 1147 1067 unsigned long flags; 1148 1068 struct cache *cache = mg->cache; 1149 1069 ··· 1155 1073 return; 1156 1074 1157 1075 } else if (mg->demote) { 1158 - if (dm_cache_remove_mapping(cache->cmd, mg->cblock)) { 1076 + r = dm_cache_remove_mapping(cache->cmd, mg->cblock); 1077 + if (r) { 1159 1078 DMWARN_LIMIT("demotion failed; couldn't update on disk metadata"); 1079 + metadata_operation_failed(cache, "dm_cache_remove_mapping", r); 1160 1080 policy_force_mapping(cache->policy, mg->new_oblock, 1161 1081 mg->old_oblock); 1162 1082 if (mg->promote) ··· 1167 1083 return; 1168 1084 } 1169 1085 } else { 1170 - if (dm_cache_insert_mapping(cache->cmd, mg->cblock, mg->new_oblock)) { 1086 + r = dm_cache_insert_mapping(cache->cmd, mg->cblock, mg->new_oblock); 1087 + if (r) { 1171 1088 DMWARN_LIMIT("promotion failed; couldn't update on disk metadata"); 1089 + metadata_operation_failed(cache, "dm_cache_insert_mapping", r); 1172 1090 policy_remove_mapping(cache->policy, mg->new_oblock); 1173 1091 free_io_migration(mg); 1174 1092 return; ··· 1898 1812 jiffies > cache->last_commit_jiffies + COMMIT_PERIOD; 1899 1813 } 1900 1814 1815 + /* 1816 + * A non-zero return indicates read_only or fail_io mode. 1817 + */ 1818 + static int commit(struct cache *cache, bool clean_shutdown) 1819 + { 1820 + int r; 1821 + 1822 + if (get_cache_mode(cache) >= CM_READ_ONLY) 1823 + return -EINVAL; 1824 + 1825 + atomic_inc(&cache->stats.commit_count); 1826 + r = dm_cache_commit(cache->cmd, clean_shutdown); 1827 + if (r) 1828 + metadata_operation_failed(cache, "dm_cache_commit", r); 1829 + 1830 + return r; 1831 + } 1832 + 1901 1833 static int commit_if_needed(struct cache *cache) 1902 1834 { 1903 1835 int r = 0; 1904 1836 1905 1837 if ((cache->commit_requested || need_commit_due_to_time(cache)) && 1906 1838 dm_cache_changed_this_transaction(cache->cmd)) { 1907 - atomic_inc(&cache->stats.commit_count); 1839 + r = commit(cache, false); 1908 1840 cache->commit_requested = false; 1909 - r = dm_cache_commit(cache->cmd, false); 1910 1841 cache->last_commit_jiffies = jiffies; 1911 1842 } 1912 1843 ··· 2091 1988 r = policy_remove_cblock(cache->policy, to_cblock(begin)); 2092 1989 if (!r) { 2093 1990 r = dm_cache_remove_mapping(cache->cmd, to_cblock(begin)); 2094 - if (r) 1991 + if (r) { 1992 + metadata_operation_failed(cache, "dm_cache_remove_mapping", r); 2095 1993 break; 1994 + } 2096 1995 2097 1996 } else if (r == -ENODATA) { 2098 1997 /* harmless, already unmapped */ ··· 2238 2133 if (commit_if_needed(cache)) { 2239 2134 process_deferred_flush_bios(cache, false); 2240 2135 process_migrations(cache, &cache->need_commit_migrations, migration_failure); 2241 - 2242 - /* 2243 - * FIXME: rollback metadata or just go into a 2244 - * failure mode and error everything 2245 - */ 2246 - 2247 2136 } else { 2248 2137 process_deferred_flush_bios(cache, true); 2249 2138 process_migrations(cache, &cache->need_commit_migrations, ··· 2810 2711 goto bad; 2811 2712 } 2812 2713 cache->cmd = cmd; 2714 + set_cache_mode(cache, CM_WRITE); 2715 + if (get_cache_mode(cache) != CM_WRITE) { 2716 + *error = "Unable to get write access to metadata, please check/repair metadata."; 2717 + r = -EINVAL; 2718 + goto bad; 2719 + } 2813 2720 2814 2721 if (passthrough_mode(&cache->features)) { 2815 2722 bool all_clean; ··· 3148 3043 { 3149 3044 unsigned i, r; 3150 3045 3046 + if (get_cache_mode(cache) >= CM_READ_ONLY) 3047 + return -EINVAL; 3048 + 3151 3049 for (i = 0; i < from_cblock(cache->cache_size); i++) { 3152 3050 r = dm_cache_set_dirty(cache->cmd, to_cblock(i), 3153 3051 is_dirty(cache, to_cblock(i))); 3154 - if (r) 3052 + if (r) { 3053 + metadata_operation_failed(cache, "dm_cache_set_dirty", r); 3155 3054 return r; 3055 + } 3156 3056 } 3157 3057 3158 3058 return 0; ··· 3167 3057 { 3168 3058 unsigned i, r; 3169 3059 3060 + if (get_cache_mode(cache) >= CM_READ_ONLY) 3061 + return -EINVAL; 3062 + 3170 3063 r = dm_cache_discard_bitset_resize(cache->cmd, cache->discard_block_size, 3171 3064 cache->discard_nr_blocks); 3172 3065 if (r) { 3173 3066 DMERR("could not resize on-disk discard bitset"); 3067 + metadata_operation_failed(cache, "dm_cache_discard_bitset_resize", r); 3174 3068 return r; 3175 3069 } 3176 3070 3177 3071 for (i = 0; i < from_dblock(cache->discard_nr_blocks); i++) { 3178 3072 r = dm_cache_set_discard(cache->cmd, to_dblock(i), 3179 3073 is_discarded(cache, to_dblock(i))); 3180 - if (r) 3074 + if (r) { 3075 + metadata_operation_failed(cache, "dm_cache_set_discard", r); 3181 3076 return r; 3077 + } 3078 + } 3079 + 3080 + return 0; 3081 + } 3082 + 3083 + static int write_hints(struct cache *cache) 3084 + { 3085 + int r; 3086 + 3087 + if (get_cache_mode(cache) >= CM_READ_ONLY) 3088 + return -EINVAL; 3089 + 3090 + r = dm_cache_write_hints(cache->cmd, cache->policy); 3091 + if (r) { 3092 + metadata_operation_failed(cache, "dm_cache_write_hints", r); 3093 + return r; 3182 3094 } 3183 3095 3184 3096 return 0; ··· 3223 3091 3224 3092 save_stats(cache); 3225 3093 3226 - r3 = dm_cache_write_hints(cache->cmd, cache->policy); 3094 + r3 = write_hints(cache); 3227 3095 if (r3) 3228 3096 DMERR("could not write hints"); 3229 3097 ··· 3232 3100 * set the clean shutdown flag. This will effectively force every 3233 3101 * dirty bit to be set on reload. 3234 3102 */ 3235 - r4 = dm_cache_commit(cache->cmd, !r1 && !r2 && !r3); 3103 + r4 = commit(cache, !r1 && !r2 && !r3); 3236 3104 if (r4) 3237 - DMERR("could not write cache metadata. Data loss may occur."); 3105 + DMERR("could not write cache metadata."); 3238 3106 3239 3107 return !r1 && !r2 && !r3 && !r4; 3240 3108 } ··· 3250 3118 requeue_deferred_cells(cache); 3251 3119 stop_quiescing(cache); 3252 3120 3253 - (void) sync_metadata(cache); 3121 + if (get_cache_mode(cache) == CM_WRITE) 3122 + (void) sync_metadata(cache); 3254 3123 } 3255 3124 3256 3125 static int load_mapping(void *context, dm_oblock_t oblock, dm_cblock_t cblock, ··· 3390 3257 r = dm_cache_resize(cache->cmd, new_size); 3391 3258 if (r) { 3392 3259 DMERR("could not resize cache metadata"); 3260 + metadata_operation_failed(cache, "dm_cache_resize", r); 3393 3261 return r; 3394 3262 } 3395 3263 ··· 3429 3295 load_mapping, cache); 3430 3296 if (r) { 3431 3297 DMERR("could not load cache mappings"); 3298 + metadata_operation_failed(cache, "dm_cache_load_mappings", r); 3432 3299 return r; 3433 3300 } 3434 3301 ··· 3450 3315 r = dm_cache_load_discards(cache->cmd, load_discard, &li); 3451 3316 if (r) { 3452 3317 DMERR("could not load origin discards"); 3318 + metadata_operation_failed(cache, "dm_cache_load_discards", r); 3453 3319 return r; 3454 3320 } 3455 3321 set_discard_range(&li); ··· 3478 3342 * <#demotions> <#promotions> <#dirty> 3479 3343 * <#features> <features>* 3480 3344 * <#core args> <core args> 3481 - * <policy name> <#policy args> <policy args>* 3345 + * <policy name> <#policy args> <policy args>* <cache metadata mode> 3482 3346 */ 3483 3347 static void cache_status(struct dm_target *ti, status_type_t type, 3484 3348 unsigned status_flags, char *result, unsigned maxlen) ··· 3494 3358 3495 3359 switch (type) { 3496 3360 case STATUSTYPE_INFO: 3497 - /* Commit to ensure statistics aren't out-of-date */ 3498 - if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti)) { 3499 - r = dm_cache_commit(cache->cmd, false); 3500 - if (r) 3501 - DMERR("could not commit metadata for accurate status"); 3361 + if (get_cache_mode(cache) == CM_FAIL) { 3362 + DMEMIT("Fail"); 3363 + break; 3502 3364 } 3365 + 3366 + /* Commit to ensure statistics aren't out-of-date */ 3367 + if (!(status_flags & DM_STATUS_NOFLUSH_FLAG) && !dm_suspended(ti)) 3368 + (void) commit(cache, false); 3503 3369 3504 3370 r = dm_cache_get_free_metadata_block_count(cache->cmd, 3505 3371 &nr_free_blocks_metadata); ··· 3551 3413 3552 3414 DMEMIT("%s ", dm_cache_policy_get_name(cache->policy)); 3553 3415 if (sz < maxlen) { 3554 - r = policy_emit_config_values(cache->policy, result + sz, maxlen - sz); 3416 + r = policy_emit_config_values(cache->policy, result, maxlen, &sz); 3555 3417 if (r) 3556 3418 DMERR("policy_emit_config_values returned %d", r); 3557 3419 } 3420 + 3421 + if (get_cache_mode(cache) == CM_READ_ONLY) 3422 + DMEMIT("ro "); 3423 + else 3424 + DMEMIT("rw "); 3558 3425 3559 3426 break; 3560 3427 ··· 3716 3573 if (!argc) 3717 3574 return -EINVAL; 3718 3575 3576 + if (get_cache_mode(cache) >= CM_READ_ONLY) { 3577 + DMERR("unable to service cache target messages in READ_ONLY or FAIL mode"); 3578 + return -EOPNOTSUPP; 3579 + } 3580 + 3719 3581 if (!strcasecmp(argv[0], "invalidate_cblocks")) 3720 3582 return process_invalidate_cblocks_message(cache, argc - 1, (const char **) argv + 1); 3721 3583 ··· 3794 3646 3795 3647 static struct target_type cache_target = { 3796 3648 .name = "cache", 3797 - .version = {1, 6, 0}, 3649 + .version = {1, 7, 0}, 3798 3650 .module = THIS_MODULE, 3799 3651 .ctr = cache_ctr, 3800 3652 .dtr = cache_dtr,