Re: Initial Ramdisk support (patch)

From: Richard B. Johnson (root@chaos.analogic.com)
Date: Mon Jan 17 2000 - 10:17:58 EST


Alan and group,

        This patch, the combined work of:
        "B. D. Elliott" <bde@nwlink.com>
        "Mike Galbraith" <mikeg@weiden.de>

At least temporarily fixes the problem with Linux initial ramdisk
support. However, it does not fix the problem with the loop-device
containing stale data if it is used a second time. The loop-device
needs to have its buffers invalidated when it is closed.

Can you put this into the next development kernel, please.

--- linux-2.3.39/drivers/block/rd.c.orig Mon Jan 17 09:12:55 2000
+++ linux-2.3.39/drivers/block/rd.c Mon Jan 17 09:15:04 2000
@@ -213,24 +213,23 @@
         }
 
         /*
- * This has become somewhat more complicated with the addition of
- * the page cache. The problem is that in some cases the furnished
+ * There is a problem here in 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.
+ * The two cases are distinguished by checking whether the real
+ * buffer is already in the buffer cache, and whether it matches
+ * the one supplied.
          *
          * 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.
+ * 1. Supplied buffer matched the one in the buffer cache:
+ * Read - Clear the buffer, as it wasn't previously valid.
          * Write - Mark the buffer as "Protected".
          *
- * 2. Supplied buffer mismatched one in the buffer cache:
+ * 2. Supplied buffer mismatched the one in the buffer cache:
          * Read - Copy the data from the buffer cache entry.
          * Write - Copy the data to the buffer cache entry.
          *
@@ -239,19 +238,13 @@
          * 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);
+ memset(CURRENT->buffer, 0, len);
         } else if (rbh) {
                 if (CURRENT->cmd == READ)
                         memcpy(CURRENT->buffer, rbh->b_data, rbh->b_size);
@@ -259,14 +252,18 @@
                         memcpy(rbh->b_data, CURRENT->buffer, rbh->b_size);
         } else { /* !rbh */
                 if (CURRENT->cmd == READ)
- memset(sbh->b_data, 2, len);
+ memset(sbh->b_data, 0, 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? */
+ else {
+ printk(KERN_ERR "RAMDISK: "
+ "could not allocate buffer\n");
+ end_request(0);
+ goto repeat;
+ }
                 }
         }
         if (rbh) {
@@ -573,7 +570,7 @@
         memset(&infile, 0, sizeof(infile));
         memset(&inode, 0, sizeof(inode));
         memset(&in_dentry, 0, sizeof(in_dentry));
- inode.i_rdev = device;
+ init_special_inode(&inode, S_IFBLK | S_IRWXU, device);
         init_waitqueue_head(&inode.i_wait);
         infile.f_mode = 1; /* read only */
         infile.f_dentry = &in_dentry;
@@ -582,7 +579,7 @@
         memset(&outfile, 0, sizeof(outfile));
         memset(&out_inode, 0, sizeof(out_inode));
         memset(&out_dentry, 0, sizeof(out_dentry));
- out_inode.i_rdev = ram_device;
+ init_special_inode(&out_inode, S_IFBLK | S_IRWXU, ram_device);
         init_waitqueue_head(&out_inode.i_wait);
         outfile.f_mode = 3; /* read/write */
         outfile.f_dentry = &out_dentry;
@@ -829,7 +826,7 @@
     unsigned n;
     uch *in, ch;
     
- crd_outfp->f_op->write(crd_outfp, window, outcnt, &crd_outfp->f_pos);
+ block_write(crd_outfp, window, outcnt, &crd_outfp->f_pos);
     in = window;
     for (n = 0; n < outcnt; n++) {
             ch = *in++;
--- linux-2.3.39/fs/block_dev.c.orig Sun Jan 9 19:51:37 2000
+++ linux-2.3.39/fs/block_dev.c Mon Jan 17 09:15:04 2000
@@ -606,7 +606,7 @@
         /* syncing will go here */
         if (kind == BDEV_FILE || kind == BDEV_FS)
                 fsync_dev(rdev);
- if (atomic_dec_and_test(&bdev->bd_openers)) {
+ if (atomic_dec_and_test(&bdev->bd_openers) && MAJOR(rdev) != RAMDISK_MAJOR) {
                 /* invalidating buffers will go here */
                 invalidate_buffers(rdev);
         }

Cheers,
Dick Johnson

Penguin : Linux version 2.3.39 on an i686 machine (800.63 BogoMips).

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



This archive was generated by hypermail 2b29 : Sun Jan 23 2000 - 21:00:15 EST