Re: A Possible Solution to the Ramdisk Problem

Tigran Aivazian (tigran@sco.COM)
Fri, 19 Nov 1999 08:34:16 +0000 (GMT)


Hi Bruce,

I tested your fix and it works. Furthermore, since Linus accepted some of
my minor cleanups to rd.c into 2.3.29-pre1 it moved slightly so I made a
new version of your patch that applies cleanly to 2.3.29-pre1 and
re-tested it again (works, of course). A copy is on

http://www.ocston.org/~tigran/patches/other/bde-ramdisk-2.3.29-p1.patch

regards,
Tigran.

--- linux/drivers/block/rd.c Fri Nov 19 09:00:38 1999
+++ 2329-p1-rd/drivers/block/rd.c Fri Nov 19 09:14:26 1999
@@ -185,6 +185,7 @@
{
unsigned int minor;
unsigned long offset, len;
+ struct buffer_head *rbh, *sbh;

repeat:
INIT_REQUEST;
@@ -211,16 +212,63 @@
}

/*
- * If we're reading, fill the buffer with 0's. This is okay since
- * we're using protected buffers which should never get freed...
+ * This has become somewhat more complicated with the addition of
+ * the page cache. The problem is 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.
*
- * If we're writing, we protect the buffer.
+ * 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.
+ * Write - Mark the buffer as "Protected".
+ *
+ * 2. Supplied buffer mismatched one in the buffer cache:
+ * Read - Copy the data from the buffer cache entry.
+ * Write - Copy the data to the buffer cache entry.
+ *
+ * 3 No buffer cache entry existed:
+ * Read - Clear the supplied buffer, but do not create a real
+ * 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.
*/
-
- if (CURRENT->cmd == READ)
- memset(CURRENT->buffer, 0, len);
- else
+ 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, 0, len);
+ } else if (rbh) {
+ if (CURRENT->cmd == READ)
+ memcpy(CURRENT->buffer, rbh->b_data, rbh->b_size);
+ else
+ memcpy(rbh->b_data, CURRENT->buffer, rbh->b_size);
+ } else { /* !rbh */
+ if (CURRENT->cmd == READ)
+ 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? */
+ }
+ }
+ if (rbh) {
set_bit(BH_Protected, &CURRENT->bh->b_state);
+ brelse(rbh);
+ }

end_request(1);
goto repeat;

-
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/