2.3.40 loop-device-behaviour

Richard B. Johnson root en chaos.analogic.com
Jue Ene 27 16:03:15 CST 2000


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 en vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



Más información sobre la lista de distribución Ayuda