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 <[email protected]> NetBSD: 26 ans d'experience feront toujours la difference --
