patch-2.1.31 linux/drivers/block/loop.c
Next file: linux/drivers/block/md.c
Previous file: linux/drivers/block/ide.c
Back to the patch index
Back to the overall index
- Lines: 136
- Date:
Wed Apr 2 17:43:20 1997
- Orig file:
v2.1.30/linux/drivers/block/loop.c
- Orig date:
Sun Jan 26 02:07:10 1997
diff -u --recursive --new-file v2.1.30/linux/drivers/block/loop.c linux/drivers/block/loop.c
@@ -12,6 +12,8 @@
* Modularized and updated for 1.1.16 kernel - Mitch Dsouza 28th May 1994
*
* Adapted for 1.3.59 kernel - Andries Brouwer, 1 Feb 1996
+ *
+ * Fixed do_loop_request() re-entrancy - <Vincent.Renardias@waw.com> Mar 20, 1997
*/
#include <linux/module.h>
@@ -181,12 +183,15 @@
char *dest_addr;
struct loop_device *lo;
struct buffer_head *bh;
+ struct request *current_request;
repeat:
INIT_REQUEST;
- if (MINOR(CURRENT->rq_dev) >= MAX_LOOP)
+ current_request=CURRENT;
+ CURRENT=current_request->next;
+ if (MINOR(current_request->rq_dev) >= MAX_LOOP)
goto error_out;
- lo = &loop_dev[MINOR(CURRENT->rq_dev)];
+ lo = &loop_dev[MINOR(current_request->rq_dev)];
if (!lo->lo_inode || !lo->transfer)
goto error_out;
@@ -197,14 +202,14 @@
blksize = BLOCK_SIZE;
}
- dest_addr = CURRENT->buffer;
+ dest_addr = current_request->buffer;
if (blksize < 512) {
- block = CURRENT->sector * (512/blksize);
+ block = current_request->sector * (512/blksize);
offset = 0;
} else {
- block = CURRENT->sector / (blksize >> 9);
- offset = (CURRENT->sector % (blksize >> 9)) << 9;
+ block = current_request->sector / (blksize >> 9);
+ offset = (current_request->sector % (blksize >> 9)) << 9;
}
block += lo->lo_offset / blksize;
offset += lo->lo_offset % blksize;
@@ -212,13 +217,13 @@
block++;
offset -= blksize;
}
- len = CURRENT->current_nr_sectors << 9;
+ len = current_request->current_nr_sectors << 9;
- if (CURRENT->cmd == WRITE) {
+ if (current_request->cmd == WRITE) {
if (lo->lo_flags & LO_FLAGS_READ_ONLY)
goto error_out;
- } else if (CURRENT->cmd != READ) {
- printk("unknown loop device command (%d)?!?", CURRENT->cmd);
+ } else if (current_request->cmd != READ) {
+ printk("unknown loop device command (%d)?!?", current_request->cmd);
goto error_out;
}
while (len > 0) {
@@ -237,7 +242,7 @@
block, blksize);
goto error_out;
}
- if (!buffer_uptodate(bh) && ((CURRENT->cmd == READ) ||
+ if (!buffer_uptodate(bh) && ((current_request->cmd == READ) ||
(offset || (len < blksize)))) {
ll_rw_block(READ, 1, &bh);
wait_on_buffer(bh);
@@ -250,13 +255,13 @@
if (size > len)
size = len;
- if ((lo->transfer)(lo, CURRENT->cmd, bh->b_data + offset,
+ if ((lo->transfer)(lo, current_request->cmd, bh->b_data + offset,
dest_addr, size)) {
printk("loop: transfer error block %d\n", block);
brelse(bh);
goto error_out;
}
- if (CURRENT->cmd == WRITE) {
+ if (current_request->cmd == WRITE) {
mark_buffer_uptodate(bh, 1);
mark_buffer_dirty(bh, 1);
}
@@ -266,9 +271,13 @@
offset = 0;
block++;
}
+ current_request->next=CURRENT;
+ CURRENT=current_request;
end_request(1);
goto repeat;
error_out:
+ current_request->next=CURRENT;
+ CURRENT=current_request;
end_request(0);
goto repeat;
}
@@ -484,20 +493,20 @@
return 0;
}
-static void lo_release(struct inode *inode, struct file *file)
+static int lo_release(struct inode *inode, struct file *file)
{
struct loop_device *lo;
int dev;
if (!inode)
- return;
+ return 0;
if (MAJOR(inode->i_rdev) != MAJOR_NR) {
printk("lo_release: pseudo-major != %d\n", MAJOR_NR);
- return;
+ return 0;
}
dev = MINOR(inode->i_rdev);
if (dev >= MAX_LOOP)
- return;
+ return 0;
fsync_dev(inode->i_rdev);
lo = &loop_dev[dev];
if (lo->lo_refcnt <= 0)
@@ -506,6 +515,7 @@
lo->lo_refcnt--;
MOD_DEC_USE_COUNT;
}
+ return 0;
}
static struct file_operations lo_fops = {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov