^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright (C) 2003 Sistina Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This file is released under the LGPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/dm-io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/dm-dirty-log.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/device-mapper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define DM_MSG_PREFIX "dirty region log"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static LIST_HEAD(_log_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) static DEFINE_SPINLOCK(_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) static struct dm_dirty_log_type *__find_dirty_log_type(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct dm_dirty_log_type *log_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) list_for_each_entry(log_type, &_log_types, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (!strcmp(name, log_type->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) return log_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static struct dm_dirty_log_type *_get_dirty_log_type(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct dm_dirty_log_type *log_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) spin_lock(&_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) log_type = __find_dirty_log_type(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (log_type && !try_module_get(log_type->module))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) log_type = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) spin_unlock(&_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return log_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * get_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * @type_name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * Attempt to retrieve the dm_dirty_log_type by name. If not already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * available, attempt to load the appropriate module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Log modules are named "dm-log-" followed by the 'type_name'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * Modules may contain multiple types.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * This function will first try the module "dm-log-<type_name>",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * then truncate 'type_name' on the last '-' and try again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * For example, if type_name was "clustered-disk", it would search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * 'dm-log-clustered-disk' then 'dm-log-clustered'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Returns: dirty_log_type* on success, NULL on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static struct dm_dirty_log_type *get_type(const char *type_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) char *p, *type_name_dup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct dm_dirty_log_type *log_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (!type_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) log_type = _get_dirty_log_type(type_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (log_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return log_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) type_name_dup = kstrdup(type_name, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (!type_name_dup) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) DMWARN("No memory left to attempt log module load for \"%s\"",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) type_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) while (request_module("dm-log-%s", type_name_dup) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) !(log_type = _get_dirty_log_type(type_name))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) p = strrchr(type_name_dup, '-');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) p[0] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!log_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) DMWARN("Module for logging type \"%s\" not found.", type_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) kfree(type_name_dup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return log_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static void put_type(struct dm_dirty_log_type *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (!type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) spin_lock(&_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (!__find_dirty_log_type(type->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) module_put(type->module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) spin_unlock(&_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int dm_dirty_log_type_register(struct dm_dirty_log_type *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) int r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) spin_lock(&_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (!__find_dirty_log_type(type->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) list_add(&type->list, &_log_types);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) r = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) spin_unlock(&_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) EXPORT_SYMBOL(dm_dirty_log_type_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) spin_lock(&_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (!__find_dirty_log_type(type->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) spin_unlock(&_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) list_del(&type->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) spin_unlock(&_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) EXPORT_SYMBOL(dm_dirty_log_type_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct dm_dirty_log *dm_dirty_log_create(const char *type_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct dm_target *ti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int (*flush_callback_fn)(struct dm_target *ti),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) unsigned int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct dm_dirty_log_type *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct dm_dirty_log *log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) log = kmalloc(sizeof(*log), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (!log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) type = get_type(type_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (!type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) kfree(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) log->flush_callback_fn = flush_callback_fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) log->type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (type->ctr(log, ti, argc, argv)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) kfree(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) put_type(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) EXPORT_SYMBOL(dm_dirty_log_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) void dm_dirty_log_destroy(struct dm_dirty_log *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) log->type->dtr(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) put_type(log->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) kfree(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) EXPORT_SYMBOL(dm_dirty_log_destroy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /*-----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * Persistent and core logs share a lot of their implementation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * FIXME: need a reload method to be called from a resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *---------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Magic for persistent mirrors: "MiRr"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define MIRROR_MAGIC 0x4D695272
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * The on-disk version of the metadata.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define MIRROR_DISK_VERSION 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define LOG_OFFSET 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct log_header_disk {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) __le32 magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Simple, incrementing version. no backward
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * compatibility.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) __le32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) __le64 nr_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct log_header_core {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) uint32_t magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) uint32_t version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) uint64_t nr_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct log_c {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct dm_target *ti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int touched_dirtied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) int touched_cleaned;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int flush_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) uint32_t region_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned int region_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) region_t sync_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) unsigned bitset_uint32_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) uint32_t *clean_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) uint32_t *sync_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) uint32_t *recovering_bits; /* FIXME: this seems excessive */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int sync_search;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Resync flag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) enum sync {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) DEFAULTSYNC, /* Synchronize if necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) NOSYNC, /* Devices known to be already in sync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) FORCESYNC, /* Force a sync to happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) } sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct dm_io_request io_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * Disk log fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int log_dev_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int log_dev_flush_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct dm_dev *log_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct log_header_core header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct dm_io_region header_location;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct log_header_disk *disk_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * The touched member needs to be updated every time we access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * one of the bitsets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static inline int log_test_bit(uint32_t *bs, unsigned bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return test_bit_le(bit, bs) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) static inline void log_set_bit(struct log_c *l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) uint32_t *bs, unsigned bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) __set_bit_le(bit, bs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) l->touched_cleaned = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static inline void log_clear_bit(struct log_c *l,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) uint32_t *bs, unsigned bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) __clear_bit_le(bit, bs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) l->touched_dirtied = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /*----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * Header IO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) *--------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void header_to_disk(struct log_header_core *core, struct log_header_disk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) disk->magic = cpu_to_le32(core->magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) disk->version = cpu_to_le32(core->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) disk->nr_regions = cpu_to_le64(core->nr_regions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static void header_from_disk(struct log_header_core *core, struct log_header_disk *disk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) core->magic = le32_to_cpu(disk->magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) core->version = le32_to_cpu(disk->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) core->nr_regions = le64_to_cpu(disk->nr_regions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int rw_header(struct log_c *lc, int op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) lc->io_req.bi_op = op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) lc->io_req.bi_op_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return dm_io(&lc->io_req, 1, &lc->header_location, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int flush_header(struct log_c *lc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct dm_io_region null_location = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .bdev = lc->header_location.bdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .sector = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .count = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) lc->io_req.bi_op = REQ_OP_WRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) lc->io_req.bi_op_flags = REQ_PREFLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return dm_io(&lc->io_req, 1, &null_location, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static int read_header(struct log_c *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) r = rw_header(log, REQ_OP_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) header_from_disk(&log->header, log->disk_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* New log required? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (log->sync != DEFAULTSYNC || log->header.magic != MIRROR_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) log->header.magic = MIRROR_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) log->header.version = MIRROR_DISK_VERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) log->header.nr_regions = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) #ifdef __LITTLE_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (log->header.version == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) log->header.version = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (log->header.version != MIRROR_DISK_VERSION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) DMWARN("incompatible disk log version");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int _check_region_size(struct dm_target *ti, uint32_t region_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (region_size < 2 || region_size > ti->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (!is_power_of_2(region_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /*----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * core log constructor/destructor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * argv contains region_size followed optionally by [no]sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) *--------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) #define BYTE_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) unsigned int argc, char **argv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct dm_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) enum sync sync = DEFAULTSYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) struct log_c *lc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) uint32_t region_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) unsigned int region_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) size_t bitset_size, buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) char dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (argc < 1 || argc > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) DMWARN("wrong number of arguments to dirty region log");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (argc > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (!strcmp(argv[1], "sync"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) sync = FORCESYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) else if (!strcmp(argv[1], "nosync"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) sync = NOSYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) DMWARN("unrecognised sync argument to "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) "dirty region log: %s", argv[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (sscanf(argv[0], "%u%c", ®ion_size, &dummy) != 1 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) !_check_region_size(ti, region_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) DMWARN("invalid region size %s", argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) region_count = dm_sector_div_up(ti->len, region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) lc = kmalloc(sizeof(*lc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (!lc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) DMWARN("couldn't allocate core log");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) lc->ti = ti;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) lc->touched_dirtied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) lc->touched_cleaned = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) lc->flush_failed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) lc->region_size = region_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) lc->region_count = region_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) lc->sync = sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * Work out how many "unsigned long"s we need to hold the bitset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) bitset_size = dm_round_up(region_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) sizeof(*lc->clean_bits) << BYTE_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) bitset_size >>= BYTE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) lc->bitset_uint32_count = bitset_size / sizeof(*lc->clean_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * Disk log?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) lc->clean_bits = vmalloc(bitset_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!lc->clean_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) DMWARN("couldn't allocate clean bitset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) kfree(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) lc->disk_header = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) lc->log_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) lc->log_dev_failed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) lc->log_dev_flush_failed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) lc->header_location.bdev = lc->log_dev->bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) lc->header_location.sector = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * Buffer holds both header and bitset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) buf_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) dm_round_up((LOG_OFFSET << SECTOR_SHIFT) + bitset_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) bdev_logical_block_size(lc->header_location.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) bdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (buf_size > i_size_read(dev->bdev->bd_inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) DMWARN("log device %s too small: need %llu bytes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) dev->name, (unsigned long long)buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) kfree(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) lc->header_location.count = buf_size >> SECTOR_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) lc->io_req.mem.type = DM_IO_VMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) lc->io_req.notify.fn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) lc->io_req.client = dm_io_client_create();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (IS_ERR(lc->io_req.client)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) r = PTR_ERR(lc->io_req.client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) DMWARN("couldn't allocate disk io client");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) kfree(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) lc->disk_header = vmalloc(buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (!lc->disk_header) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) DMWARN("couldn't allocate disk log buffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) dm_io_client_destroy(lc->io_req.client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) kfree(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) lc->io_req.mem.ptr.vma = lc->disk_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) lc->clean_bits = (void *)lc->disk_header +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) (LOG_OFFSET << SECTOR_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) memset(lc->clean_bits, -1, bitset_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) lc->sync_bits = vmalloc(bitset_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (!lc->sync_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) DMWARN("couldn't allocate sync bitset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) vfree(lc->clean_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) dm_io_client_destroy(lc->io_req.client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) vfree(lc->disk_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) kfree(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) memset(lc->sync_bits, (sync == NOSYNC) ? -1 : 0, bitset_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) lc->sync_count = (sync == NOSYNC) ? region_count : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) lc->recovering_bits = vzalloc(bitset_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!lc->recovering_bits) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) DMWARN("couldn't allocate sync bitset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) vfree(lc->sync_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) vfree(lc->clean_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) dm_io_client_destroy(lc->io_req.client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) vfree(lc->disk_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) kfree(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) lc->sync_search = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) log->context = lc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static int core_ctr(struct dm_dirty_log *log, struct dm_target *ti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) unsigned int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) return create_log_context(log, ti, argc, argv, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static void destroy_log_context(struct log_c *lc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) vfree(lc->sync_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) vfree(lc->recovering_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) kfree(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static void core_dtr(struct dm_dirty_log *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) vfree(lc->clean_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) destroy_log_context(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /*----------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * disk log constructor/destructor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * argv contains log_device region_size followed optionally by [no]sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) *--------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) unsigned int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) struct dm_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (argc < 2 || argc > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) DMWARN("wrong number of arguments to disk dirty region log");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) r = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) r = create_log_context(log, ti, argc - 1, argv + 1, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) dm_put_device(ti, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) static void disk_dtr(struct dm_dirty_log *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) dm_put_device(lc->ti, lc->log_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) vfree(lc->disk_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) dm_io_client_destroy(lc->io_req.client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) destroy_log_context(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void fail_log_device(struct log_c *lc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (lc->log_dev_failed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) lc->log_dev_failed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) dm_table_event(lc->ti->table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int disk_resume(struct dm_dirty_log *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) size_t size = lc->bitset_uint32_count * sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* read the disk header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) r = read_header(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) DMWARN("%s: Failed to read header on dirty region log device",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) lc->log_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) fail_log_device(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * If the log device cannot be read, we must assume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * all regions are out-of-sync. If we simply return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * here, the state will be uninitialized and could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * lead us to return 'in-sync' status for regions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * that are actually 'out-of-sync'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) lc->header.nr_regions = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /* set or clear any new bits -- device has grown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (lc->sync == NOSYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) for (i = lc->header.nr_regions; i < lc->region_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* FIXME: amazingly inefficient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) log_set_bit(lc, lc->clean_bits, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) for (i = lc->header.nr_regions; i < lc->region_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /* FIXME: amazingly inefficient */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) log_clear_bit(lc, lc->clean_bits, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* clear any old bits -- device has shrunk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) for (i = lc->region_count; i % (sizeof(*lc->clean_bits) << BYTE_SHIFT); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) log_clear_bit(lc, lc->clean_bits, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* copy clean across to sync */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) memcpy(lc->sync_bits, lc->clean_bits, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) lc->sync_count = memweight(lc->clean_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) lc->bitset_uint32_count * sizeof(uint32_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) lc->sync_search = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /* set the correct number of regions in the header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) lc->header.nr_regions = lc->region_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) header_to_disk(&lc->header, lc->disk_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) /* write the new header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) r = rw_header(lc, REQ_OP_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (!r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) r = flush_header(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) lc->log_dev_flush_failed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) DMWARN("%s: Failed to write header on dirty region log device",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) lc->log_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) fail_log_device(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static uint32_t core_get_region_size(struct dm_dirty_log *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return lc->region_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static int core_resume(struct dm_dirty_log *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) lc->sync_search = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) static int core_is_clean(struct dm_dirty_log *log, region_t region)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) return log_test_bit(lc->clean_bits, region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static int core_in_sync(struct dm_dirty_log *log, region_t region, int block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return log_test_bit(lc->sync_bits, region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static int core_flush(struct dm_dirty_log *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* no op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) static int disk_flush(struct dm_dirty_log *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) int r, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct log_c *lc = log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /* only write if the log has changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (!lc->touched_cleaned && !lc->touched_dirtied)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (lc->touched_cleaned && log->flush_callback_fn &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) log->flush_callback_fn(lc->ti)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * At this point it is impossible to determine which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * regions are clean and which are dirty (without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * re-reading the log off disk). So mark all of them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * dirty.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) lc->flush_failed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) for (i = 0; i < lc->region_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) log_clear_bit(lc, lc->clean_bits, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) r = rw_header(lc, REQ_OP_WRITE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) fail_log_device(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (lc->touched_dirtied) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) r = flush_header(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) lc->log_dev_flush_failed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) fail_log_device(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) lc->touched_dirtied = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) lc->touched_cleaned = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) static void core_mark_region(struct dm_dirty_log *log, region_t region)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) log_clear_bit(lc, lc->clean_bits, region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) static void core_clear_region(struct dm_dirty_log *log, region_t region)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (likely(!lc->flush_failed))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) log_set_bit(lc, lc->clean_bits, region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) static int core_get_resync_work(struct dm_dirty_log *log, region_t *region)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (lc->sync_search >= lc->region_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) *region = find_next_zero_bit_le(lc->sync_bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) lc->region_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) lc->sync_search);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) lc->sync_search = *region + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (*region >= lc->region_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) } while (log_test_bit(lc->recovering_bits, *region));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) log_set_bit(lc, lc->recovering_bits, *region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static void core_set_region_sync(struct dm_dirty_log *log, region_t region,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) int in_sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) log_clear_bit(lc, lc->recovering_bits, region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (in_sync) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) log_set_bit(lc, lc->sync_bits, region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) lc->sync_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) } else if (log_test_bit(lc->sync_bits, region)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) lc->sync_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) log_clear_bit(lc, lc->sync_bits, region);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static region_t core_get_sync_count(struct dm_dirty_log *log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) struct log_c *lc = (struct log_c *) log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) return lc->sync_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) #define DMEMIT_SYNC \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (lc->sync != DEFAULTSYNC) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) DMEMIT("%ssync ", lc->sync == NOSYNC ? "no" : "")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static int core_status(struct dm_dirty_log *log, status_type_t status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) char *result, unsigned int maxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) int sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) struct log_c *lc = log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) switch(status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) case STATUSTYPE_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) DMEMIT("1 %s", log->type->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) case STATUSTYPE_TABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) DMEMIT("%s %u %u ", log->type->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) lc->sync == DEFAULTSYNC ? 1 : 2, lc->region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) DMEMIT_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) static int disk_status(struct dm_dirty_log *log, status_type_t status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) char *result, unsigned int maxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) int sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct log_c *lc = log->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) switch(status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) case STATUSTYPE_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) DMEMIT("3 %s %s %c", log->type->name, lc->log_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) lc->log_dev_flush_failed ? 'F' :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) lc->log_dev_failed ? 'D' :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 'A');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) case STATUSTYPE_TABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) DMEMIT("%s %u %s %u ", log->type->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) lc->sync == DEFAULTSYNC ? 2 : 3, lc->log_dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) lc->region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) DMEMIT_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) static struct dm_dirty_log_type _core_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) .name = "core",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) .ctr = core_ctr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) .dtr = core_dtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) .resume = core_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) .get_region_size = core_get_region_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) .is_clean = core_is_clean,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) .in_sync = core_in_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) .flush = core_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) .mark_region = core_mark_region,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) .clear_region = core_clear_region,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) .get_resync_work = core_get_resync_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) .set_region_sync = core_set_region_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) .get_sync_count = core_get_sync_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) .status = core_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static struct dm_dirty_log_type _disk_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) .name = "disk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) .module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) .ctr = disk_ctr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) .dtr = disk_dtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) .postsuspend = disk_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) .resume = disk_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) .get_region_size = core_get_region_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) .is_clean = core_is_clean,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) .in_sync = core_in_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) .flush = disk_flush,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) .mark_region = core_mark_region,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) .clear_region = core_clear_region,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) .get_resync_work = core_get_resync_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) .set_region_sync = core_set_region_sync,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) .get_sync_count = core_get_sync_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) .status = disk_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static int __init dm_dirty_log_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) r = dm_dirty_log_type_register(&_core_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) DMWARN("couldn't register core log");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) r = dm_dirty_log_type_register(&_disk_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if (r) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) DMWARN("couldn't register disk type");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) dm_dirty_log_type_unregister(&_core_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) return r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static void __exit dm_dirty_log_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) dm_dirty_log_type_unregister(&_disk_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) dm_dirty_log_type_unregister(&_core_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) module_init(dm_dirty_log_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) module_exit(dm_dirty_log_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) MODULE_DESCRIPTION(DM_NAME " dirty region log");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) MODULE_AUTHOR("Joe Thornber, Heinz Mauelshagen <dm-devel@redhat.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) MODULE_LICENSE("GPL");