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

dm cache: policy ignore hints if generated by different version

When reading the dm cache metadata from disk, ignore the policy hints
unless they were generated by the same major version number of the same
policy module.

The hints are considered to be private data belonging to the specific
module that generated them and there is no requirement for them to make
sense to different versions of the policy that generated them.
Policy modules are all required to work fine if no previous hints are
supplied (or if existing hints are lost).

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>

authored by

Mike Snitzer and committed by
Alasdair G Kergon
ea2dd8c1 4e7f506f

+39 -13
+37 -10
drivers/md/dm-cache-metadata.c
··· 863 863 bool hints_valid; 864 864 }; 865 865 866 + static bool policy_unchanged(struct dm_cache_metadata *cmd, 867 + struct dm_cache_policy *policy) 868 + { 869 + const char *policy_name = dm_cache_policy_get_name(policy); 870 + const unsigned *policy_version = dm_cache_policy_get_version(policy); 871 + size_t policy_hint_size = dm_cache_policy_get_hint_size(policy); 872 + 873 + /* 874 + * Ensure policy names match. 875 + */ 876 + if (strncmp(cmd->policy_name, policy_name, sizeof(cmd->policy_name))) 877 + return false; 878 + 879 + /* 880 + * Ensure policy major versions match. 881 + */ 882 + if (cmd->policy_version[0] != policy_version[0]) 883 + return false; 884 + 885 + /* 886 + * Ensure policy hint sizes match. 887 + */ 888 + if (cmd->policy_hint_size != policy_hint_size) 889 + return false; 890 + 891 + return true; 892 + } 893 + 866 894 static bool hints_array_initialized(struct dm_cache_metadata *cmd) 867 895 { 868 896 return cmd->hint_root && cmd->policy_hint_size; 869 897 } 870 898 871 899 static bool hints_array_available(struct dm_cache_metadata *cmd, 872 - const char *policy_name) 900 + struct dm_cache_policy *policy) 873 901 { 874 - bool policy_names_match = !strncmp(cmd->policy_name, policy_name, 875 - sizeof(cmd->policy_name)); 876 - 877 - return cmd->clean_when_opened && policy_names_match && 902 + return cmd->clean_when_opened && policy_unchanged(cmd, policy) && 878 903 hints_array_initialized(cmd); 879 904 } 880 905 ··· 933 908 return r; 934 909 } 935 910 936 - static int __load_mappings(struct dm_cache_metadata *cmd, const char *policy_name, 911 + static int __load_mappings(struct dm_cache_metadata *cmd, 912 + struct dm_cache_policy *policy, 937 913 load_mapping_fn fn, void *context) 938 914 { 939 915 struct thunk thunk; ··· 944 918 945 919 thunk.cmd = cmd; 946 920 thunk.respect_dirty_flags = cmd->clean_when_opened; 947 - thunk.hints_valid = hints_array_available(cmd, policy_name); 921 + thunk.hints_valid = hints_array_available(cmd, policy); 948 922 949 923 return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk); 950 924 } 951 925 952 - int dm_cache_load_mappings(struct dm_cache_metadata *cmd, const char *policy_name, 926 + int dm_cache_load_mappings(struct dm_cache_metadata *cmd, 927 + struct dm_cache_policy *policy, 953 928 load_mapping_fn fn, void *context) 954 929 { 955 930 int r; 956 931 957 932 down_read(&cmd->root_lock); 958 - r = __load_mappings(cmd, policy_name, fn, context); 933 + r = __load_mappings(cmd, policy, fn, context); 959 934 up_read(&cmd->root_lock); 960 935 961 936 return r; ··· 1112 1085 (strlen(policy_name) > sizeof(cmd->policy_name) - 1)) 1113 1086 return -EINVAL; 1114 1087 1115 - if (strcmp(cmd->policy_name, policy_name)) { 1088 + if (!policy_unchanged(cmd, policy)) { 1116 1089 strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name)); 1117 1090 memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version)); 1118 1091
+1 -1
drivers/md/dm-cache-metadata.h
··· 89 89 dm_cblock_t cblock, bool dirty, 90 90 uint32_t hint, bool hint_valid); 91 91 int dm_cache_load_mappings(struct dm_cache_metadata *cmd, 92 - const char *policy_name, 92 + struct dm_cache_policy *policy, 93 93 load_mapping_fn fn, 94 94 void *context); 95 95
+1 -2
drivers/md/dm-cache-target.c
··· 2369 2369 } 2370 2370 2371 2371 if (!cache->loaded_mappings) { 2372 - r = dm_cache_load_mappings(cache->cmd, 2373 - dm_cache_policy_get_name(cache->policy), 2372 + r = dm_cache_load_mappings(cache->cmd, cache->policy, 2374 2373 load_mapping, cache); 2375 2374 if (r) { 2376 2375 DMERR("could not load cache mappings");