--- linux/drivers/block/ll_rw_blk.c	Mon Mar  5 17:25:24 2001
+++ linux-raid/drivers/block/ll_rw_blk.c	Mon Mar  5 17:12:50 2001
@@ -838,19 +838,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 (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)) {
@@ -861,14 +848,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(bh[i], rw);
-				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;
@@ -948,6 +947,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;
@@ -1049,6 +1049,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 -ur -X /home/joe/packages/dontdiff linux/drivers/block/md.c linux-raid/drivers/block/md.c
--- linux/drivers/block/md.c	Mon Mar  5 17:25:25 2001
+++ linux-raid/drivers/block/md.c	Mon Mar  5 17:23:14 2001
@@ -2880,7 +2880,7 @@
 #endif
 
 int md_map (kdev_t dev, kdev_t *rdev,
-			 unsigned long *rsector, unsigned long size)
+	    unsigned long *rsector, unsigned long size)
 {
 	int err;
 	mddev_t *mddev = kdev_to_mddev(dev);
@@ -2898,7 +2898,13 @@
 int md_make_request (struct buffer_head * bh, int rw)
 {
 	int err;
-	mddev_t *mddev = kdev_to_mddev(bh->b_dev);
+	mddev_t *mddev = kdev_to_mddev(bh->b_rdev);
+
+	err = md_map(bh->b_rdev, &bh->b_rdev, &bh->b_rsector, bh->b_size >> 9);
+	if(err) {
+	  printk(KERN_ERR "Bad md_map in md_make_request\n");
+	  return err;
+	}
 
 	if (!mddev || !mddev->pers) {
 		err = -ENXIO;
@@ -2926,10 +2932,9 @@
 			}
 		}
 		err = mddev->pers->make_request(mddev, rw, bh);
-	} else {
-		make_request (MAJOR(bh->b_rdev), rw, bh);
-		err = 0;
-	}
+	} else
+		err = 1;
+
 out:
 	return err;
 }
@@ -3932,6 +3937,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;
 	md_gendisk.next = gendisk_head;
diff -ur -X /home/joe/packages/dontdiff linux/include/linux/blkdev.h linux-raid/include/linux/blkdev.h
--- linux/include/linux/blkdev.h	Mon Mar  5 17:25:24 2001
+++ linux-raid/include/linux/blkdev.h	Mon Mar  5 17:21:43 2001
@@ -65,8 +65,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,8 +104,7 @@
 extern void make_request(int major,int rw, struct buffer_head * bh);
 
 /* md needs this function to remap requests */
-extern int md_map (kdev_t dev, kdev_t *rdev,
-				 unsigned long *rsector, unsigned long size);
+extern int md_map (kdev_t dev, kdev_t *rdev, unsigned long *rsector, unsigned long size);
 extern int md_make_request (struct buffer_head * bh, int rw);
 extern int md_error (kdev_t mddev, kdev_t rdev);
 
