patch-2.0.21 linux/drivers/block/ll_rw_blk.c

Next file: linux/drivers/char/mem.c
Previous file: linux/drivers/block/ide_modes.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.20/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
@@ -349,6 +349,10 @@
 	}
 
 /* look for a free request. */
+       /* Loop uses two requests, 1 for loop and 1 for the real device.
+        * Cut max_req in half to avoid running out and deadlocking. */
+        if (major == LOOP_MAJOR)
+	     max_req >>= 1;
 
 	/*
 	 * Try to coalesce the new request with old requests
@@ -508,7 +512,6 @@
 	for (i = 0; i < nr; i++) {
 		if (bh[i]) {
 			set_bit(BH_Req, &bh[i]->b_state);
-
 			make_request(MAJOR(bh[i]->b_rdev), rw, bh[i]);
 		}
 	}
@@ -528,6 +531,7 @@
 {
 	int i, j;
 	int buffersize;
+	int max_req;
 	unsigned long rsector;
 	kdev_t rdev;
 	struct request * req[8];
@@ -539,10 +543,12 @@
                                    " nonexistent block-device\n");
 		return;
 	}
+	max_req = NR_REQUEST;
 	switch (rw) {
 		case READ:
 			break;
 		case WRITE:
+			max_req = (NR_REQUEST * 2) / 3;
 			if (is_read_only(dev)) {
 				printk(KERN_NOTICE
                                        "Can't swap to read-only device %s\n",
@@ -555,6 +561,8 @@
 	}
 	buffersize = PAGE_SIZE / nb;
 
+	if (major == LOOP_MAJOR)
+	     max_req >>= 1;
 	for (j=0, i=0; i<nb;)
 	{
 		for (; j < 8 && i < nb; j++, i++, buf += buffersize)
@@ -572,10 +580,10 @@
 #endif
 			
 			if (j == 0) {
-				req[j] = get_request_wait(NR_REQUEST, rdev);
+				req[j] = get_request_wait(max_req, rdev);
 			} else {
 				cli();
-				req[j] = get_request(NR_REQUEST, rdev);
+				req[j] = get_request(max_req, rdev);
 				sti();
 				if (req[j] == NULL)
 					break;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov