[patch] Re: 2.3.29: ramdisk still broken.

Mike Galbraith (mikeg@weiden.de)
Wed, 1 Dec 1999 22:35:07 +0100 (CET)


On Tue, 30 Nov 1999, Stephen C. Tweedie wrote:

> Hi,
>
> On Mon, 29 Nov 1999 06:03:54 +0100 (CET), Mike Galbraith
> <mikeg@weiden.de> said:
>
> > (when I said I'd taken the ramdisk out of the buffer cache, I meant only
> > the persistent data.. copied that unconditionally to/from vmalloc'd area
> > instead of pegging down buffers. works fine but is slooo)
>
> Slow, perhaps, but it's probably the only way to preserve proper buffer
> cache semantics now given the fancy tricks with moving blocks in memory
> that the filesystem layers are playing.

Then maybe I should go ahead and post a vmalloc patch.

-Mike

--- drivers/block/rd.c.org Wed Dec 1 12:12:20 1999
+++ drivers/block/rd.c Wed Dec 1 12:14:47 1999
@@ -40,6 +40,10 @@
*
* Make block size and block size shift for RAM disks a global macro
* and set blk_size for -ENOSPC, Werner Fink <werner@suse.de>, Apr '99
+ *
+ * Temporary OOM fix. Reverted to static ramdisk until someone can come
+ * up with a better solution. Added setup parameter 'ramdisk_blocksize='
+ * for in-kernel ramdisk. Mike Galbraith, Dec '99
*/

#include <linux/config.h>
@@ -54,6 +58,7 @@
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/malloc.h>
+#include <linux/vmalloc.h>
#include <linux/ioctl.h>
#include <linux/fd.h>
#include <linux/module.h>
@@ -95,8 +100,9 @@

static unsigned long rd_length[NUM_RAMDISKS]; /* Size of RAM disks in bytes */
static int rd_hardsec[NUM_RAMDISKS]; /* Size of real blocks in bytes */
-static int rd_blocksizes[NUM_RAMDISKS]; /* Size of 1024 byte blocks :) */
-static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */
+static int rd_blocksizes[NUM_RAMDISKS]; /* Size of logical blocks in bytes*/
+static int rd_kbsize[NUM_RAMDISKS]; /* Size of device in KB */
+static void * rd_data[NUM_RAMDISKS]; /* Data area */

/*
* Parameters for the boot-loading of the RAM disk. These are set by
@@ -106,14 +112,7 @@
*/
int rd_size = 4096; /* Size of the RAM disks */
/*
- * It would be very desiderable to have a soft-blocksize (that in the case
- * of the ramdisk driver is also the hardblocksize ;) of PAGE_SIZE because
- * doing that we'll achieve a far better MM footprint. Using a rd_blocksize of
- * BLOCK_SIZE in the worst case we'll make PAGE_SIZE/BLOCK_SIZE buffer-pages
- * unfreeable. With a rd_blocksize of PAGE_SIZE instead we are sure that only
- * 1 page will be protected. Depending on the size of the ramdisk you
- * may want to change the ramdisk blocksize to achieve a better or worse MM
- * behaviour. The default is still BLOCK_SIZE (needed by rd_load_image that
+ * The default is still BLOCK_SIZE (needed by rd_load_image that
* supposes the filesystem in the image uses a BLOCK_SIZE blocksize).
*/
int rd_blocksize = BLOCK_SIZE; /* Size of the RAM disks */
@@ -167,20 +166,21 @@
return ramdisk_size(str);
}

+static int __init ramdisk_blocksize(char *str)
+{
+ rd_blocksize = simple_strtol(str,NULL,0);
+ return 1;
+}
+
__setup("ramdisk_start=", ramdisk_start_setup);
__setup("load_ramdisk=", load_ramdisk);
__setup("prompt_ramdisk=", prompt_ramdisk);
__setup("ramdisk=", ramdisk_size);
__setup("ramdisk_size=", ramdisk_size2);
+__setup("ramdisk_blocksize=", ramdisk_blocksize);

#endif

-/*
- * Basically, my strategy here is to set up a buffer-head which can't be
- * deleted, and make that my Ramdisk. If the request is outside of the
- * allocated size, we must get rid of it...
- *
- */
static void rd_request(void)
{
unsigned int minor;
@@ -210,17 +210,10 @@
goto repeat;
}

- /*
- * If we're reading, fill the buffer with 0's. This is okay since
- * we're using protected buffers which should never get freed...
- *
- * If we're writing, we protect the buffer.
- */
-
- if (CURRENT->cmd == READ)
- memset(CURRENT->buffer, 0, len);
+ if (CURRENT->cmd == READ)
+ memcpy(CURRENT->buffer, rd_data[minor]+offset, len);
else
- set_bit(BH_Protected, &CURRENT->bh->b_state);
+ memcpy(rd_data[minor]+offset, CURRENT->buffer, len);

end_request(1);
goto repeat;
@@ -304,6 +297,7 @@

static int rd_open(struct inode * inode, struct file * filp)
{
+ int device;
#ifdef CONFIG_BLK_DEV_INITRD
if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) {
if (!initrd_start) return -ENODEV;
@@ -316,6 +310,11 @@
if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
return -ENXIO;

+ device = DEVICE_NR(inode->i_rdev);
+ if (!rd_data[device])
+ if(!(rd_data[device] = vmalloc(rd_length[device])))
+ return -ENOMEM;
+
MOD_INC_USE_COUNT;

return 0;
@@ -346,8 +345,11 @@
{
int i;

- for (i = 0 ; i < NUM_RAMDISKS; i++)
+ for (i = 0 ; i < NUM_RAMDISKS; i++) {
invalidate_buffers(MKDEV(MAJOR_NR, i));
+ if (rd_data[i])
+ vfree(rd_data[i]);
+ }

unregister_blkdev( MAJOR_NR, "ramdisk" );
blk_dev[MAJOR_NR].request_fn = 0;

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