Set the ti->split_io field for the origin to the smallest chunk-size of its
snapshots. This is done each time the origin is resumed, since new snapshots
(with smaller chunk-sizes) could have been added.  [Kevin Corry]


--- diff/drivers/md/dm-snapshot.c	2003-10-29 14:52:46.000000000 +0000
+++ source/drivers/md/dm-snapshot.c	2003-10-29 14:52:57.000000000 +0000
@@ -1139,6 +1139,33 @@
 	return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : 1;
 }
 
+#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r))
+
+/*
+ * Set the target "split_io" field to the minimum of all the snapshots'
+ * chunk sizes.
+ */
+static void origin_resume(struct dm_target *ti)
+{
+	struct dm_dev *dev = (struct dm_dev *) ti->private;
+	struct dm_snapshot *snap;
+	struct origin *o;
+	struct list_head *sl;
+	chunk_t chunk_size = 0;
+
+	down_read(&_origins_lock);
+	o = __lookup_origin(dev->bdev);
+	if (o) {
+		list_for_each(sl, &o->snapshots) {
+			snap = list_entry(sl, struct dm_snapshot, list);
+			chunk_size = min_not_zero(chunk_size, snap->chunk_size);
+		}
+	}
+	up_read(&_origins_lock);
+
+	ti->split_io = chunk_size;
+}
+
 static int origin_status(struct dm_target *ti, status_type_t type, char *result,
 			 unsigned int maxlen)
 {
@@ -1165,6 +1192,7 @@
 	ctr:	origin_ctr,
 	dtr:	origin_dtr,
 	map:	origin_map,
+	resume:	origin_resume,
 	status:	origin_status,
 };