All of lore.kernel.org
 help / color / mirror / Atom feed
* [QUESTION] Buffer locking and similar
@ 2005-06-15 10:41 Jan Kara
  2005-06-15 21:09 ` Andrew Morton
  0 siblings, 1 reply; 3+ messages in thread
From: Jan Kara @ 2005-06-15 10:41 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: akpm, sct

  Hello,

  I have a simple question: What is exactly the meaning of buffer being
locked (by lock_buffer() or set_buffer_locked())? Because some places -
such as ll_rw_block() suppose that when the buffer is locked it was
already sent for IO (and hence skip the buffer). But other places
violate this assumption and lock_buffer() without submitting it for IO.
What is supposed to be guarded by the buffer lock? Specifically
changes of data in a buffer or marking a buffer dirty does not seem to
need the buffer lock (only if the buffer is uptodate?).
  The final question: should not JBD wait for a buffer lock before it
files a buffer to some list to make sure that a potential write-out of
the buffer is finished? For example do_get_write_access() does not do
this and seems to be racy against __flush_batch().
  I'm willing to make a patch fixing these issues but first I need to be
sure what is actually supposed to be the correct behaviour ;).

					Thanks for an answer
								Honza
-- 
Jan Kara <jack@suse.cz>
SuSE CR Labs

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [QUESTION] Buffer locking and similar
  2005-06-15 10:41 [QUESTION] Buffer locking and similar Jan Kara
@ 2005-06-15 21:09 ` Andrew Morton
  2005-06-24 15:02   ` Jan Kara
  0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2005-06-15 21:09 UTC (permalink / raw)
  To: Jan Kara; +Cc: linux-fsdevel, sct

Jan Kara <jack@suse.cz> wrote:
>
>   Hello,
> 
>   I have a simple question: What is exactly the meaning of buffer being
> locked (by lock_buffer() or set_buffer_locked())?

Good question.   Lots of things.

- Provides exclusion against a thread bringing the buffer uptodate

- Pins the buffer and its page

- Indicates that the buffer is under I/O

- Probably lots of other ad-hoc stuff ;(

> Because some places -
> such as ll_rw_block() suppose that when the buffer is locked it was
> already sent for IO (and hence skip the buffer).

Yes.  Basically it is illegal to unlock a non-uptodate buffer.  IOW: if you
locked a non-uptodate buffer, ll_rw_block() will assume that you locked it
for the purpose of bringing it uptodate, either via a read or a memset.

> But other places
> violate this assumption and lock_buffer() without submitting it for IO.

If it was a non-uptodate buffer then that's bad.  Perhaps we should have a
diagnostic check for a non-uptodate buffer in unlock_buffer().

> What is supposed to be guarded by the buffer lock? Specifically
> changes of data in a buffer or marking a buffer dirty does not seem to
> need the buffer lock (only if the buffer is uptodate?).

If it's non-uptodate then yes, we need lock_buffer exclusion while bringing
it uptodate.

If the buffer was already uptodate then any modification of its data is a
*dirtying* operattion, not a *bringing uptodate* operation.  That's quite a
different thing, and dirtying doesn't require lock_buffer().  Because we
mark the buffer dirty _after_ changing its contents.

>   The final question: should not JBD wait for a buffer lock before it
> files a buffer to some list to make sure that a potential write-out of
> the buffer is finished?

Maybe.  Would need to see specifics and then go into deep-think mode.

> For example do_get_write_access() does not do
> this and seems to be racy against __flush_batch().

do_get_write_access() does lock_buffer().  Can you be more specific?


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [QUESTION] Buffer locking and similar
  2005-06-15 21:09 ` Andrew Morton
@ 2005-06-24 15:02   ` Jan Kara
  0 siblings, 0 replies; 3+ messages in thread
From: Jan Kara @ 2005-06-24 15:02 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-fsdevel, sct

  Hello,

  sorry for a late response but I was not reading emails for a week.

> Jan Kara <jack@suse.cz> wrote:
> >
> >   Hello,
> > 
> >   I have a simple question: What is exactly the meaning of buffer being
> > locked (by lock_buffer() or set_buffer_locked())?
> 
> Good question.   Lots of things.
> 
> - Provides exclusion against a thread bringing the buffer uptodate
  Umm, I'm not sure about this one - some buffers get set uptodate
while only holding the page lock (e.g. in block_read_full_page()). But
they seem to be freshly created buffers so it is probably OK in this
case.

> - Pins the buffer and its page
> 
> - Indicates that the buffer is under I/O
> 
> - Probably lots of other ad-hoc stuff ;(
> 
> > Because some places -
> > such as ll_rw_block() suppose that when the buffer is locked it was
> > already sent for IO (and hence skip the buffer).
> 
> Yes.  Basically it is illegal to unlock a non-uptodate buffer.  IOW: if you
> locked a non-uptodate buffer, ll_rw_block() will assume that you locked it
> for the purpose of bringing it uptodate, either via a read or a memset.
  Actually the situation I'm worried more about is when we are writing
out. For journaling assumptions we need to be sure that if we submit a
buffer for IO it really hits the disk. But ll_rw_blk() silently skips
the buffer if it is locked. So I guess we should not use ll_rw_blk() for
writing in the journaling code as unlocking uptodate but *dirty* buffer is
perfectly OK from what you say.

> > But other places
> > violate this assumption and lock_buffer() without submitting it for IO.
> 
> If it was a non-uptodate buffer then that's bad.  Perhaps we should have a
> diagnostic check for a non-uptodate buffer in unlock_buffer().
  I'll add it and try to run the kernel :).

> > What is supposed to be guarded by the buffer lock? Specifically
> > changes of data in a buffer or marking a buffer dirty does not seem to
> > need the buffer lock (only if the buffer is uptodate?).
> 
> If it's non-uptodate then yes, we need lock_buffer exclusion while bringing
> it uptodate.
> 
> If the buffer was already uptodate then any modification of its data is a
> *dirtying* operattion, not a *bringing uptodate* operation.  That's quite a
> different thing, and dirtying doesn't require lock_buffer().  Because we
> mark the buffer dirty _after_ changing its contents.
  OK, I see the point. Thanks for explanation.

> >   The final question: should not JBD wait for a buffer lock before it
> > files a buffer to some list to make sure that a potential write-out of
> > the buffer is finished?
> 
> Maybe.  Would need to see specifics and then go into deep-think mode.
  See below...

> > For example do_get_write_access() does not do
> > this and seems to be racy against __flush_batch().
> 
> do_get_write_access() does lock_buffer().  Can you be more specific?
  Consider the below race:
    Proc 1                               Proc 2

     __flush_batch()
       ll_rw_block()
                                        do_get_write_access()
                                           do some checks under lock_buffer()
                                           unlock_buffer
    test_set_buffer_locked()
    test_clear_buffer_dirty()
                                           __journal_file_buffer()
                                        change the data
    submit_bh()

  In this case we have made a mistake and attached the buffer to the
transaction even though it is on the way to a disk. Hence some unexpected
data might be written.

								Honza

-- 
Jan Kara <jack@suse.cz>
SuSE CR Labs

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2005-06-24 15:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-15 10:41 [QUESTION] Buffer locking and similar Jan Kara
2005-06-15 21:09 ` Andrew Morton
2005-06-24 15:02   ` Jan Kara

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.