--- /src/2.6.7.csnap/drivers/md/dm-csnap.c	2004-09-03 21:02:24.000000000 +0000
+++ dm-csnap.c	2004-09-03 21:01:15.000000000 +0000
@@ -6,7 +6,6 @@
 #include <linux/file.h>
 #include <net/sock.h>
 #include <asm/uaccess.h>
-#include <linux/bio.h>
 #include "dm.h"
 #include "dm-csnap.h"
 
@@ -19,12 +18,22 @@
 
 #define trace trace_on
 
+#define bio buffer_head
+#define bi_sector b_rsector
+#define bio_end_io_t bh_end_io_t
+#define bi_private b_private
+#define bi_end_io b_end_io
+#define bi_bdev b_rdev
+#define CLONE_KERNEL (CLONE_FS|CLONE_FILES|CLONE_SIGNAL)
+#define SOCKET_I(inode) (&inode->u.socket_i)
+#define bio_data_dir(bio) rw
+#define bi_size b_size
+
 /* Pipe helpers */
 
 static int rwpipe(struct file *file, const void *buffer, unsigned int count,
-	ssize_t (*op)(struct kiocb *, const char *, size_t, loff_t), int mode)
+	ssize_t (*op)(struct file *, const char *, size_t, loff_t *), int mode)
 {
-	struct kiocb iocb;
 	mm_segment_t oldseg;
 	int err = 0;
 
@@ -33,12 +42,10 @@
 		return -EBADF;
 	if (!op)
 		return -EINVAL;
-	init_sync_kiocb(&iocb, file); // new in 2.5 (hmm)
-	iocb.ki_pos = file->f_pos;
 	oldseg = get_fs();
 	set_fs(get_ds());
 	while (count) {
-		int chunk = (*op)(&iocb, buffer, count, iocb.ki_pos);
+		int chunk = (*op)(file, buffer, count, &file->f_pos);
 		if (chunk <= 0) {
 			err = chunk? chunk: -EPIPE;
 			break;
@@ -48,18 +55,17 @@
 		buffer += chunk;
 	}
 	set_fs(oldseg);
-	file->f_pos = iocb.ki_pos;
 	return err;
 }
 
 static inline int readpipe(struct file *file, void *buffer, unsigned int count)
 {
-	return rwpipe(file, buffer, count, (void *)file->f_op->aio_read, FMODE_READ);
+	return rwpipe(file, buffer, count, (void *)file->f_op->read, FMODE_READ);
 }
 
 static inline int writepipe(struct file *file, void *buffer, unsigned int count)
 {
-	return rwpipe(file, buffer, count, file->f_op->aio_write, FMODE_WRITE);
+	return rwpipe(file, buffer, count, file->f_op->write, FMODE_WRITE);
 }
 
 #define outbead(SOCK, CODE, STRUCT, VALUES...) ({ \
@@ -167,6 +173,7 @@
 	u64 chunk;
 	unsigned chunks;
 	unsigned id;
+	unsigned rw;
 	struct bio *bio;
 	list_t list;
 };
@@ -256,7 +263,7 @@
 	list_t list;
 };
 
-static int snapshot_read_end_io(struct bio *bio, unsigned int done, int error)
+static void snapshot_read_end_io(struct bio *bio, int uptodate)
 {
 	struct end_io_hook *hook = bio->bi_private;
 	struct snapinfo *info = hook->info;
@@ -269,7 +276,7 @@
 
 	bio->bi_private = hook->old_private;
 	bio->bi_end_io = hook->old_end_io;
-	return bio->bi_end_io(bio, done, error);
+	bio->bi_end_io(bio, uptodate);
 }
 
 /* This is the part that does all the work. */
@@ -306,7 +313,7 @@
 		if (chunks != pending->chunks) {
 			warn("Message mismatch, expected %x got %x", chunks, chunks);
 			kmem_cache_free(pending_cache, pending);
-			bio_io_error(bio, bio->bi_size);
+			buffer_IO_error(bio);
 			return -1;
 		}
 
