[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

UNSUBSCRIBE Re: Bug in __invalidate_buffers?



Andreas Dilger wrote:
I previously wrote:
> I have come across what appears to be a bug in __invalidate_buffers()
> w.r.t. the change in ext3-0.0.6 using BH_JDirty instead of BH_Dirty
> for buffers held in the journal.  If invalidate_buffers() is called
> on a device (LVM likes to do this a lot, for whatever reason), it yanks
> JDirty buffers out from underneath the journal layer, and causes an
> oops in journal_insert_checkpoint() (line 385, "buffer_dirty(bh) ||
> buffer_jdirty()" is false).

OK, my previous patch cleans up the ASSERT for invalidate_buffers()
(modulo the fact that it was missing a ')' at the end of the line)
but it hasn't really fixed the whole problem.  If a file write is in
progress when invalidate_buffers() is called, I get an oops:

[[[LVM is in the process of calling PV_FLUSH ioctl => invalidate_buffers()]]]
Attempt to refile free buffer
Unable to handle kernel NULL pointer dereference at virtual address 00000000
<kdb stuff>
refile_buffer
cleanup_transaction
log_do_checkpoint
log_wait_for_space
start_this_handle
journal_start
ext3_file_write
do_readv_writev
sys_write

The oops is from "*(char *)0 = 0" added by the ext3 patch, but I take
it that trying to refile a free buffer is fundamentally a bad thing.

The oops is caused from __invalidate_buffers() calling put_last_free(bh)
on the device buffers (for buffers with b_count == 0 and not dirty), which
must conflict somehow with what jfs expects of the state of a buffer.  It
seems we would not have this problem if bh->b_count was non-zero.

What I'm just testing is checking if a buffer is B_FREE before calling
refile_buffer() on it, and just doing journal_remove_checkpoint() on
the buffer directly...  Nope, still not enough - now I get an oops:

[[[LVM is in the process of calling PV_FLUSH ioctl => invalidate_buffers()]]]
Attempt to refile free buffer
Unable to handle kernel NULL pointer dereference at virtual address 00000000
<kdb stuff>
refile_buffer
journal_clean_data_list
journal_commit_transaction
kjournald

Maybe it is better to just call journal_remove_checkpoint() on a B_FREE
buffer in refile_buffer (if it has a transaction), and only oops if it
is not part of a transaction?  The other option is to add the manual
journal_remove_checkpoint() for all B_FREE buffers instead of calling
refile_buffer().  I'm not sure which is the right thing to do.

Cheers, Andreas

_______________________________________________
Ext3-users mailing list
Ext3-users redhat com
https://listman.redhat.com/mailman/listinfo/ext3-users

-- 
Paul Lathrop

Red Hat, Inc.
Sales Engineer
tel: 206.613.6806
 
[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]