lkml.org 
[lkml]   [1999]   [Dec]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: Ok, making ready for pre-2.4 and code-freeze..
On Wed, Dec 15, 1999 at 10:20:08AM -0500, Richard B. Johnson wrote:

[ ... ]

> This initial ramdisk "initrd" seems to work with the patch submitted
> yeaterday, but user-mode ramdisk doesn't retain data and the loop-back
> device doesn't write back data to the file that was mounted via
> loop.
>
> This means that I can boot the new kernel with an initial ram-disk,
> but I can't make a new one when using the new kernel.

Yes, it's definitely broken. The problem is the BH_Protected flag is
set on the wrong buffer in some cases. The patch below seems to work
a lot better for me.

=======================================================================
--- linux/init/main.c.orig Wed Dec 8 23:20:25 1999
+++ linux/init/main.c Wed Dec 8 23:22:27 1999
@@ -499,6 +500,7 @@
kmem_cache_init();
sti();
calibrate_delay();
+#if 0000
#ifdef CONFIG_BLK_DEV_INITRD
// FIXME, use the bootmem.h interface.
if (initrd_start && !initrd_below_start_ok && initrd_start < memory_start) {
@@ -507,6 +509,7 @@
initrd_start = 0;
}
#endif
+#endif /* 0000 */
mem_init();
kmem_cache_sizes_init();
#ifdef CONFIG_PROC_FS
--- linux/drivers/block/rd.c.orig Wed Dec 8 23:20:19 1999
+++ linux/drivers/block/rd.c Thu Dec 16 04:12:40 1999
@@ -189,6 +189,8 @@
{
unsigned int minor;
unsigned long offset, len;
+ struct buffer_head *rbh;
+ struct buffer_head *sbh;

repeat:
INIT_REQUEST;
@@ -215,16 +217,66 @@
}

/*
- * 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.
- */
-
- if (CURRENT->cmd == READ)
- memset(CURRENT->buffer, 0, len);
- else
- set_bit(BH_Protected, &CURRENT->bh->b_state);
+ * 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.
+ */
+
+ 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);
+ } 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, 2, 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, &rbh->b_state);
+ brelse(rbh);
+ }

end_request(1);
goto repeat;
--- linux/arch/i386/kernel/setup.c.orig Tue Dec 7 23:01:40 1999
+++ linux/arch/i386/kernel/setup.c Wed Dec 8 23:22:27 1999
@@ -706,7 +706,7 @@
#endif

#ifdef CONFIG_BLK_DEV_INITRD
- if (LOADER_TYPE) {
+ if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE < (max_low_pfn << PAGE_SHIFT)) {
reserve_bootmem(INITRD_START, INITRD_SIZE);
initrd_start =
=======================================================================
--
B. D. Elliott bde@nwlink.com (Seattle)

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

\
 
 \ /
  Last update: 2005-03-22 13:55    [W:0.125 / U:1.016 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site