Messages in this thread Patch in this message | | | Date | Mon, 7 Feb 2000 17:32:50 +0100 (CET) | From | Mike Galbraith <> | Subject | Re: 2.3.42 fs corruption |
| |
On Fri, 4 Feb 2000, Andrea Arcangeli wrote:
> I would be interested to know if people who experienced fs corruption with > the late 2.3.x is able to reproduce after applying this patch on the top > of 2.3.42: > > ftp://ftp.*.kernel.org/pub/linux/kernel/people/andrea/kernels/v2.3/2.3.42aa2.gz > > The interesting bit is this: > > ftp://ftp.*.kernel.org/pub/linux/kernel/people/andrea/kernels/v2.3/2.3.42aa2/buffer-4.gz > > I am now running under heavy fs/dentry load 2.3.42aa2 on alpha and I am > waiting to reproduce. If you have hints on how to exploit the corruption > your're welcome ;).
I know an excellent way to create corruption :) Use the loop device on an fs-in-a-box created with mke2fs -Fqb ${BLKSIZE} ${BOX} ${BLOCKS}. What corruption happens is dependant on what blocksize the host fs is. It gets more interesting when you use the same dirctory/file names on two different fs with two different blocksizes.
Your buffer-4 fixed 99% of the trouble :) Replacing invalidate_buffers() with destroy_buffers() got rid of the crumbs it was leaving around.
-Mike
<sigh> P.S. With the attached diag-diff, it almost works perfectly now. (seems to be a bit racy if you reuse too soon. the hunk that seems likely to make your facial expression change is why I'm attaching it. I really don't understand why it has to start with blocksize=PAGE_SIZE to work right.. almost.. and hope some reader may know why:) --- drivers/block/loop.c.org Wed Feb 2 07:16:15 2000 +++ drivers/block/loop.c Mon Feb 7 16:39:13 2000 @@ -435,6 +435,7 @@ lo->lo_dentry = dget(file->f_dentry); lo->transfer = NULL; lo->ioctl = NULL; + set_blocksize(MKDEV(MAJOR_NR,lo->lo_number), PAGE_SIZE); figure_loop_size(lo); out_putf: @@ -506,7 +507,8 @@ memset(lo->lo_encrypt_key, 0, LO_KEY_SIZE); memset(lo->lo_name, 0, LO_NAME_SIZE); loop_sizes[lo->lo_number] = 0; - invalidate_buffers(dev); + loop_blksizes[lo->lo_number] = 0; + destroy_buffers(dev); MOD_DEC_USE_COUNT; return 0; } @@ -757,10 +759,10 @@ } memset(loop_sizes, 0, max_loop * sizeof(int)); memset(loop_blksizes, 0, max_loop * sizeof(int)); - blk_size[MAJOR_NR] = loop_sizes; blksize_size[MAJOR_NR] = loop_blksizes; for (i=0; i < max_loop; i++) register_disk(NULL, MKDEV(MAJOR_NR,i), 1, &lo_fops, 0); + blk_size[MAJOR_NR] = loop_sizes; return 0; } @@ -771,6 +773,9 @@ if (unregister_blkdev(MAJOR_NR, "loop") != 0) printk(KERN_WARNING "loop: cannot unregister blkdev\n"); + blksize_size[MAJOR_NR] = NULL; + blk_size[MAJOR_NR] = NULL; + kfree (loop_dev); kfree (loop_sizes); kfree (loop_blksizes); | |