From: Alasdair G Kergon <agk@redhat.com>

Add parameter to register_snapshot() which we can set if we know the origin
structure already exists so will never need allocating.

(A subsequent patch will call it in such circumstances.)

Signed-off-by: Alasdair G Kergon <agk@redhat.com>
---
 drivers/md/dm-snap.c |   26 +++++++++++++++++++-------
 1 file changed, 19 insertions(+), 7 deletions(-)

Index: linux-2.6.32-rc6/drivers/md/dm-snap.c
===================================================================
--- linux-2.6.32-rc6.orig/drivers/md/dm-snap.c
+++ linux-2.6.32-rc6/drivers/md/dm-snap.c
@@ -306,15 +306,19 @@ static void __insert_origin(struct origi
  * Make a note of the snapshot and its origin so we can look it
  * up when the origin has a write on it.
  */
-static int register_snapshot(struct dm_snapshot *snap)
+static int register_snapshot(struct dm_snapshot *snap,
+			     int origin_exists)
 {
 	struct dm_snapshot *l;
-	struct origin *o, *new_o;
+	struct origin *o, *new_o = NULL;
 	struct block_device *bdev = snap->origin->bdev;
+	int r = 0;
 
-	new_o = kmalloc(sizeof(*new_o), GFP_KERNEL);
-	if (!new_o)
-		return -ENOMEM;
+	if (!origin_exists) {
+		new_o = kmalloc(sizeof(*new_o), GFP_KERNEL);
+		if (!new_o)
+			return -ENOMEM;
+	}
 
 	down_write(&_origins_lock);
 	o = __lookup_origin(bdev);
@@ -322,6 +326,12 @@ static int register_snapshot(struct dm_s
 	if (o)
 		kfree(new_o);
 	else {
+		if (origin_exists) {
+			DMERR("register_snapshot failed to find origin.");
+			r = -EINVAL;
+			goto out;
+		}
+
 		/* New origin */
 		o = new_o;
 
@@ -338,8 +348,10 @@ static int register_snapshot(struct dm_s
 			break;
 	list_add_tail(&snap->list, &l->list);
 
+out:
 	up_write(&_origins_lock);
-	return 0;
+
+	return r;
 }
 
 static void unregister_snapshot(struct dm_snapshot *s)
@@ -715,7 +727,7 @@ static int snapshot_ctr(struct dm_target
 
 	/* Add snapshot to the list of snapshots for this origin */
 	/* Exceptions aren't triggered till snapshot_resume() is called */
-	if (register_snapshot(s)) {
+	if (register_snapshot(s, 0)) {
 		r = -EINVAL;
 		ti->error = "Cannot register snapshot origin";
 		goto bad_load_and_register;
