dm snapshot: extend exception store functions

Supply dm_add_exception as a callback to the read_metadata function.
Add a status function ready for a later patch and name the functions
consistently.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index 74777e0..dccbfb0 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -11,7 +11,6 @@
 #include <linux/pagemap.h>
 #include <linux/vmalloc.h>
 #include <linux/slab.h>
-#include <linux/device-mapper.h>
 
 #define DM_MSG_PREFIX "snapshot exception stores"
 
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h
index 78d1ace..bb9f33d 100644
--- a/drivers/md/dm-exception-store.h
+++ b/drivers/md/dm-exception-store.h
@@ -11,6 +11,7 @@
 #define _LINUX_DM_EXCEPTION_STORE
 
 #include <linux/blkdev.h>
+#include <linux/device-mapper.h>
 
 /*
  * The snapshot code deals with largish chunks of the disk at a
@@ -37,7 +38,6 @@
  * COW device).
  */
 struct dm_exception_store {
-
 	/*
 	 * Destroys this object when you've finished with it.
 	 */
@@ -45,9 +45,13 @@
 
 	/*
 	 * The target shouldn't read the COW device until this is
-	 * called.
+	 * called.  As exceptions are read from the COW, they are
+	 * reported back via the callback.
 	 */
-	int (*read_metadata) (struct dm_exception_store *store);
+	int (*read_metadata) (struct dm_exception_store *store,
+			      int (*callback)(void *callback_context,
+					      chunk_t old, chunk_t new),
+			      void *callback_context);
 
 	/*
 	 * Find somewhere to store the next exception.
@@ -68,6 +72,9 @@
 	 */
 	void (*drop_snapshot) (struct dm_exception_store *store);
 
+	int (*status) (struct dm_exception_store *store, status_type_t status,
+		       char *result, unsigned int maxlen);
+
 	/*
 	 * Return how full the snapshot is.
 	 */
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index 57c946c..936b34e 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -395,7 +395,11 @@
  * 'full' is filled in to indicate if the area has been
  * filled.
  */
-static int insert_exceptions(struct pstore *ps, int *full)
+static int insert_exceptions(struct pstore *ps,
+			     int (*callback)(void *callback_context,
+					     chunk_t old, chunk_t new),
+			     void *callback_context,
+			     int *full)
 {
 	int r;
 	unsigned int i;
@@ -428,7 +432,7 @@
 		/*
 		 * Otherwise we add the exception to the snapshot.
 		 */
-		r = dm_add_exception(ps->snap, de.old_chunk, de.new_chunk);
+		r = callback(callback_context, de.old_chunk, de.new_chunk);
 		if (r)
 			return r;
 	}
@@ -436,7 +440,10 @@
 	return 0;
 }
 
-static int read_exceptions(struct pstore *ps)
+static int read_exceptions(struct pstore *ps,
+			   int (*callback)(void *callback_context, chunk_t old,
+					   chunk_t new),
+			   void *callback_context)
 {
 	int r, full = 1;
 
@@ -449,7 +456,7 @@
 		if (r)
 			return r;
 
-		r = insert_exceptions(ps, &full);
+		r = insert_exceptions(ps, callback, callback_context, &full);
 		if (r)
 			return r;
 	}
@@ -482,7 +489,10 @@
 	kfree(ps);
 }
 
-static int persistent_read_metadata(struct dm_exception_store *store)
+static int persistent_read_metadata(struct dm_exception_store *store,
+				    int (*callback)(void *callback_context,
+						    chunk_t old, chunk_t new),
+				    void *callback_context)
 {
 	int r, uninitialized_var(new_snapshot);
 	struct pstore *ps = get_info(store);
@@ -540,7 +550,7 @@
 		/*
 		 * Read the metadata.
 		 */
-		r = read_exceptions(ps);
+		r = read_exceptions(ps, callback, callback_context);
 		if (r)
 			return r;
 	}
@@ -548,8 +558,8 @@
 	return 0;
 }
 
-static int persistent_prepare(struct dm_exception_store *store,
-			      struct dm_snap_exception *e)
+static int persistent_prepare_exception(struct dm_exception_store *store,
+					struct dm_snap_exception *e)
 {
 	struct pstore *ps = get_info(store);
 	uint32_t stride;
@@ -575,10 +585,10 @@
 	return 0;
 }
 
