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