]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
VFS sometimes is unable to inactivate a vnode when vnode use count
authorKonstantin Belousov <kib@FreeBSD.org>
Sun, 24 Apr 2011 10:47:56 +0000 (10:47 +0000)
committerKonstantin Belousov <kib@FreeBSD.org>
Sun, 24 Apr 2011 10:47:56 +0000 (10:47 +0000)
commitd9ca1af7edbc99946d519b8a7820e6b38108606a
tree0d608ac56aebd6ed577365a58f9e733bb4b382ab
parent16a174b5c5a93aa079e406241c89c4d7cfc702b4
VFS sometimes is unable to inactivate a vnode when vnode use count
goes to zero. E.g., the vnode might be only shared-locked at the time of
vput() call. Such vnodes are kept in the hash, so they can be found later.

If ffs_valloc() allocated an inode that has its vnode cached in hash, and
still owing the inactivation, then vget() call from ffs_valloc() clears
VI_OWEINACT, and then the vnode is reused for the newly allocated inode.

The problem is, the vnode is not reclaimed before it is put to the new
use. ffs_valloc() recycles vnode vm object, but this is not enough.
In particular, at least v_vflag should be cleared, and several bits of
UFS state need to be removed.

It is very inconvenient to call vgone() at this point. Instead, move
some parts of ufs_reclaim() into helper function ufs_prepare_reclaim(),
and call the helper from VOP_RECLAIM and ffs_valloc().

Reviewed by: mckusick
Tested by: pho
MFC after: 3 weeks
sys/ufs/ffs/ffs_alloc.c
sys/ufs/ufs/ufs_extern.h
sys/ufs/ufs/ufs_inode.c