9 #include <linux/slab.h>
10 #include <linux/module.h>
17 #define DM_MSG_PREFIX "dirty region log"
22 static struct dm_dirty_log_type *__find_dirty_log_type(
const char *
name)
24 struct dm_dirty_log_type *log_type;
33 static
struct dm_dirty_log_type *_get_dirty_log_type(
const char *name)
35 struct dm_dirty_log_type *log_type;
39 log_type = __find_dirty_log_type(name);
40 if (log_type && !try_module_get(log_type->module))
65 static struct dm_dirty_log_type *get_type(
const char *type_name)
67 char *
p, *type_name_dup;
68 struct dm_dirty_log_type *log_type;
73 log_type = _get_dirty_log_type(type_name);
79 DMWARN(
"No memory left to attempt log module load for \"%s\"",
84 while (request_module(
"dm-log-%s", type_name_dup) ||
85 !(log_type = _get_dirty_log_type(type_name))) {
86 p =
strrchr(type_name_dup,
'-');
93 DMWARN(
"Module for logging type \"%s\" not found.", type_name);
100 static void put_type(
struct dm_dirty_log_type *
type)
106 if (!__find_dirty_log_type(type->name))
109 module_put(type->module);
120 if (!__find_dirty_log_type(type->name))
121 list_add(&type->list, &_log_types);
134 if (!__find_dirty_log_type(type->name)) {
149 int (*flush_callback_fn)(
struct dm_target *ti),
150 unsigned int argc,
char **argv)
152 struct dm_dirty_log_type *
type;
153 struct dm_dirty_log *
log;
159 type = get_type(type_name);
165 log->flush_callback_fn = flush_callback_fn;
167 if (type->ctr(log, ti, argc, argv)) {
192 #define MIRROR_MAGIC 0x4D695272
197 #define MIRROR_DISK_VERSION 2
258 static inline int log_test_bit(
uint32_t *bs,
unsigned bit)
260 return test_bit_le(bit, bs) ? 1 : 0;
263 static inline void log_set_bit(
struct log_c *
l,
266 __set_bit_le(bit, bs);
270 static inline void log_clear_bit(
struct log_c *
l,
273 __clear_bit_le(bit, bs);
294 static int rw_header(
struct log_c *
lc,
int rw)
301 static int flush_header(
struct log_c *
lc)
303 struct dm_io_region null_location = {
311 return dm_io(&lc->
io_req, 1, &null_location, NULL);
314 static int read_header(
struct log_c *
log)
318 r = rw_header(log,
READ);
328 log->
header.nr_regions = 0;
331 #ifdef __LITTLE_ENDIAN
332 if (log->
header.version == 1)
337 DMWARN(
"incompatible disk log version");
346 if (region_size < 2 || region_size > ti->
len)
361 static int create_log_context(
struct dm_dirty_log *log,
struct dm_target *ti,
362 unsigned int argc,
char **argv,
374 if (argc < 1 || argc > 2) {
375 DMWARN(
"wrong number of arguments to dirty region log");
380 if (!
strcmp(argv[1],
"sync"))
382 else if (!
strcmp(argv[1],
"nosync"))
385 DMWARN(
"unrecognised sync argument to "
386 "dirty region log: %s", argv[1]);
391 if (
sscanf(argv[0],
"%u%c", ®ion_size, &dummy) != 1 ||
392 !_check_region_size(ti, region_size)) {
393 DMWARN(
"invalid region size %s", argv[0]);
401 DMWARN(
"couldn't allocate core log");
428 DMWARN(
"couldn't allocate clean bitset");
448 if (buf_size > i_size_read(dev->
bdev->bd_inode)) {
449 DMWARN(
"log device %s too small: need %llu bytes",
450 dev->
name, (
unsigned long long)buf_size);
457 lc->
io_req.mem.type = DM_IO_VMA;
460 if (IS_ERR(lc->
io_req.client)) {
461 r = PTR_ERR(lc->
io_req.client);
462 DMWARN(
"couldn't allocate disk io client");
469 DMWARN(
"couldn't allocate disk log buffer");
484 DMWARN(
"couldn't allocate sync bitset");
498 DMWARN(
"couldn't allocate sync bitset");
514 static int core_ctr(
struct dm_dirty_log *log,
struct dm_target *ti,
515 unsigned int argc,
char **argv)
517 return create_log_context(log, ti, argc, argv, NULL);
520 static void destroy_log_context(
struct log_c *
lc)
527 static void core_dtr(
struct dm_dirty_log *log)
532 destroy_log_context(lc);
540 static int disk_ctr(
struct dm_dirty_log *log,
struct dm_target *ti,
541 unsigned int argc,
char **argv)
546 if (argc < 2 || argc > 3) {
547 DMWARN(
"wrong number of arguments to disk dirty region log");
555 r = create_log_context(log, ti, argc - 1, argv + 1, dev);
564 static void disk_dtr(
struct dm_dirty_log *log)
566 struct log_c *lc = (
struct log_c *) log->context;
571 destroy_log_context(lc);
574 static void fail_log_device(
struct log_c *lc)
583 static int disk_resume(
struct dm_dirty_log *log)
587 struct log_c *lc = (
struct log_c *) log->context;
593 DMWARN(
"%s: Failed to read header on dirty region log device",
603 lc->
header.nr_regions = 0;
632 r = rw_header(lc,
WRITE);
634 r = flush_header(lc);
639 DMWARN(
"%s: Failed to write header on dirty region log device",
647 static uint32_t core_get_region_size(
struct dm_dirty_log *log)
649 struct log_c *lc = (
struct log_c *) log->context;
653 static int core_resume(
struct dm_dirty_log *log)
655 struct log_c *lc = (
struct log_c *) log->context;
660 static int core_is_clean(
struct dm_dirty_log *log,
region_t region)
662 struct log_c *lc = (
struct log_c *) log->context;
666 static int core_in_sync(
struct dm_dirty_log *log,
region_t region,
int block)
668 struct log_c *lc = (
struct log_c *) log->context;
669 return log_test_bit(lc->
sync_bits, region);
672 static int core_flush(
struct dm_dirty_log *log)
678 static int disk_flush(
struct dm_dirty_log *log)
681 struct log_c *lc = log->context;
688 log->flush_callback_fn(lc->
ti)) {
700 r = rw_header(lc,
WRITE);
705 r = flush_header(lc);
718 static void core_mark_region(
struct dm_dirty_log *log,
region_t region)
720 struct log_c *lc = (
struct log_c *) log->context;
724 static void core_clear_region(
struct dm_dirty_log *log,
region_t region)
726 struct log_c *lc = (
struct log_c *) log->context;
731 static int core_get_resync_work(
struct dm_dirty_log *log,
region_t *region)
733 struct log_c *lc = (
struct log_c *) log->context;
753 static void core_set_region_sync(
struct dm_dirty_log *log,
region_t region,
756 struct log_c *lc = (
struct log_c *) log->context;
762 }
else if (log_test_bit(lc->
sync_bits, region)) {
764 log_clear_bit(lc, lc->
sync_bits, region);
768 static region_t core_get_sync_count(
struct dm_dirty_log *log)
770 struct log_c *lc = (
struct log_c *) log->context;
775 #define DMEMIT_SYNC \
776 if (lc->sync != DEFAULTSYNC) \
777 DMEMIT("%ssync ", lc->sync == NOSYNC ? "no" : "")
780 char *
result,
unsigned int maxlen)
783 struct log_c *lc = log->context;
787 DMEMIT(
"1 %s", log->type->name);
791 DMEMIT(
"%s %u %u ", log->type->name,
800 char *
result,
unsigned int maxlen)
803 struct log_c *lc = log->context;
814 DMEMIT(
"%s %u %s %u ", log->type->name,
823 static struct dm_dirty_log_type _core_type = {
828 .resume = core_resume,
829 .get_region_size = core_get_region_size,
830 .is_clean = core_is_clean,
831 .in_sync = core_in_sync,
833 .mark_region = core_mark_region,
834 .clear_region = core_clear_region,
835 .get_resync_work = core_get_resync_work,
836 .set_region_sync = core_set_region_sync,
837 .get_sync_count = core_get_sync_count,
838 .status = core_status,
841 static struct dm_dirty_log_type _disk_type = {
846 .postsuspend = disk_flush,
847 .resume = disk_resume,
848 .get_region_size = core_get_region_size,
849 .is_clean = core_is_clean,
850 .in_sync = core_in_sync,
852 .mark_region = core_mark_region,
853 .clear_region = core_clear_region,
854 .get_resync_work = core_get_resync_work,
855 .set_region_sync = core_set_region_sync,
856 .get_sync_count = core_get_sync_count,
857 .status = disk_status,
860 static int __init dm_dirty_log_init(
void)
866 DMWARN(
"couldn't register core log");
870 DMWARN(
"couldn't register disk type");
877 static void __exit dm_dirty_log_exit(
void)