

After ext3_writepage() has called block_write_full_page() it will walk the
page's buffer ring dropping the buffer_head refcounts.

It does this wrong - on the final loop it will dereference the buffer_head
which it just dropped the refcount on.  Poisoned oopses have been seen
against bh->b_this_page.

Change it to take a local copy of b_this_page prior to dropping the bh's
refcount.




 25-akpm/fs/ext3/inode.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletion(-)

diff -puN fs/ext3/inode.c~jbd-530-walk_page_buffers-race-fix fs/ext3/inode.c
--- 25/fs/ext3/inode.c~jbd-530-walk_page_buffers-race-fix	Thu Jun  5 15:14:34 2003
+++ 25-akpm/fs/ext3/inode.c	Thu Jun  5 15:14:34 2003
@@ -1026,11 +1026,13 @@ static int walk_page_buffers(	handle_t *
 	unsigned block_start, block_end;
 	unsigned blocksize = head->b_size;
 	int err, ret = 0;
+	struct buffer_head *next;
 
 	for (	bh = head, block_start = 0;
 		ret == 0 && (bh != head || !block_start);
-	    	block_start = block_end, bh = bh->b_this_page)
+	    	block_start = block_end, bh = next)
 	{
+		next = bh->b_this_page;
 		block_end = block_start + blocksize;
 		if (block_end <= from || block_start >= to) {
 			if (partial && !buffer_uptodate(bh))

_
