The locking when leaving __request was broken.

Split off __deferring()
--- diff/drivers/md/dm.c	2002-11-07 11:50:41.000000000 +0000
+++ source/drivers/md/dm.c	2002-11-11 10:24:45.000000000 +0000
@@ -368,7 +368,12 @@
 	return r;
 }
 
-static int __request(struct mapped_device *md, int rw, struct buffer_head *bh)
+/*
+ * Checks to see if we should be deferring io, if so it queues it
+ * and returns 1.
+ */
+static inline int __deferring(struct mapped_device *md, int rw,
+			      struct buffer_head *bh)
 {
 	int r;
 
@@ -383,31 +388,22 @@
 		 * request, just drop it.
 		 */
 		if (rw == READA) {
-			r = -EIO;
-			goto out_no_lock;
+			down_read(&md->lock);
+			return -EIO;
 		}
 
 		r = queue_io(md, bh, rw);
-		if (r <= 0)
-			/*
-			 * Either an error occurred or we deferred
-			 * successfully.
-			 */
-			goto out_no_lock;
-
-		/*
-		 * We're in a while loop, because someone could
-		 * suspend before we get to the following read
-		 * lock.
-		 */
 		down_read(&md->lock);
-	}
 
-	r = __map_buffer(md, rw, bh);
+		if (r < 0)
+			return r;
 
- out_no_lock:
-	down_read(&md->lock);
-	return r;
+		if (r == 0)
+			return 1; /* deferred successfully */
+
+	}
+
+	return 0;
 }
 
 static int dm_request(request_queue_t *q, int rw, struct buffer_head *bh)
@@ -423,15 +419,27 @@
 
 	down_read(&md->lock);
 
-	r = __request(md, rw, bh);
-	if (r < 0) {
-		buffer_IO_error(bh);
+	r = __deferring(md, rw, bh);
+	if (r < 0)
+		goto bad;
+
+	else if (!r) {
+		/* not deferring */
+		r = __map_buffer(md, rw, bh);
+		if (r < 0)
+			goto bad;
+	} else
 		r = 0;
-	}
 
 	up_read(&md->lock);
 	dm_put(md);
 	return r;
+
+ bad:
+	buffer_IO_error(bh);
+	up_read(&md->lock);
+	dm_put(md);
+	return 0;
 }
 
 static int check_dev_size(kdev_t dev, unsigned long block)