13 #include <linux/export.h>
14 #include <linux/slab.h>
17 #define DM_MSG_PREFIX "persistent snapshot"
18 #define DM_CHUNK_SIZE_DEFAULT_SECTORS 32
52 #define SNAP_MAGIC 0x70416e53
57 #define SNAPSHOT_DISK_VERSION 1
59 #define NUM_SNAPSHOT_HDR_CHUNKS 1
163 static int alloc_area(
struct pstore *
ps)
184 goto err_header_area;
233 struct dm_io_region where = {
236 .count = ps->
store->chunk_size,
238 struct dm_io_request
io_req = {
240 .mem.type = DM_IO_VMA,
276 static int area_io(
struct pstore *ps,
int rw)
283 r = chunk_io(ps, ps->
area, chunk, rw, 0);
290 static void zero_memory_area(
struct pstore *ps)
297 return chunk_io(ps, ps->
zero_area, area_location(ps, area),
WRITE, 0);
300 static int read_header(
struct pstore *ps,
int *new_snapshot)
305 int chunk_size_supplied = 1;
312 if (!ps->
store->chunk_size) {
316 ps->
store->chunk_mask = ps->
store->chunk_size - 1;
318 chunk_size_supplied = 0;
341 DMWARN(
"Invalid or corrupt snapshot");
351 if (ps->
store->chunk_size == chunk_size)
354 if (chunk_size_supplied)
355 DMWARN(
"chunk size %u in device metadata overrides "
356 "table chunk size of %u.",
357 chunk_size, ps->
store->chunk_size);
365 DMERR(
"invalid on-disk chunk size %u: %s.",
366 chunk_size, chunk_err);
378 static int write_header(
struct pstore *ps)
403 static void read_exception(
struct pstore *ps,
413 static void write_exception(
struct pstore *ps,
437 static int insert_exceptions(
struct pstore *ps,
438 int (*
callback)(
void *callback_context,
440 void *callback_context,
451 read_exception(ps, i, &
e);
459 if (
e.new_chunk == 0
LL) {
474 r =
callback(callback_context,
e.old_chunk,
e.new_chunk);
482 static int read_exceptions(
struct pstore *ps,
485 void *callback_context)
494 r = area_io(ps,
READ);
498 r = insert_exceptions(ps,
callback, callback_context, &full);
518 struct pstore *ps = get_info(store);
534 struct pstore *ps = get_info(store);
551 int (*
callback)(
void *callback_context,
553 void *callback_context)
556 struct pstore *ps = get_info(store);
561 r = read_header(ps, &new_snapshot);
579 r = write_header(ps);
581 DMWARN(
"write_header failed");
586 zero_memory_area(ps);
587 r = zero_disk_area(ps, 0);
589 DMWARN(
"zero_disk_area(0) failed");
596 DMWARN(
"unable to handle snapshot disk version %d",
610 r = read_exceptions(ps,
callback, callback_context);
618 struct pstore *ps = get_info(store);
644 void (*
callback) (
void *,
int success),
645 void *callback_context)
648 struct pstore *ps = get_info(store);
664 cb->
context = callback_context;
693 zero_memory_area(ps);
708 struct pstore *ps = get_info(store);
724 r = area_io(ps,
READ);
731 *last_old_chunk =
ce.old_chunk;
732 *last_new_chunk =
ce.new_chunk;
742 if (
ce.old_chunk != *last_old_chunk - nr_consecutive ||
743 ce.new_chunk != *last_new_chunk - nr_consecutive)
747 return nr_consecutive;
754 struct pstore *ps = get_info(store);
758 for (i = 0; i < nr_merged; i++)
785 struct pstore *ps = get_info(store);
788 if (write_header(ps))
789 DMWARN(
"write header failed");
793 unsigned argc,
char **argv)
818 DMERR(
"couldn't start header metadata update thread");
844 .name =
"persistent",
846 .ctr = persistent_ctr,
847 .dtr = persistent_dtr,
848 .read_metadata = persistent_read_metadata,
849 .prepare_exception = persistent_prepare_exception,
850 .commit_exception = persistent_commit_exception,
851 .prepare_merge = persistent_prepare_merge,
852 .commit_merge = persistent_commit_merge,
853 .drop_snapshot = persistent_drop_snapshot,
854 .usage = persistent_usage,
855 .status = persistent_status,
861 .ctr = persistent_ctr,
862 .dtr = persistent_dtr,
863 .read_metadata = persistent_read_metadata,
864 .prepare_exception = persistent_prepare_exception,
865 .commit_exception = persistent_commit_exception,
866 .prepare_merge = persistent_prepare_merge,
867 .commit_merge = persistent_commit_merge,
868 .drop_snapshot = persistent_drop_snapshot,
869 .usage = persistent_usage,
870 .status = persistent_status,
879 DMERR(
"Unable to register persistent exception store type");
885 DMERR(
"Unable to register old-style persistent exception "