Messages in this thread Patch in this message | | | Date | Sun, 22 Aug 1999 15:43:08 +0200 (CEST) | From | Andrea Arcangeli <> | Subject | [patch] fix for pagecache fs corruption (2.3.15-pre2) [Re: [patch] ramdisk blocksize] |
| |
On Sat, 21 Aug 1999, Bradley D. LaRonde wrote:
>Both initrd and regular ramdisk usage appear to work with the patch applied, >but booting with initrd gives the following error (then goes on, apparently >working fine): > >kernel BUG at buffer.c:696! >invalid operand: 0000 >CPU: 0 >EIP: 0010:[<c01236de>] >EFLAGS: 00010092 >eax: 0000001c ebx: c7ceb060 ecx: c018dc68 edx: c018dc70 >esi: c01a9a90 edi: 00000001 ebp: 00000000 esp: c009df7c >ds: 0018 es: 0018 ss: 0018 >Process kflushd (pid: 3, stackpage=c009d000) >Stack: 000002b8 c0144230 c7ceb060 00000001 c01a9a90 ffffffff c018f38c >c014ee07 > c01a9a90 00000001 c0182d9b 00000001 c014eee3 00000001 00000246 >c018f38c > c01435f4 00000000 c0125fe6 c01b3190 00000f00 c0e9dfb4 c037d0cc >00000912 >Call Trace: [<c0144230>] [<c014ee07>] [<c0182d9b>] [<c014eee3>] [<c01435f4>] >[<c0125fe6>] [<c01065b7>] >Code: 0f 0b 83 c4 0c c3 57 56 53 8b 7c 24 10 8b 4c 24 14 85 c9 74 > >ksymoops says: >EIP: c01236de <end_buffer_io_bad+42/48> >Trace: c0144230 <end_that_request_first+80/c4> >Trace: c014ee07 <end_request+17/34> >Trace: c0182d9b <head_vals.697+21af/35f4> >Trace: c014eee3 <rd_request+bf/cc> >Trace: c01435f4 <unplug_device+38/3c> >Trace: c0125fe6 <bdflush+19e/1fc> >Trace: c01065b7 <kernel_thread+23/30> >Code: c01236de <end_buffer_io_bad+42/48> 00000000 <_EIP>: <=== >Code: c01236de <end_buffer_io_bad+42/48> 0: 0f 0b ud2a ><=== >Code: c01236e0 <end_buffer_io_bad+44/48> 2: 83 c4 0c addl >$0xc,%esp >Code: c01236e3 <end_buffer_io_bad+47/48> 5: c3 ret >Code: c01236e4 <end_buffer_io_async+0/144> 6: 57 >pushl %edi >Code: c01236e5 <end_buffer_io_async+1/144> 7: 56 >pushl %esi >Code: c01236e6 <end_buffer_io_async+2/144> 8: 53 >pushl %ebx >Code: c01236e7 <end_buffer_io_async+3/144> 9: 8b 7c 24 10 movl >0x10(%esp,1),%edi >Code: c01236eb <end_buffer_io_async+7/144> d: 8b 4c 24 14 movl >0x14(%esp,1),%ecx >Code: c01236ef <end_buffer_io_async+b/144> 11: 85 c9 >testl %ecx,%ecx >Code: c01236f1 <end_buffer_io_async+d/144> 13: 74 00 je >c01236f3 <end_buffer_io_async+f/144> > >The error message occurs about 20 seconds after the command shell comes up, >even if no commands are issued. The filesystem appears to be fine, both >before and after the message. Here are the details of what's booted:
I had some bug in my buffer code changes. I fixed it now.
This is a _incremental_ patch against the previous page-cache-ramdisk fixes. NOTE: using pre1 or pre2 make no difference at all for these issues.
It should fix the problem you reported plus some other "uptodate" fixes I noticed now.
diff -urN 2.3.15-pre2-pagecache/fs/buffer.c 2.3.15-pre2-pagecache-devel/fs/buffer.c --- 2.3.15-pre2-pagecache/fs/buffer.c Sun Aug 22 14:36:09 1999 +++ 2.3.15-pre2-pagecache-devel/fs/buffer.c Sun Aug 22 15:32:57 1999 @@ -793,6 +793,10 @@ repeat: bh = get_hash_table(dev, block, size); if (bh) { + /* we may have found a orhpaned-hashed buffer, and so it + may have a end_io handler different than the io_sync one. */ + bh->b_end_io = end_buffer_io_sync; + mb(); if (!buffer_dirty(bh)) { bh->b_flushtime = 0; } @@ -1492,8 +1496,14 @@ bh_old = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size); - if (!bh_old) + if (!bh_old || !buffer_uptodate(bh_old)) { + if (bh_old) + { + trash_buffer(bh_old); + __remove_from_queues(bh_old); + atomic_dec(&bh_old->b_count); + } ll_rw_block(READ, 1, &bh); wait_on_buffer(bh); err = -EIO; @@ -1676,8 +1686,14 @@ bh_old = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size); - if (!bh_old) + if (!bh_old || !buffer_uptodate(bh_old)) { + if (bh_old) + { + trash_buffer(bh_old); + __remove_from_queues(bh_old); + atomic_dec(&bh_old->b_count); + } ll_rw_block(READ, 1, &bh); wait_on_buffer(bh); err = -EIO; @@ -2118,22 +2134,46 @@ bh_old = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size); - if (bh_old) + if (bh_old && buffer_uptodate(bh_old)) { memcpy(bh->b_data, bh_old->b_data, bh->b_size); + set_bit(BH_Uptodate, &bh->b_state); /* move the protected bit from the old buffer to the new buffer. */ if (atomic_expose_buffer(bh_old)) atomic_protect_buffer(bh); if (atomic_set_buffer_clean(bh_old)) + { + /* the buffer will do IO + so it must have a valid + end_io handler before + setting it dirty. */ + bh->b_end_io = end_buffer_io_sync; + /* even if to refile the buffer + will run a spin_lock(), here + is more robust to enforce + a SMP memory barrier by hand + because a buffer is writable + only in function of the + dirty bit and not in + function of where it's + placed in the lru lists. */ + mb(); mark_buffer_dirty(bh, 0); + } /* now trash the old regular buffer */ trash_buffer(bh_old); __remove_from_queues(bh_old); atomic_dec(&bh_old->b_count); continue; + } + if (bh_old) + { + trash_buffer(bh_old); + __remove_from_queues(bh_old); + atomic_dec(&bh_old->b_count); } } }
If you are more confortable with only one whole patch (instead of two incremental patches) against a clean 2.3.15-pre2 you can find it here:
ftp://e-mind.com/pub/andrea/kernel-patches/pending-2.3.x/page-cache-2.3.15-pre2-2
To make the ramdisk drive working properly and to fix the other page-cache fs-corruption bugs you only need to apply the above patch against 2.3.15-pre2. I propose it for inclusion into the next 2.3.x.
Andrea
- 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/
| |