patch-1.3.69 linux/drivers/block/ll_rw_blk.c
Next file: linux/drivers/block/loop.c
Previous file: linux/drivers/block/linear.c
Back to the patch index
Back to the overall index
- Lines: 139
- Date:
Mon Feb 26 13:51:45 1996
- Orig file:
v1.3.68/linux/drivers/block/ll_rw_blk.c
- Orig date:
Fri Feb 23 13:54:34 1996
diff -u --recursive --new-file v1.3.68/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
@@ -24,12 +24,7 @@
/*
* The request-struct contains all necessary data
* to load a nr of sectors into memory
- *
- * NR_REQUEST is the number of entries in the request-queue.
- * NOTE that writes may use only the low 2/3 of these: reads
- * take precedence.
*/
-#define NR_REQUEST 64
static struct request all_requests[NR_REQUEST];
/*
@@ -232,11 +227,15 @@
* By this point, req->cmd is always either READ/WRITE, never READA/WRITEA,
* which is important for drive_stat_acct() above.
*/
-static void add_request(struct blk_dev_struct * dev, struct request * req)
+
+struct semaphore request_lock = MUTEX;
+
+void add_request(struct blk_dev_struct * dev, struct request * req)
{
struct request * tmp;
short disk_index;
+ down (&request_lock);
switch (MAJOR(req->rq_dev)) {
case SCSI_DISK_MAJOR:
disk_index = (MINOR(req->rq_dev) & 0x0070) >> 4;
@@ -257,10 +256,11 @@
req->next = NULL;
cli();
- if (req->bh)
+ if (req->bh && req->bh->b_dev==req->bh->b_rdev)
mark_buffer_clean(req->bh);
if (!(tmp = dev->current_request)) {
dev->current_request = req;
+ up (&request_lock);
(dev->request_fn)();
sti();
return;
@@ -274,8 +274,9 @@
req->next = tmp->next;
tmp->next = req;
+ up (&request_lock);
/* for SCSI devices, call request_fn unconditionally */
- if (scsi_major(MAJOR(req->rq_dev)))
+ if (scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR)
(dev->request_fn)();
sti();
@@ -338,6 +339,7 @@
/* look for a free request. */
cli();
+ down (&request_lock);
/* The scsi disk and cdrom drivers completely remove the request
* from the queue when they start processing an entry. For this reason
@@ -345,6 +347,7 @@
*/
if (( major == IDE0_MAJOR /* same as HD_MAJOR */
|| major == IDE1_MAJOR
+ || major == MD_MAJOR
|| major == FLOPPY_MAJOR
|| major == SCSI_DISK_MAJOR
|| major == SCSI_CDROM_MAJOR
@@ -354,6 +357,7 @@
{
if (major != SCSI_DISK_MAJOR && major != SCSI_CDROM_MAJOR)
req = req->next;
+
while (req) {
if (req->rq_dev == bh->b_dev &&
!req->sem &&
@@ -365,6 +369,7 @@
req->bhtail = bh;
req->nr_sectors += count;
mark_buffer_clean(bh);
+ up (&request_lock);
sti();
return;
}
@@ -382,6 +387,7 @@
req->sector = sector;
mark_buffer_clean(bh);
req->bh = bh;
+ up (&request_lock);
sti();
return;
}
@@ -390,6 +396,8 @@
}
}
+ up (&request_lock);
+
/* find an unused request. */
req = get_request(max_req, bh->b_dev);
sti();
@@ -417,6 +425,15 @@
add_request(major+blk_dev,req);
}
+#ifdef CONFIG_BLK_DEV_MD
+
+struct request *get_md_request (int max_req, kdev_t dev)
+{
+ return (get_request_wait (max_req, dev));
+}
+
+#endif
+
/*
* Swap partitions are now read via brw_page. ll_rw_page is an
* asynchronous function now --- we must call wait_on_page afterwards
@@ -515,6 +532,10 @@
for (i = 0; i < nr; i++) {
if (bh[i]) {
set_bit(BH_Req, &bh[i]->b_state);
+
+ /* Md needs this for error recovery */
+ bh[i]->b_rdev = bh[i]->b_dev;
+
make_request(major, rw, bh[i]);
}
}
@@ -658,5 +679,8 @@
#ifdef CONFIG_SJCD
sjcd_init();
#endif CONFIG_SJCD
+#ifdef CONFIG_BLK_DEV_MD
+ md_init();
+#endif CONFIG_BLK_DEV_MD
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this