--- linux/drivers/block/ll_rw_blk.c	Tue Apr 10 11:44:28 2001
+++ linux-new-raid/drivers/block/ll_rw_blk.c	Tue Apr 10 11:06:12 2001
@@ -588,11 +588,6 @@
 	count = bh->b_size >> 9;
 	sector = bh->b_rsector;
 
-	/* Uhhuh.. Nasty dead-lock possible here.. */
-	if (buffer_locked(bh))
-		return;
-	/* Maybe the above fixes it, and maybe it doesn't boot. Life is interesting */
-	lock_buffer(bh);
 	if (!buffer_lowprio(bh))
 		io_events[major]++;
 
@@ -838,19 +833,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)) {
@@ -860,16 +842,18 @@
 	}
 
 	for (i = 0; i < nr; i++) {
-		if (bh[i]) {
-			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;
-			}
-#endif
-			make_request(MAJOR(bh[i]->b_rdev), rw, bh[i]);
-		}
+		if (!bh[i])
+ 			continue;
+ 
+ 		set_bit(BH_Req, &bh[i]->b_state);
+ 		bh[i]->b_rdev = bh[i]->b_dev;
+ 		bh[i]->b_rsector = bh[i]->b_blocknr * (bh[i]->b_size >> 9);
+ 
+ 		if (buffer_locked(bh[i]))
+ 		  continue;
+ 
+ 		lock_buffer(bh[i]);
+ 		generic_make_request(rw, bh[i]);
 	}
 	return;
 
@@ -884,6 +868,29 @@
 	return;
 }
 
+int generic_make_request(int rw, struct buffer_head *bh) {
+	int r = 1;
+	struct blk_dev_struct *dev = blk_dev + MAJOR(bh->b_rdev);
+
+	while(dev->make_req_fn) {
+		if((r = dev->make_req_fn(bh, rw)) < 0) {
+			printk(KERN_NOTICE "Custom request function failed\n");
+			bh->b_end_io(bh, 0);
+			return -1;
+		}
+
+		dev = blk_dev + MAJOR(bh->b_rdev);
+		if(!r) break;
+	}
+
+	if(r > 0)
+		make_request(MAJOR(bh->b_rdev), rw, bh);
+
+	return 0;
+}
+
+
+
 #ifdef CONFIG_STRAM_SWAP
 extern int stram_device_init( void );
 #endif
@@ -948,6 +955,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;
@@ -1053,6 +1061,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
--- linux/drivers/block/md.c	Tue Apr 10 11:44:29 2001
+++ linux-new-raid/drivers/block/md.c	Tue Apr 10 11:09:08 2001
@@ -2898,13 +2898,20 @@
 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);
 
 	if (!mddev || !mddev->pers) {
 		err = -ENXIO;
 		goto out;
 	}
 
+ 	err = md_map(MINOR(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->pers->make_request) {
 		if (buffer_locked(bh)) {
 			err = 0;
@@ -3932,6 +3939,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;
--- linux/include/linux/blkdev.h	Tue Apr 10 11:44:28 2001
+++ linux-new-raid/include/linux/blkdev.h	Tue Apr 10 11:10:35 2001
@@ -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
 	 */
 
