Don't read metadata if we are going to do handover. This saves memory (without the patch, the exception store would consume twice more memory while doing handover). If the handover doesn't happen (due to user abusing dmsetup), the snapshot is marked as invalid. Signed-off-by: Mikulas Patocka Reviewed-by: Mike Snitzer Reviewed-by: Jonathan Brassow --- drivers/md/dm-exception-store.h | 6 +++++- drivers/md/dm-snap-persistent.c | 5 +++-- drivers/md/dm-snap-transient.c | 2 +- drivers/md/dm-snap.c | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) Index: linux-2.6.31-fast-new-2/drivers/md/dm-exception-store.h =================================================================== --- linux-2.6.31-fast-new-2.orig/drivers/md/dm-exception-store.h 2009-10-16 20:54:34.000000000 +0200 +++ linux-2.6.31-fast-new-2/drivers/md/dm-exception-store.h 2009-10-16 21:48:19.000000000 +0200 @@ -54,11 +54,15 @@ struct dm_exception_store_type { * The target shouldn't read the COW device until this is * called. As exceptions are read from the COW, they are * reported back via the callback. + * + * will_handover means that there is another snapshot active; + * chunk size must be setup but no exceptions need to be read + * because they will be handed over from the active snapshot. */ int (*read_metadata) (struct dm_exception_store *store, int (*callback)(void *callback_context, chunk_t old, chunk_t new), - void *callback_context); + void *callback_context, int will_handover); /* * Find somewhere to store the next exception. Index: linux-2.6.31-fast-new-2/drivers/md/dm-snap-persistent.c =================================================================== --- linux-2.6.31-fast-new-2.orig/drivers/md/dm-snap-persistent.c 2009-10-16 20:54:34.000000000 +0200 +++ linux-2.6.31-fast-new-2/drivers/md/dm-snap-persistent.c 2009-10-16 21:48:19.000000000 +0200 @@ -529,7 +529,7 @@ static void persistent_dtr(struct dm_exc static int persistent_read_metadata(struct dm_exception_store *store, int (*callback)(void *callback_context, chunk_t old, chunk_t new), - void *callback_context) + void *callback_context, int will_handover) { int r, uninitialized_var(new_snapshot); struct pstore *ps = get_info(store); @@ -586,7 +586,8 @@ static int persistent_read_metadata(stru /* * Read the metadata. */ - r = read_exceptions(ps, callback, callback_context); + if (!will_handover) + r = read_exceptions(ps, callback, callback_context); return r; } Index: linux-2.6.31-fast-new-2/drivers/md/dm-snap-transient.c =================================================================== --- linux-2.6.31-fast-new-2.orig/drivers/md/dm-snap-transient.c 2009-10-16 20:54:34.000000000 +0200 +++ linux-2.6.31-fast-new-2/drivers/md/dm-snap-transient.c 2009-10-16 21:48:19.000000000 +0200 @@ -30,7 +30,7 @@ static void transient_dtr(struct dm_exce static int transient_read_metadata(struct dm_exception_store *store, int (*callback)(void *callback_context, chunk_t old, chunk_t new), - void *callback_context) + void *callback_context, int will_handover) { return 0; } Index: linux-2.6.31-fast-new-2/drivers/md/dm-snap.c =================================================================== --- linux-2.6.31-fast-new-2.orig/drivers/md/dm-snap.c 2009-10-16 21:48:16.000000000 +0200 +++ linux-2.6.31-fast-new-2/drivers/md/dm-snap.c 2009-10-16 21:48:19.000000000 +0200 @@ -741,7 +741,7 @@ static int snapshot_ctr(struct dm_target /* Metadata must only be loaded into one table at once */ r = s->store->type->read_metadata(s->store, dm_add_exception, - (void *)s); + (void *)s, s->handover); if (r < 0) { ti->error = "Failed to read snapshot metadata"; goto bad_load_and_register;