Re: 2.3.40 loop-device-behaviour

From: Richard B. Johnson (root@chaos.analogic.com)
Date: Thu Jan 27 2000 - 13:18:42 EST

  • Next message: Ingo Molnar: "Re: [patch] smp-2.3.41-A1, (was: Re: BUG? i386 TLB Flushing)"

    On Thu, 27 Jan 2000, Ralf Burger wrote:

    > hi all,
    >
    > > > csb:/usr/src/linux # mount -t minix -o loop /tmp/fsfile /mnt/fd2
    > > > mount: wrong fs type, bad option, bad superblock on /dev/loop0,
    > > > or too many mounted file systems
    > >
    > > I do not know if your problem is the same, but I experience
    > > difficulties with stale data staying in memory.
    > >
    > > Consider the following script:
    > >
    > > genromfs -a 512 -f flash.root.image -d proto
    > ....
    >
    > ok - the loop-device-problem is solved by workaround (thanks for the
    > asisstence - btw. "cat /dev/zero >/dev/loop" is also helpful) -
    > but now I've got a new one:
    >
    > whenever I try to build a root/boot-disk with a 2.3.xx-er kernel, I'll get an
    > Oops:
    >
    > after kernel-loading and startup-messages
    > ...
    > ...
    > Floppy drive(s): fd0 is 1.44M
    > FDC 0 is a post-1991 82077
    > Unable to handle kernel NULL pointer dereference at virtual address 000000030
    > printing eip:
    > c012fb51
    > *pde = 0000000000
    > Oops: 0000
    > CPU: 0
    > EIP: 0010:[c012fb51]
    > EFLAGS: 00010202
    > ...
    >
    >
    > I've build several thousends of root/boot-disks with 2.0.xx and 2.2.xx
    > kernels - any hints or ideas ?
    >
    >
    > best regards
    >
    > ralf
    >

    Try this patch. It worked for me.

    --- linux/drivers/block/rd.c.orig Fri Jan 7 11:38:05 2000
    +++ linux/drivers/block/rd.c Sun Jan 16 01:42:32 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++;

    --- fs/block_dev.c.org Mon Jan 17 05:33:16 2000
    +++ fs/block_dev.c Mon Jan 17 05:34:20 2000
    @@ -627,7 +627,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 : Thu Jan 27 2000 - 16:57:51 EST