Loading drivers/md/dm-cache-metadata.c +80 −23 Original line number Diff line number Diff line Loading @@ -140,6 +140,13 @@ struct dm_cache_metadata { * the device. */ bool fail_io:1; /* * These structures are used when loading metadata. They're too * big to put on the stack. */ struct dm_array_cursor mapping_cursor; struct dm_array_cursor hint_cursor; }; /*------------------------------------------------------------------- Loading Loading @@ -1171,31 +1178,37 @@ static bool hints_array_available(struct dm_cache_metadata *cmd, hints_array_initialized(cmd); } static int __load_mapping(void *context, uint64_t cblock, void *leaf) static int __load_mapping(struct dm_cache_metadata *cmd, uint64_t cb, bool hints_valid, struct dm_array_cursor *mapping_cursor, struct dm_array_cursor *hint_cursor, load_mapping_fn fn, void *context) { int r = 0; bool dirty; __le64 value; __le32 hint_value = 0; __le64 mapping; __le32 hint = 0; __le64 *mapping_value_le; __le32 *hint_value_le; dm_oblock_t oblock; unsigned flags; struct thunk *thunk = context; struct dm_cache_metadata *cmd = thunk->cmd; memcpy(&value, leaf, sizeof(value)); unpack_value(value, &oblock, &flags); dm_array_cursor_get_value(mapping_cursor, (void **) &mapping_value_le); memcpy(&mapping, mapping_value_le, sizeof(mapping)); unpack_value(mapping, &oblock, &flags); if (flags & M_VALID) { if (thunk->hints_valid) { r = dm_array_get_value(&cmd->hint_info, cmd->hint_root, cblock, &hint_value); if (r && r != -ENODATA) return r; if (hints_valid) { dm_array_cursor_get_value(hint_cursor, (void **) &hint_value_le); memcpy(&hint, hint_value_le, sizeof(hint)); } dirty = thunk->respect_dirty_flags ? (flags & M_DIRTY) : true; r = thunk->fn(thunk->context, oblock, to_cblock(cblock), dirty, le32_to_cpu(hint_value), thunk->hints_valid); r = fn(context, oblock, to_cblock(cb), flags & M_DIRTY, le32_to_cpu(hint), hints_valid); if (r) DMERR("policy couldn't load cblock"); } return r; Loading @@ -1205,16 +1218,60 @@ static int __load_mappings(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy, load_mapping_fn fn, void *context) { struct thunk thunk; int r; uint64_t cb; thunk.fn = fn; thunk.context = context; bool hints_valid = hints_array_available(cmd, policy); thunk.cmd = cmd; thunk.respect_dirty_flags = cmd->clean_when_opened; thunk.hints_valid = hints_array_available(cmd, policy); if (from_cblock(cmd->cache_blocks) == 0) /* Nothing to do */ return 0; r = dm_array_cursor_begin(&cmd->info, cmd->root, &cmd->mapping_cursor); if (r) return r; return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk); if (hints_valid) { r = dm_array_cursor_begin(&cmd->hint_info, cmd->hint_root, &cmd->hint_cursor); if (r) { dm_array_cursor_end(&cmd->mapping_cursor); return r; } } for (cb = 0; ; cb++) { r = __load_mapping(cmd, cb, hints_valid, &cmd->mapping_cursor, &cmd->hint_cursor, fn, context); if (r) goto out; /* * We need to break out before we move the cursors. */ if (cb >= (from_cblock(cmd->cache_blocks) - 1)) break; r = dm_array_cursor_next(&cmd->mapping_cursor); if (r) { DMERR("dm_array_cursor_next for mapping failed"); goto out; } if (hints_valid) { r = dm_array_cursor_next(&cmd->hint_cursor); if (r) { DMERR("dm_array_cursor_next for hint failed"); goto out; } } } out: dm_array_cursor_end(&cmd->mapping_cursor); if (hints_valid) dm_array_cursor_end(&cmd->hint_cursor); return r; } int dm_cache_load_mappings(struct dm_cache_metadata *cmd, Loading Loading
drivers/md/dm-cache-metadata.c +80 −23 Original line number Diff line number Diff line Loading @@ -140,6 +140,13 @@ struct dm_cache_metadata { * the device. */ bool fail_io:1; /* * These structures are used when loading metadata. They're too * big to put on the stack. */ struct dm_array_cursor mapping_cursor; struct dm_array_cursor hint_cursor; }; /*------------------------------------------------------------------- Loading Loading @@ -1171,31 +1178,37 @@ static bool hints_array_available(struct dm_cache_metadata *cmd, hints_array_initialized(cmd); } static int __load_mapping(void *context, uint64_t cblock, void *leaf) static int __load_mapping(struct dm_cache_metadata *cmd, uint64_t cb, bool hints_valid, struct dm_array_cursor *mapping_cursor, struct dm_array_cursor *hint_cursor, load_mapping_fn fn, void *context) { int r = 0; bool dirty; __le64 value; __le32 hint_value = 0; __le64 mapping; __le32 hint = 0; __le64 *mapping_value_le; __le32 *hint_value_le; dm_oblock_t oblock; unsigned flags; struct thunk *thunk = context; struct dm_cache_metadata *cmd = thunk->cmd; memcpy(&value, leaf, sizeof(value)); unpack_value(value, &oblock, &flags); dm_array_cursor_get_value(mapping_cursor, (void **) &mapping_value_le); memcpy(&mapping, mapping_value_le, sizeof(mapping)); unpack_value(mapping, &oblock, &flags); if (flags & M_VALID) { if (thunk->hints_valid) { r = dm_array_get_value(&cmd->hint_info, cmd->hint_root, cblock, &hint_value); if (r && r != -ENODATA) return r; if (hints_valid) { dm_array_cursor_get_value(hint_cursor, (void **) &hint_value_le); memcpy(&hint, hint_value_le, sizeof(hint)); } dirty = thunk->respect_dirty_flags ? (flags & M_DIRTY) : true; r = thunk->fn(thunk->context, oblock, to_cblock(cblock), dirty, le32_to_cpu(hint_value), thunk->hints_valid); r = fn(context, oblock, to_cblock(cb), flags & M_DIRTY, le32_to_cpu(hint), hints_valid); if (r) DMERR("policy couldn't load cblock"); } return r; Loading @@ -1205,16 +1218,60 @@ static int __load_mappings(struct dm_cache_metadata *cmd, struct dm_cache_policy *policy, load_mapping_fn fn, void *context) { struct thunk thunk; int r; uint64_t cb; thunk.fn = fn; thunk.context = context; bool hints_valid = hints_array_available(cmd, policy); thunk.cmd = cmd; thunk.respect_dirty_flags = cmd->clean_when_opened; thunk.hints_valid = hints_array_available(cmd, policy); if (from_cblock(cmd->cache_blocks) == 0) /* Nothing to do */ return 0; r = dm_array_cursor_begin(&cmd->info, cmd->root, &cmd->mapping_cursor); if (r) return r; return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk); if (hints_valid) { r = dm_array_cursor_begin(&cmd->hint_info, cmd->hint_root, &cmd->hint_cursor); if (r) { dm_array_cursor_end(&cmd->mapping_cursor); return r; } } for (cb = 0; ; cb++) { r = __load_mapping(cmd, cb, hints_valid, &cmd->mapping_cursor, &cmd->hint_cursor, fn, context); if (r) goto out; /* * We need to break out before we move the cursors. */ if (cb >= (from_cblock(cmd->cache_blocks) - 1)) break; r = dm_array_cursor_next(&cmd->mapping_cursor); if (r) { DMERR("dm_array_cursor_next for mapping failed"); goto out; } if (hints_valid) { r = dm_array_cursor_next(&cmd->hint_cursor); if (r) { DMERR("dm_array_cursor_next for hint failed"); goto out; } } } out: dm_array_cursor_end(&cmd->mapping_cursor); if (hints_valid) dm_array_cursor_end(&cmd->hint_cursor); return r; } int dm_cache_load_mappings(struct dm_cache_metadata *cmd, Loading