Re: Understanding locking for buf

From: Alexander Lochmann <alexander.lochmann_at_tu-dortmund.de>
Date: Tue, 18 Apr 2023 12:23:44 UTC
Thanks, Kirk, for your explanation!

On 14.04.23 00:24, Kirk McKusick wrote:
> Let me try to give a different explanation for how buffer locking
> is handled which may help clear up what is happening. When a system
> call into a filesystem using buffers locks a buffer it is required
> to release the lock before it returns. When reading a block this
> requirement is easy to fulfill because the thread blcks in the
> kernel while the read is done then wakes up, copies out the data,
> unlocks the buffer, and returns.
Might it be possible that I mixed up the (associated) buffer and struct 
buf? Currently, I'm only interested in the struct buf.

Let me re-phrase to see if I got it right:
 From a system-wide perspective, a particular struct buf (and the buffer 
itself) is secured against concurrent usage by other threads.
The geom thread, however, completes a read request, and modifies the 
struct buf. The buffer itself is also modified but I ignored that for a 
moment. In that particular part of the code (g_vfs_done()), no lock is 
needed since the struct buf is already globally  locked, and no other 
concurrent accesses are possible.
That is what I meant by 'valid exception'. From a textbook perspective, 
one should acquire a lock somewhat before the access, and release it 
afterwards. That is the baseline I'm comparing to.


- Alex
> 
> However when doing a write, the buffer is locked and the data copied
> into it. If the write is delayed (bdwrite) or synchronous (bwrite)
> then the buffer is unlocked and the system call returns. However if
> an asynchronous write is done (bawrite) then then the system call
> wants to return before the write has occurred. Doing so however would
> violate the requirement that the buffer be unlocked. And unlocking the
> buffer would allow other writes to occur on a buffer that was possibly
> being written thus having inconsistent data on the disk. The solution
> is to "pass ownership" to the kernel (using KERNPROC). Thus the system
> call can return as it no longer owns any locked buffers. Instead the
> kernel takes responsibility for unlocking the buffer when the write
> has been completed. Thus the buffer unlock is done by the kernel in
> g_vfs_done() which allows other threads wishing to access the buffer
> to proceed.
> 
> 	Kirk McKusick

-- 
Technische Universität Dortmund
Computer Science XII - System Software Group
Alexander Lochmann                PGP key: 0xBC3EF6FD
Otto-Hahn-Str. 16                 phone:  +49.231.7556141
D-44227 Dortmund                  fax:    +49.231.7556116
https://sys.cs.tu-dortmund.de/al