Messages in this thread Patch in this message | | | Date | Thu, 16 Dec 1999 04:43:25 -0800 | From | "B. D. Elliott" <> | Subject | Re: 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/
| |