buffer cache can return buffer of another inode ?

Hi,
while investigating directory corruption on my NFS server I found
a possible issue with the buffer cache.
The buffer cache keeps a hash of buf_t, the key being (vp, bp->b_lblkno).
This allows, for a read or write, to find if a buffer for this block
has already been allocated and if data is already in code (eventually).
buffers in this hash should also be in one of the vnode's buffer list,
and the vnode should be on the hold list (so it gets recycled after
vnodes with no buffer).
Now if vnode_free_list is empty, getcleanvnode() will remove one from
vnode_hold_list and vclean() it. vclean() will flush and release buffers
from the vnode lists, but won't remove the buffer from the (vp, bp->b_lblkno)
hash. This clean vnode will get associated with a new inode and
if the I/O started on it has the same lblkno, the buffer will be
found in the hash, eventually providing data from the previous inode,
or writing to the previous inode. This is very rare, because
vnode from the hold list are not reused often and there is usually
less buffers than vnodes in the system (so a buffer is likely recycled
before a vnode is). Also, VREG vnode usually don't use the buffer cache.
I think vclean() should also take care of removing the vnode from
the buffer cache's hash. Comments ?
--
Manuel Bouyer <bouyer%antioche.eu.org@localhost>
NetBSD: 26 ans d'experience feront toujours la difference
--