@@ -317,7 +324,7 @@
 				u64 logical = bio->bi_sector;
 				u64 physical = (*p2++ << shift) + (logical & mask);
 				trace(warn("logical %Lx = physical %Lx", logical, physical));
-				bio->bi_bdev = info->snapdev->bdev;
+				bio->bi_bdev = info->snapdev->dev;
 				bio->bi_sector = physical;
 			}
 			p = (struct chunk_range *)p2;
@@ -338,7 +345,7 @@
 			bio->bi_private = hook;
 		}
 
-		generic_make_request(bio);
+		generic_make_request(rw, bio);
 		submitted++;
 #ifdef CACHE
 		for (j = 0; j < p->chunks; j++)
@@ -347,13 +354,7 @@
 		kmem_cache_free(pending_cache, pending);
 	}
 	if (submitted){
-		request_queue_t *q;
-		q = bdev_get_queue(info->orgdev->bdev);
-		if (q->unplug_fn)
-			q->unplug_fn(q);
-		q = bdev_get_queue(info->snapdev->bdev);
-		if (q->unplug_fn)
-			q->unplug_fn(q);
+		run_task_queue(&tq_disk);
 	}
 	return 0;
 }
@@ -582,14 +583,14 @@
  * at the moment, or may not have been established yet, in which case we have
  * to defer the request until the server becomes available.
  */
-static int csnap_map(struct dm_target *target, struct bio *bio, union map_info *context)
+static int csnap_map(struct dm_target *target, struct bio *bio, int rw, union map_info *context)
 {
 	struct snapinfo *info = target->private;
 	struct pending *pending;
 	chunk_t chunk;
 	unsigned id;
 
-	bio->bi_bdev = info->orgdev->bdev;
+	bio->bi_bdev = info->orgdev->dev;
 	if (bio_data_dir(bio) == READ && !is_snapshot(info))
 		return 1;
 
@@ -625,7 +626,7 @@
 
 	id = info->nextid;
 	info->nextid = (id + 1) & ~(-1 << ID_BITS);
-	*pending = (struct pending){ .id = id, .bio = bio, .chunk = chunk, .chunks = 1 };
+	*pending = (struct pending){ .id = id, .bio = bio, .rw = rw, .chunk = chunk, .chunks = 1 };
 	spin_lock(&info->pending_lock);
 	list_add(&pending->list, info->pending_buckets + hash_pending(pending->id));
 	spin_unlock(&info->pending_lock);
@@ -787,7 +788,6 @@
 	if ((err = kernel_thread((void *)worker, target, CLONE_KERNEL)) < 0)
 		goto eek;
 	warn("Created snapshot device origin=%s snapstore=%s snapshot=%i", argv[0], argv[1], snap);
-	target->split_io = 1 << info->chunkshift; // !!! lose this as soon as possible
 	return 0;
 
 eek:	warn("Virtual device create error %i: %s!", err, error);
@@ -828,8 +828,6 @@
 
 static int csnap_status(struct dm_target *target, status_type_t type, char *result, unsigned int maxlen)
 {
-	char orgbuffer[32];
-	char snapbuffer[32];
 	struct snapinfo *info = target->private;
 
 	switch (type) {
@@ -838,10 +836,10 @@
 		break;
 
 	case STATUSTYPE_TABLE:
-		format_dev_t(orgbuffer, info->orgdev->bdev->bd_dev);
-		format_dev_t(snapbuffer, info->snapdev->bdev->bd_dev);
 		snprintf(result, maxlen, "%s %s %u",
-			 orgbuffer, snapbuffer, 1 << info->chunksize_bits);
+			dm_kdevname(info->orgdev->dev),
+			dm_kdevname(info->snapdev->dev),
+			1 << info->chunksize_bits);
 		break;
 	}
 
