--- rd.c.0 Thu Dec 23 08:13:58 1999 +++ rd.c Thu Dec 23 09:58:14 1999 @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -93,6 +94,7 @@ /* Various static variables go here. Most are used only in the RAM disk code. */ +static char *rd_memory[NUM_RAMDISKS]; /* where the data is kept */ 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 :) */ @@ -210,17 +212,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); + memcpy(CURRENT->buffer, rd_memory[minor] + offset, len); else - set_bit(BH_Protected, &CURRENT->bh->b_state); + memcpy(rd_memory[minor] + offset, CURRENT->buffer, len); end_request(1); goto repeat; @@ -237,7 +232,8 @@ switch (cmd) { case BLKFLSBUF: - if (!capable(CAP_SYS_ADMIN)) return -EACCES; + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; invalidate_buffers(inode->i_rdev); break; @@ -304,8 +300,10 @@ static int rd_open(struct inode * inode, struct file * filp) { + int minor = DEVICE_NR(inode->i_rdev); + #ifdef CONFIG_BLK_DEV_INITRD - if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) { + if (minor == INITRD_MINOR) { if (!initrd_start) return -ENODEV; initrd_users++; filp->f_op = &initrd_fops; @@ -313,11 +311,21 @@ } #endif - if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS) + if (minor >= NUM_RAMDISKS) return -ENXIO; - MOD_INC_USE_COUNT; + if (rd_memory[minor] == NULL) { + rd_memory[minor] = vmalloc(rd_length[minor]); + if (!rd_memory[minor]) { + printk(KERN_ERR + "RAMDISK: Can't vmalloc(%08lx) for minor=%d\n", + rd_length[minor], minor); + return -ENOMEM; + } + memset(rd_memory[minor], '\0', rd_length[minor]); + } + MOD_INC_USE_COUNT; return 0; } @@ -346,9 +354,11 @@ { int i; - for (i = 0 ; i < NUM_RAMDISKS; i++) + for (i = 0; i < NUM_RAMDISKS; i++) { + if (rd_memory[i] != NULL) + vfree(rd_memory[i]); invalidate_buffers(MKDEV(MAJOR_NR, i)); - + } unregister_blkdev( MAJOR_NR, "ramdisk" ); blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); } @@ -356,16 +366,16 @@ /* This is the registration and initialization section of the RAM disk driver */ int __init rd_init (void) { - int i; + int i; if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 || - (rd_blocksize & (rd_blocksize-1))) - { + (rd_blocksize & (rd_blocksize-1))) { printk("RAMDISK: wrong blocksize %d, reverting to defaults\n", rd_blocksize); rd_blocksize = BLOCK_SIZE; } + if (register_blkdev(MAJOR_NR, "ramdisk", &fd_fops)) { printk("RAMDISK: Could not get major %d", MAJOR_NR); return -EIO; @@ -375,10 +385,11 @@ for (i = 0; i < NUM_RAMDISKS; i++) { /* rd_size is given in kB */ - rd_length[i] = rd_size << 10; + rd_length[i] = PAGE_ALIGN(rd_size << 10); rd_hardsec[i] = rd_blocksize; rd_blocksizes[i] = rd_blocksize; rd_kbsize[i] = rd_size; + rd_memory[i] = NULL; } hardsect_size[MAJOR_NR] = rd_hardsec; /* Size of the RAM disk blocks */ .