Alan and group,
This patch, the combined work of:
"B. D. Elliott" <bde@nwlink.com>
"Mike Galbraith" <mikeg@weiden.de>
At least temporarily fixes the problem with Linux initial ramdisk
support. However, it does not fix the problem with the loop-device
containing stale data if it is used a second time. The loop-device
needs to have its buffers invalidated when it is closed.
Can you put this into the next development kernel, please.
--- linux-2.3.39/drivers/block/rd.c.orig Mon Jan 17 09:12:55 2000
+++ linux-2.3.39/drivers/block/rd.c Mon Jan 17 09:15:04 2000
@@ -213,24 +213,23 @@
}
/*
- * This has become somewhat more complicated with the addition of
- * the page cache. The problem is that in some cases the furnished
+ * There is a problem here in that in some cases the furnished
* buffer is "real", i.e., part of the existing ramdisk, while in
* others it is "unreal", e.g., part of a page. In the first case
* not much needs to be done, while in the second, some kind of
* transfer is needed.
*
- * The two cases are distinguished here by checking whether the
- * real buffer is already in the buffer cache, and whether it is
- * the same as the one supplied.
+ * The two cases are distinguished by checking whether the real
+ * buffer is already in the buffer cache, and whether it matches
+ * the one supplied.
*
* There are three cases with read/write to consider:
*
- * 1. Supplied buffer matched one in the buffer cache:
- * Read - Clear the buffer, as it wasn't already valid.
+ * 1. Supplied buffer matched the one in the buffer cache:
+ * Read - Clear the buffer, as it wasn't previously valid.
* Write - Mark the buffer as "Protected".
*
- * 2. Supplied buffer mismatched one in the buffer cache:
+ * 2. Supplied buffer mismatched the one in the buffer cache:
* Read - Copy the data from the buffer cache entry.
* Write - Copy the data to the buffer cache entry.
*
@@ -239,19 +238,13 @@
* one.
* Write - Create a real buffer, copy the data to it, and mark
* it as "Protected".
- *
- * NOTE: There seems to be some schizophrenia here - the logic
- * using "len" seems to assume arbitrary request lengths, while
- * the "protect" logic assumes a single buffer cache entry.
- * This seems to be left over from the ancient contiguous ramdisk
- * logic.
*/
sbh = CURRENT->bh;
rbh = get_hash_table(sbh->b_dev, sbh->b_blocknr, sbh->b_size);
if (sbh == rbh) {
if (CURRENT->cmd == READ)
- memset(CURRENT->buffer, 1, len);
+ memset(CURRENT->buffer, 0, len);
} else if (rbh) {
if (CURRENT->cmd == READ)
memcpy(CURRENT->buffer, rbh->b_data, rbh->b_size);
@@ -259,14 +252,18 @@
memcpy(rbh->b_data, CURRENT->buffer, rbh->b_size);
} else { /* !rbh */
if (CURRENT->cmd == READ)
- memset(sbh->b_data, 2, len);
+ memset(sbh->b_data, 0, len);
else {
rbh = getblk(sbh->b_dev, sbh->b_blocknr, sbh->b_size);
if (rbh)
memcpy(rbh->b_data, CURRENT->buffer,
rbh->b_size);
- else
- BUG(); /* No buffer, what to do here? */
+ else {
+ printk(KERN_ERR "RAMDISK: "
+ "could not allocate buffer\n");
+ end_request(0);
+ goto repeat;
+ }
}
}
if (rbh) {
@@ -573,7 +570,7 @@
memset(&infile, 0, sizeof(infile));
memset(&inode, 0, sizeof(inode));
memset(&in_dentry, 0, sizeof(in_dentry));
- inode.i_rdev = device;
+ init_special_inode(&inode, S_IFBLK | S_IRWXU, device);
init_waitqueue_head(&inode.i_wait);
infile.f_mode = 1; /* read only */
infile.f_dentry = &in_dentry;
@@ -582,7 +579,7 @@
memset(&outfile, 0, sizeof(outfile));
memset(&out_inode, 0, sizeof(out_inode));
memset(&out_dentry, 0, sizeof(out_dentry));
- out_inode.i_rdev = ram_device;
+ init_special_inode(&out_inode, S_IFBLK | S_IRWXU, ram_device);
init_waitqueue_head(&out_inode.i_wait);
outfile.f_mode = 3; /* read/write */
outfile.f_dentry = &out_dentry;
@@ -829,7 +826,7 @@
unsigned n;
uch *in, ch;
- crd_outfp->f_op->write(crd_outfp, window, outcnt, &crd_outfp->f_pos);
+ block_write(crd_outfp, window, outcnt, &crd_outfp->f_pos);
in = window;
for (n = 0; n < outcnt; n++) {
ch = *in++;
--- linux-2.3.39/fs/block_dev.c.orig Sun Jan 9 19:51:37 2000
+++ linux-2.3.39/fs/block_dev.c Mon Jan 17 09:15:04 2000
@@ -606,7 +606,7 @@
/* syncing will go here */
if (kind == BDEV_FILE || kind == BDEV_FS)
fsync_dev(rdev);
- if (atomic_dec_and_test(&bdev->bd_openers)) {
+ if (atomic_dec_and_test(&bdev->bd_openers) && MAJOR(rdev) != RAMDISK_MAJOR) {
/* invalidating buffers will go here */
invalidate_buffers(rdev);
}
Cheers,
Dick Johnson
Penguin : Linux version 2.3.39 on an i686 machine (800.63 BogoMips).
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Sun Jan 23 2000 - 21:00:15 EST