vfs_hash_insert: ensure that predicate is true

After vnode lock, recheck v_hash. When vfs_hash_insert() is used with
a predicate, recheck it after the selected vnode is locked. Since
vfs_hash_lock is dropped, vnode could be rehashed during the sleep for
the vnode lock, which could go unnoticed there.

Reported and tested by:	pho
Reviewed by:	mckusick, rmacklem
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D31464
This commit is contained in:
Konstantin Belousov 2021-08-17 16:47:25 +03:00
parent 85fb840ebf
commit 7c1e4aab79

View File

@ -93,8 +93,14 @@ vfs_hash_get(const struct mount *mp, u_int hash, int flags, struct thread *td,
error = vget_finish(vp, flags, vs);
if (error == ENOENT && (flags & LK_NOWAIT) == 0)
break;
if (error)
if (error != 0)
return (error);
if (vp->v_hash != hash ||
(fn != NULL && fn(vp, arg))) {
vput(vp);
/* Restart the bucket walk. */
break;
}
*vpp = vp;
return (0);
}