patch-2.2.8 linux/drivers/block/rd.c
Next file: linux/drivers/cdrom/cdrom.c
Previous file: linux/drivers/block/ide.c
Back to the patch index
Back to the overall index
- Lines: 274
- Date:
Thu Apr 29 11:53:41 1999
- Orig file:
v2.2.7/linux/drivers/block/rd.c
- Orig date:
Wed Apr 28 11:37:30 1999
diff -u --recursive --new-file v2.2.7/linux/drivers/block/rd.c linux/drivers/block/rd.c
@@ -33,11 +33,13 @@
*
* Added initrd: Werner Almesberger & Hans Lermen, Feb '96
*
-* 4/25/96 : Made RAM disk size a parameter (default is now 4 MB)
+ * 4/25/96 : Made RAM disk size a parameter (default is now 4 MB)
* - Chad Page
*
* Add support for fs images split across >1 disk, Paul Gortmaker, Mar '98
*
+ * 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
*/
#include <linux/config.h>
@@ -47,6 +49,7 @@
#include <linux/romfs_fs.h>
#include <linux/fs.h>
#include <linux/kernel.h>
+#include <linux/hdreg.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/mman.h>
@@ -70,6 +73,15 @@
#define MAJOR_NR RAMDISK_MAJOR
#include <linux/blk.h>
+/*
+ * We use a block size of 512 bytes in comparision to BLOCK_SIZE
+ * defined in include/linux/blk.h. This because of the finer
+ * granularity for filling up a RAM disk.
+ */
+#define RDBLK_SIZE_BITS 9
+#define RDBLK_SIZE (1<<RDBLK_SIZE_BITS)
+
+
/* The RAM disk size is now a parameter */
#define NUM_RAMDISKS 16 /* This cannot be overridden (yet) */
@@ -89,8 +101,10 @@
/* Various static variables go here. Most are used only in the RAM disk code.
*/
-static int rd_length[NUM_RAMDISKS];
-static int rd_blocksizes[NUM_RAMDISKS];
+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 */
/*
* Parameters for the boot-loading of the RAM disk. These are set by
@@ -120,9 +134,12 @@
static void rd_request(void)
{
unsigned int minor;
- int offset, len;
+ unsigned long offset, len;
repeat:
+ if (!CURRENT)
+ return;
+
INIT_REQUEST;
minor = MINOR(CURRENT->rq_dev);
@@ -132,14 +149,20 @@
goto repeat;
}
- offset = CURRENT->sector << 9;
- len = CURRENT->current_nr_sectors << 9;
+ offset = CURRENT->sector << RDBLK_SIZE_BITS;
+ len = CURRENT->current_nr_sectors << RDBLK_SIZE_BITS;
if ((offset + len) > rd_length[minor]) {
end_request(0);
goto repeat;
}
+ if ((CURRENT->cmd != READ) && (CURRENT->cmd != WRITE)) {
+ printk(KERN_INFO "RAMDISK: bad command: %d\n", CURRENT->cmd);
+ end_request(0);
+ 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...
@@ -158,24 +181,31 @@
static int rd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
+ unsigned int minor;
+
if (!inode || !inode->i_rdev)
return -EINVAL;
+ minor = MINOR(inode->i_rdev);
+
switch (cmd) {
case BLKFLSBUF:
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
invalidate_buffers(inode->i_rdev);
break;
+
case BLKGETSIZE: /* Return device size */
if (!arg) return -EINVAL;
- return put_user(rd_length[MINOR(inode->i_rdev)] / 512,
- (long *) arg);
- case BLKSSZGET:
- /* Block size of media */
- return put_user(rd_blocksizes[MINOR(inode->i_rdev)],
- (int *)arg);
+ return put_user(rd_length[minor] >> RDBLK_SIZE_BITS, (long *) arg);
+
+ case BLKSSZGET: /* Block size of media */
+ if (!arg) return -EINVAL;
+ return put_user(rd_blocksizes[minor], (int *)arg);
+
+ RO_IOCTLS(inode->i_rdev, arg);
+
default:
- break;
+ return -EINVAL;
};
return 0;
@@ -263,7 +293,7 @@
rd_open, /* open */
NULL, /* flush */
rd_release, /* module needs to decrement use count */
- block_fsync /* fsync */
+ block_fsync /* fsync */
};
/* This is the registration and initialization section of the RAM disk driver */
@@ -279,11 +309,16 @@
blk_dev[MAJOR_NR].request_fn = &rd_request;
for (i = 0; i < NUM_RAMDISKS; i++) {
- rd_length[i] = (rd_size * 1024);
- rd_blocksizes[i] = 1024;
+ /* rd_size is given in kB */
+ rd_length[i] = (rd_size << BLOCK_SIZE_BITS);
+ rd_hardsec[i] = RDBLK_SIZE;
+ rd_blocksizes[i] = BLOCK_SIZE;
+ rd_kbsize[i] = (rd_length[i] >> BLOCK_SIZE_BITS);
}
- blksize_size[MAJOR_NR] = rd_blocksizes;
+ hardsect_size[MAJOR_NR] = rd_hardsec; /* Size of the RAM disk blocks */
+ blksize_size[MAJOR_NR] = rd_blocksizes; /* Avoid set_blocksize() check */
+ blk_size[MAJOR_NR] = rd_kbsize; /* Size of the RAM disk in kB */
printk("RAM disk driver initialized: %d RAM disks of %dK size\n",
NUM_RAMDISKS, rd_size);
@@ -295,7 +330,8 @@
#ifdef MODULE
-MODULE_PARM (rd_size, "1i");
+MODULE_PARM (rd_size, "1i");
+MODULE_PARM_DESC(rd_size, "Size of each RAM disk.");
int init_module(void)
{
@@ -427,7 +463,7 @@
/*
* This routine loads in the RAM disk image.
*/
-__initfunc(static void rd_load_image(kdev_t device,int offset))
+__initfunc(static void rd_load_image(kdev_t device, int offset, int unit))
{
struct inode inode, out_inode;
struct file infile, outfile;
@@ -440,7 +476,7 @@
unsigned short devblocks = 0;
char rotator[4] = { '|' , '/' , '-' , '\\' };
- ram_device = MKDEV(MAJOR_NR, 0);
+ ram_device = MKDEV(MAJOR_NR, unit);
memset(&infile, 0, sizeof(infile));
memset(&inode, 0, sizeof(inode));
@@ -480,9 +516,9 @@
goto done;
}
- if (nblocks > (rd_length[0] >> BLOCK_SIZE_BITS)) {
+ if (nblocks > (rd_length[unit] >> RDBLK_SIZE_BITS)) {
printk("RAMDISK: image too big! (%d/%d blocks)\n",
- nblocks, rd_length[0] >> BLOCK_SIZE_BITS);
+ nblocks, rd_length[unit] >> RDBLK_SIZE_BITS);
goto done;
}
@@ -538,7 +574,7 @@
successful_load:
invalidate_buffers(device);
- ROOT_DEV = MKDEV(MAJOR_NR,0);
+ ROOT_DEV = MKDEV(MAJOR_NR, unit);
done:
if (infile.f_op->release)
@@ -547,12 +583,21 @@
}
-__initfunc(void rd_load(void))
+__initfunc(static void rd_load_disk(int n))
{
+#ifdef CONFIG_BLK_DEV_INITRD
+ extern kdev_t real_root_dev;
+#endif
+
if (rd_doload == 0)
return;
-
- if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR) return;
+
+ if (MAJOR(ROOT_DEV) != FLOPPY_MAJOR
+#ifdef CONFIG_BLK_DEV_INITRD
+ && MAJOR(real_root_dev) != FLOPPY_MAJOR
+#endif
+ )
+ return;
if (rd_prompt) {
#ifdef CONFIG_BLK_DEV_FD
@@ -563,15 +608,24 @@
wait_for_keypress();
}
- rd_load_image(ROOT_DEV,rd_image_start);
+ rd_load_image(ROOT_DEV,rd_image_start, n);
}
+__initfunc(void rd_load(void))
+{
+ rd_load_disk(0);
+}
+
+__initfunc(void rd_load_secondary(void))
+{
+ rd_load_disk(1);
+}
#ifdef CONFIG_BLK_DEV_INITRD
__initfunc(void initrd_load(void))
{
- rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),0);
+ rd_load_image(MKDEV(MAJOR_NR, INITRD_MINOR),0,0);
}
#endif
@@ -695,7 +749,14 @@
crd_load(struct file * fp, struct file *outfp))
{
int result;
-
+
+ insize = 0; /* valid bytes in inbuf */
+ inptr = 0; /* index of next byte to be processed in inbuf */
+ outcnt = 0; /* bytes in output buffer */
+ exit_code = 0;
+ bytes_out = 0;
+ crc = (ulg)0xffffffffL; /* shift register contents */
+
crd_infp = fp;
crd_outfp = outfp;
inbuf = kmalloc(INBUFSIZ, GFP_KERNEL);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)