diff options
author | Joe Thornber <ejt@redhat.com> | 2016-09-20 06:16:00 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2016-09-22 11:15:05 -0400 |
commit | f177940a80917044f0ea6fd18ea1bfbdff012050 (patch) | |
tree | fc1a276c90fcb1b77eb302fa35808616d127e7a2 /drivers/md/dm-cache-metadata.c | |
parent | fdd1315aa5f022fe6574efdc2d9535f75a0ee255 (diff) |
dm cache metadata: switch to using the new cursor api for loading metadata
This change offers a pretty significant performance improvement.
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.c | 103 |
1 files changed, 80 insertions, 23 deletions
diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index a60f10a0ee0a..695577812cf6 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c | |||
@@ -140,6 +140,13 @@ struct dm_cache_metadata { | |||
140 | * the device. | 140 | * the device. |
141 | */ | 141 | */ |
142 | bool fail_io:1; | 142 | bool fail_io:1; |
143 | |||
144 | /* | ||
145 | * These structures are used when loading metadata. They're too | ||
146 | * big to put on the stack. | ||
147 | */ | ||
148 | struct dm_array_cursor mapping_cursor; | ||
149 | struct dm_array_cursor hint_cursor; | ||
143 | }; | 150 | }; |
144 | 151 | ||
145 | /*------------------------------------------------------------------- | 152 | /*------------------------------------------------------------------- |
@@ -1171,31 +1178,37 @@ static bool hints_array_available(struct dm_cache_metadata *cmd, | |||
1171 | hints_array_initialized(cmd); | 1178 | hints_array_initialized(cmd); |
1172 | } | 1179 | } |
1173 | 1180 | ||
1174 | static int __load_mapping(void *context, uint64_t cblock, void *leaf) | 1181 | static int __load_mapping(struct dm_cache_metadata *cmd, |
1182 | uint64_t cb, bool hints_valid, | ||
1183 | struct dm_array_cursor *mapping_cursor, | ||
1184 | struct dm_array_cursor *hint_cursor, | ||
1185 | load_mapping_fn fn, void *context) | ||
1175 | { | 1186 | { |
1176 | int r = 0; | 1187 | int r = 0; |
1177 | bool dirty; | 1188 | |
1178 | __le64 value; | 1189 | __le64 mapping; |
1179 | __le32 hint_value = 0; | 1190 | __le32 hint = 0; |
1191 | |||
1192 | __le64 *mapping_value_le; | ||
1193 | __le32 *hint_value_le; | ||
1194 | |||
1180 | dm_oblock_t oblock; | 1195 | dm_oblock_t oblock; |
1181 | unsigned flags; | 1196 | unsigned flags; |
1182 | struct thunk *thunk = context; | ||
1183 | struct dm_cache_metadata *cmd = thunk->cmd; | ||
1184 | 1197 | ||
1185 | memcpy(&value, leaf, sizeof(value)); | 1198 | dm_array_cursor_get_value(mapping_cursor, (void **) &mapping_value_le); |
1186 | unpack_value(value, &oblock, &flags); | 1199 | memcpy(&mapping, mapping_value_le, sizeof(mapping)); |
1200 | unpack_value(mapping, &oblock, &flags); | ||
1187 | 1201 | ||
1188 | if (flags & M_VALID) { | 1202 | if (flags & M_VALID) { |
1189 | if (thunk->hints_valid) { | 1203 | if (hints_valid) { |
1190 | r = dm_array_get_value(&cmd->hint_info, cmd->hint_root, | 1204 | dm_array_cursor_get_value(hint_cursor, (void **) &hint_value_le); |
1191 | cblock, &hint_value); | 1205 | memcpy(&hint, hint_value_le, sizeof(hint)); |
1192 | if (r && r != -ENODATA) | ||
1193 | return r; | ||
1194 | } | 1206 | } |
1195 | 1207 | ||
1196 | dirty = thunk->respect_dirty_flags ? (flags & M_DIRTY) : true; | 1208 | r = fn(context, oblock, to_cblock(cb), flags & M_DIRTY, |
1197 | r = thunk->fn(thunk->context, oblock, to_cblock(cblock), | 1209 | le32_to_cpu(hint), hints_valid); |
1198 | dirty, le32_to_cpu(hint_value), thunk->hints_valid); | 1210 | if (r) |
1211 | DMERR("policy couldn't load cblock"); | ||
1199 | } | 1212 | } |
1200 | 1213 | ||
1201 | return r; | 1214 | return r; |
@@ -1205,16 +1218,60 @@ static int __load_mappings(struct dm_cache_metadata *cmd, | |||
1205 | struct dm_cache_policy *policy, | 1218 | struct dm_cache_policy *policy, |
1206 | load_mapping_fn fn, void *context) | 1219 | load_mapping_fn fn, void *context) |
1207 | { | 1220 | { |
1208 | struct thunk thunk; | 1221 | int r; |
1222 | uint64_t cb; | ||
1209 | 1223 | ||
1210 | thunk.fn = fn; | 1224 | bool hints_valid = hints_array_available(cmd, policy); |
1211 | thunk.context = context; | ||
1212 | 1225 | ||
1213 | thunk.cmd = cmd; | 1226 | if (from_cblock(cmd->cache_blocks) == 0) |
1214 | thunk.respect_dirty_flags = cmd->clean_when_opened; | 1227 | /* Nothing to do */ |
1215 | thunk.hints_valid = hints_array_available(cmd, policy); | 1228 | return 0; |
1216 | 1229 | ||
1217 | return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk); | 1230 | r = dm_array_cursor_begin(&cmd->info, cmd->root, &cmd->mapping_cursor); |
1231 | if (r) | ||
1232 | return r; | ||
1233 | |||
1234 | if (hints_valid) { | ||
1235 | r = dm_array_cursor_begin(&cmd->hint_info, cmd->hint_root, &cmd->hint_cursor); | ||
1236 | if (r) { | ||
1237 | dm_array_cursor_end(&cmd->mapping_cursor); | ||
1238 | return r; | ||
1239 | } | ||
1240 | } | ||
1241 | |||
1242 | for (cb = 0; ; cb++) { | ||
1243 | r = __load_mapping(cmd, cb, hints_valid, | ||
1244 | &cmd->mapping_cursor, &cmd->hint_cursor, | ||
1245 | fn, context); | ||
1246 | if (r) | ||
1247 | goto out; | ||
1248 | |||
1249 | /* | ||
1250 | * We need to break out before we move the cursors. | ||
1251 | */ | ||
1252 | if (cb >= (from_cblock(cmd->cache_blocks) - 1)) | ||
1253 | break; | ||
1254 | |||
1255 | r = dm_array_cursor_next(&cmd->mapping_cursor); | ||
1256 | if (r) { | ||
1257 | DMERR("dm_array_cursor_next for mapping failed"); | ||
1258 | goto out; | ||
1259 | } | ||
1260 | |||
1261 | if (hints_valid) { | ||
1262 | r = dm_array_cursor_next(&cmd->hint_cursor); | ||
1263 | if (r) { | ||
1264 | DMERR("dm_array_cursor_next for hint failed"); | ||
1265 | goto out; | ||
1266 | } | ||
1267 | } | ||
1268 | } | ||
1269 | out: | ||
1270 | dm_array_cursor_end(&cmd->mapping_cursor); | ||
1271 | if (hints_valid) | ||
1272 | dm_array_cursor_end(&cmd->hint_cursor); | ||
1273 | |||
1274 | return r; | ||
1218 | } | 1275 | } |
1219 | 1276 | ||
1220 | int dm_cache_load_mappings(struct dm_cache_metadata *cmd, | 1277 | int dm_cache_load_mappings(struct dm_cache_metadata *cmd, |