-static void persistent_commit(struct dm_exception_store *store,
-			      struct dm_snap_exception *e,
-			      void (*callback) (void *, int success),
-			      void *callback_context)
+static void persistent_commit_exception(struct dm_exception_store *store,
+					struct dm_snap_exception *e,
+					void (*callback) (void *, int success),
+					void *callback_context)
 {
 	unsigned int i;
 	struct pstore *ps = get_info(store);
@@ -637,7 +647,7 @@
 	ps->callback_count = 0;
 }
 
-static void persistent_drop(struct dm_exception_store *store)
+static void persistent_drop_snapshot(struct dm_exception_store *store)
 {
 	struct pstore *ps = get_info(store);
 
@@ -675,9 +685,9 @@
 
 	store->destroy = persistent_destroy;
 	store->read_metadata = persistent_read_metadata;
-	store->prepare_exception = persistent_prepare;
-	store->commit_exception = persistent_commit;
-	store->drop_snapshot = persistent_drop;
+	store->prepare_exception = persistent_prepare_exception;
+	store->commit_exception = persistent_commit_exception;
+	store->drop_snapshot = persistent_drop_snapshot;
 	store->fraction_full = persistent_fraction_full;
 	store->context = ps;
 
diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c
index 2a781df..7f6e2e6 100644
--- a/drivers/md/dm-snap-transient.c
+++ b/drivers/md/dm-snap-transient.c
@@ -28,13 +28,16 @@
 	kfree(store->context);
 }
 
-static int transient_read_metadata(struct dm_exception_store *store)
+static int transient_read_metadata(struct dm_exception_store *store,
+				   int (*callback)(void *callback_context,
+						   chunk_t old, chunk_t new),
+				   void *callback_context)
 {
 	return 0;
 }
 
-static int transient_prepare(struct dm_exception_store *store,
-			     struct dm_snap_exception *e)
+static int transient_prepare_exception(struct dm_exception_store *store,
+				       struct dm_snap_exception *e)
 {
 	struct transient_c *tc = (struct transient_c *) store->context;
 	sector_t size = get_dev_size(store->snap->cow->bdev);
@@ -48,10 +51,10 @@
 	return 0;
 }
 
-static void transient_commit(struct dm_exception_store *store,
-			     struct dm_snap_exception *e,
-			     void (*callback) (void *, int success),
-			     void *callback_context)
+static void transient_commit_exception(struct dm_exception_store *store,
+				       struct dm_snap_exception *e,
+				       void (*callback) (void *, int success),
+				       void *callback_context)
 {
 	/* Just succeed */
 	callback(callback_context, 1);
@@ -70,8 +73,8 @@
 
 	store->destroy = transient_destroy;
 	store->read_metadata = transient_read_metadata;
-	store->prepare_exception = transient_prepare;
-	store->commit_exception = transient_commit;
+	store->prepare_exception = transient_prepare_exception;
+	store->commit_exception = transient_commit_exception;
 	store->drop_snapshot = NULL;
 	store->fraction_full = transient_fraction_full;
 
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 018b567..65ff82f 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -430,8 +430,13 @@
 	list_add(&new_e->hash_list, e ? &e->hash_list : l);
 }
 
-int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new)
+/*
+ * Callback used by the exception stores to load exceptions when
+ * initialising.
+ */
+static int dm_add_exception(void *context, chunk_t old, chunk_t new)
 {
+	struct dm_snapshot *s = context;
 	struct dm_snap_exception *e;
 
 	e = alloc_exception();
@@ -660,7 +665,7 @@
 	spin_lock_init(&s->tracked_chunk_lock);
 
 	/* Metadata must only be loaded into one table at once */
-	r = s->store.read_metadata(&s->store);
+	r = s->store.read_metadata(&s->store, dm_add_exception, (void *)s);
 	if (r < 0) {
 		ti->error = "Failed to read snapshot metadata";
 		goto bad_load_and_register;
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h
index 9281236..d9e62b4 100644
--- a/drivers/md/dm-snap.h
+++ b/drivers/md/dm-snap.h
@@ -76,12 +76,6 @@
 };
 
 /*
- * Used by the exception stores to load exceptions hen
- * initialising.
- */
-int dm_add_exception(struct dm_snapshot *s, chunk_t old, chunk_t new);
-
-/*
  * Return the number of sectors in the device.
  */
 static inline sector_t get_dev_size(struct block_device *bdev)