diff -urN -X /home/joe/packages/dontdiff linux-2.2.18-raw/drivers/block/ll_rw_blk.c linux-2.2.18-raw-lvm0.9/drivers/block/ll_rw_blk.c
--- linux-2.2.18-raw/drivers/block/ll_rw_blk.c	Wed Dec 13 15:08:14 2000
+++ linux-2.2.18-raw-lvm0.9/drivers/block/ll_rw_blk.c	Wed Dec 13 11:20:11 2000
@@ -826,19 +826,6 @@
 			       correct_size, bh[i]->b_size);
 			goto sorry;
 		}
-
-		/* Md remaps blocks now */
-		bh[i]->b_rdev = bh[i]->b_dev;
-		bh[i]->b_rsector=bh[i]->b_blocknr*(bh[i]->b_size >> 9);
-#ifdef CONFIG_BLK_DEV_MD
-		if (major==MD_MAJOR &&
-		    md_map (MINOR(bh[i]->b_dev), &bh[i]->b_rdev,
-			    &bh[i]->b_rsector, bh[i]->b_size >> 9)) {
-		        printk (KERN_ERR
-				"Bad md_map in ll_rw_block\n");
-		        goto sorry;
-		}
-#endif
 	}
 
 	if ((rw == WRITE || rw == WRITEA) && is_read_only(bh[0]->b_dev)) {
@@ -849,14 +836,26 @@
 
 	for (i = 0; i < nr; i++) {
 		if (bh[i]) {
+			int r = 1;
+
 			set_bit(BH_Req, &bh[i]->b_state);
-#ifdef CONFIG_BLK_DEV_MD
-			if (MAJOR(bh[i]->b_dev) == MD_MAJOR) {
-				md_make_request(MINOR (bh[i]->b_dev), rw, bh[i]);
-				continue;
+
+			bh[i]->b_rdev = bh[i]->b_dev;
+			bh[i]->b_rsector=bh[i]->b_blocknr*(bh[i]->b_size >> 9);
+
+			dev = blk_dev + MAJOR(bh[i]->b_rdev);
+			while(dev->make_req_fn) {
+				if((r = dev->make_req_fn(bh[i], rw)) < 0) {
+					printk(KERN_NOTICE "Custom request function failed\n");
+					goto sorry;
+				}
+
+				dev = blk_dev + MAJOR(bh[i]->b_rdev);
+				if(!r) break;
 			}
-#endif
-			make_request(MAJOR(bh[i]->b_rdev), rw, bh[i]);
+
+			if(r > 0)
+				make_request(MAJOR(bh[i]->b_rdev), rw, bh[i]);
 		}
 	}
 	return;
@@ -936,6 +935,7 @@
 
 	for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) {
 		dev->request_fn      = NULL;
+		dev->make_req_fn          = NULL;
 		dev->queue           = NULL;
 		dev->current_request = NULL;
 		dev->plug.rq_status  = RQ_INACTIVE;
@@ -1037,6 +1037,9 @@
 #ifdef CONFIG_SJCD
 	sjcd_init();
 #endif CONFIG_SJCD
+#ifdef CONFIG_BLK_DEV_LVM
+	lvm_init();
+#endif
 #ifdef CONFIG_BLK_DEV_MD
 	md_init();
 #endif CONFIG_BLK_DEV_MD
diff -urN -X /home/joe/packages/dontdiff linux-2.2.18-raw/drivers/block/md.c linux-2.2.18-raw-lvm0.9/drivers/block/md.c
--- linux-2.2.18-raw/drivers/block/md.c	Mon Sep  4 18:39:16 2000
+++ linux-2.2.18-raw-lvm0.9/drivers/block/md.c	Wed Dec 13 11:20:11 2000
@@ -775,8 +775,16 @@
   return (md_dev[minor].pers->map(md_dev+minor, rdev, rsector, size));
 }
   
-int md_make_request (int minor, int rw, struct buffer_head * bh)
+int md_make_request(struct buffer_head *bh, int rw)
 {
+	int minor = MINOR(bh->b_rdev), r;
+
+	r = md_map(minor, &bh->b_rdev, &bh->b_rsector, bh->b_size >> 9);
+	if(r) {
+	  printk(KERN_ERR "Bad md_map in md_make_request\n");
+	  return r;
+	}
+
 	if (md_dev [minor].pers->make_request) {
 		if (buffer_locked(bh))
 			return 0;
@@ -793,11 +801,12 @@
 				return 0;
 			}
 		}
-		return (md_dev[minor].pers->make_request(md_dev+minor, rw, bh));
-	} else {
-		make_request (MAJOR(bh->b_rdev), rw, bh);
-		return 0;
+
+		/* I presume this returns <0 error, 0 success */
+		return md_dev[minor].pers->make_request(md_dev+minor, rw, bh);
 	}
+
+	return 1;
 }
 
 static void do_md_request (void)
@@ -1320,6 +1329,7 @@
   }
 
   blk_dev[MD_MAJOR].request_fn=DEVICE_REQUEST;
+  blk_dev[MD_MAJOR].make_req_fn = md_make_request;
   blk_dev[MD_MAJOR].current_request=NULL;
   read_ahead[MD_MAJOR]=INT_MAX;
   memset(md_dev, 0, MAX_MD_DEV * sizeof (struct md_dev));
diff -urN -X /home/joe/packages/dontdiff linux-2.2.18-raw/include/linux/blkdev.h linux-2.2.18-raw-lvm0.9/include/linux/blkdev.h
--- linux-2.2.18-raw/include/linux/blkdev.h	Wed Dec 13 15:08:31 2000
+++ linux-2.2.18-raw-lvm0.9/include/linux/blkdev.h	Wed Dec 13 15:34:20 2000
@@ -64,8 +64,20 @@
 #define BLKELVGET   _IOR(0x12,106,sizeof(blkelv_ioctl_arg_t))
 #define BLKELVSET   _IOW(0x12,107,sizeof(blkelv_ioctl_arg_t))
 
+/*
+ * should return:
+ * < 0 - error
+ * 0 - I've handled this request, you can stop now
+ * > 0 - carry on processing
+ */
+typedef int (bd_make_req_fn)(struct buffer_head *bh, int rw);
+
 struct blk_dev_struct {
 	request_fn_proc		*request_fn;
+
+	/* hook for remapping devices, used by md and lvm */
+	bd_make_req_fn *make_req_fn;
+
 	/*
 	 * queue_proc has to be atomic
 	 */
@@ -92,7 +104,7 @@
 
 /* md needs this function to remap requests */
 extern int md_map (int minor, kdev_t *rdev, unsigned long *rsector, unsigned long size);
-extern int md_make_request (int minor, int rw, struct buffer_head * bh);
+extern int md_make_request (struct buffer_head * bh, int rw);
 extern int md_error (kdev_t mddev, kdev_t rdev);
 
 extern int * blk_size[MAX_BLKDEV];
