[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Kernel oops on new mailserver
On Tue, 2002-03-26 at 05:24, Paul Schutte wrote:
> Hi,
>
> It happened again.
>
> Dell PE2550
> 1G RAM
> 2 x 1.133GHz CPUs
> 4x18Gb Seagate cheeta's in RAID 10 on Perc hardware RAID
>
> kernel 2.4.18 (checked out on 21 March 2002 ) after the following take:
>
Don't worry, I have not forgotten you! Nathan's change is mostly all
formatting, no real structural changes in there.
Can you try this code?
Thanks,
Steve
Steve Lord voice: +1-651-683-3511
Principal Engineer, Filesystem Software email: lord@sgi.com
===========================================================================
Index: linux/fs/xfs/pagebuf/page_buf_io.c
===========================================================================
--- /usr/tmp/TmpDir.17165-0/linux/fs/xfs/pagebuf/page_buf_io.c_1.18 Tue Mar 26 08:31:11 2002
+++ linux/fs/xfs/pagebuf/page_buf_io.c Mon Mar 25 12:50:15 2002
@@ -638,12 +638,12 @@
error = bmap(inode, ((loff_t)page->index << PAGE_CACHE_SHIFT),
PAGE_CACHE_SIZE, &map, 1, &nmaps, PBF_READ);
+
+ hook_buffers_to_page(target, inode, page, &map, nmaps);
+ bh = head = page->buffers;
if (error)
BUG();
- if (map.pbm_bn >= 0) {
- hook_buffers_to_page(target, inode, page, &map, nmaps);
- bh = head = page->buffers;
- } else if (map.pbm_flags & (PBMF_HOLE|PBMF_DELAY)) {
+ if (map.pbm_flags & (PBMF_HOLE|PBMF_DELAY)) {
memset(kmap(page), 0, PAGE_CACHE_SIZE);
flush_dcache_page(page);
kunmap(page);
@@ -754,11 +754,10 @@
{
struct buffer_head *bh;
- if (page->buffers)
- BUG();
- create_empty_buffers(page, target->pbr_device, PAGE_CACHE_SIZE);
+ if (!page->buffers)
+ create_empty_buffers(page, target->pbr_device, PAGE_CACHE_SIZE);
bh = page->buffers;
- bh->b_state = (1 << BH_Delay) | (1 << BH_Mapped);
+ bh->b_state = (1 << BH_Delay) | (1 << BH_Mapped) | (1 << BH_Uptodate);
__mark_buffer_dirty(bh);
buffer_insert_inode_data_queue(bh, inode);
balance_dirty();
@@ -785,19 +784,22 @@
* delta = offset of _this_ page in extent.
* pbm_offset = offset in file corresponding to pbm_bn.
*/
- delta = page->index; /* do computations in 64 bit ... */
- delta <<= PAGE_CACHE_SHIFT; /* delta now offset from 0 of page */
- delta -= mp->pbm_offset; /* delta now offset in extent of page */
-
- bn = mp->pbm_bn >>
- (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
- bn += (delta >> PAGE_CACHE_SHIFT);
- lock_buffer(bh);
- bh->b_blocknr = bn;
- bh->b_dev = target->pbr_device;
- set_bit(BH_Mapped, &bh->b_state);
- clear_bit(BH_Delay, &bh->b_state);
- unlock_buffer(bh);
+
+ if (mp->pbm_bn >= 0) {
+ delta = page->index; /* do computations in 64 bit */
+ delta <<= PAGE_CACHE_SHIFT; /* delta is offset from 0 of page */
+ delta -= mp->pbm_offset; /* delta is offset in extent */
+ bn = mp->pbm_bn >>
+ (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
+ bn += (delta >> PAGE_CACHE_SHIFT);
+ bh = page->buffers;
+ lock_buffer(bh);
+ bh->b_blocknr = bn;
+ bh->b_dev = target->pbr_device;
+ set_bit(BH_Mapped, &bh->b_state);
+ clear_bit(BH_Delay, &bh->b_state);
+ unlock_buffer(bh);
+ }
}
STATIC void
@@ -809,13 +811,9 @@
int need_balance_dirty = 0;
#ifdef PAGEBUF_DEBUG
- /* negative blocknr is always bad; if it's zero, and the
- * inode & bh are on different devices, it could be an
- * xfs realtime file, which would be OK. Either that
- * or something is seriously wrong!
+ /* negative blocknr is always bad;
*/
- if ((bh->b_blocknr < 0) ||
- ((bh->b_blocknr == 0) && (inode->i_dev == bh->b_dev))) {
+ if (bh->b_blocknr < 0) {
printk("Warning: buffer 0x%p with weird blockno (%ld)\n",
bh, bh->b_blocknr);
}
@@ -860,8 +858,10 @@
* go get some space.
*/
bh = page->buffers;
+/***
if ((!bh || buffer_delay(bh)) && (!dp || (flags & PBF_FILE_ALLOCATE)))
- {
+***/
+ if (!bh || !buffer_mapped(bh)) {
if (!mp) {
mp = map;
err = bmap(inode, ((loff_t)page->index << PAGE_CACHE_SHIFT),
@@ -870,10 +870,8 @@
goto out;
}
}
- if (mp->pbm_bn >= 0) {
- hook_buffers_to_page(target, inode, page, mp, nmaps);
- bh = page->buffers;
- }
+ hook_buffers_to_page(target, inode, page, mp, nmaps);
+ bh = page->buffers;
}
/* Is the write over the entire page? */
@@ -961,9 +959,9 @@
* parts of page not covered by from/to. Page is now fully valid.
*/
SetPageUptodate(page);
- if ((bh = page->buffers) && !buffer_delay(bh)) {
+ if ((bh = page->buffers) && buffer_mapped(bh)) {
set_buffer_dirty_uptodate(inode, page->buffers, partial);
- } else if (!DelallocPage(page)) {
+ } else {
hook_buffers_to_page_delay(target, inode, page);
}
}
@@ -1363,7 +1361,7 @@
/* Three possible conditions - page with delayed buffers,
* page with real buffers, or page with no buffers (mmap)
*/
- if (!bh || DelallocPage(page)) {
+ if (!bh || DelallocPage(page) || !buffer_mapped(bh)) {
hook_buffers_to_page(target, inode, page, mp, nmaps);
}
@@ -1424,7 +1422,8 @@
loff_t rounded_offset;
/* Fast path for mapped page */
- if (page->buffers && !buffer_delay(page->buffers)) {
+ if (page->buffers && !buffer_delay(page->buffers) &&
+ buffer_mapped(page->buffers)) {
if (async_write) {
submit_page_io(page);
}