struct vnode::v_mount access rules

Taylor R Campbell <[email protected]>
Newsgroups gmane.os.netbsd.devel.kernel
Message-ID <[email protected]>
Under what circumstances is access to struct vnode::v_mount allowed?

A vnode may be concurrently revoked at any time.  Part of revoking a
vnode vp, in vcache_reclaim, involves vfs_insmntque to set vp->v_mount
to dead_rootmount.  So there must be some circumstances under which
access to v_mount is forbidden -- those circumstances that can race
with that part of vcache_reclaim.

Holding the vnode lock makes access to vp->v_mount safe, because
vcache_reclaim runs with the exclusive vnode lock held.  But
_acquiring_ the vnode lock first requires reading vp->v_mount inside
VOP_LOCK, before the vnode lock is actually acquired.

Is it safe to read between fd_getvnode and fd_putfile, like here?

int
do_sys_fstatvfs(struct lwp *l, int fd, int flags, struct statvfs *sb)
{
	file_t *fp;
	struct mount *mp;
	int error;

	/* fd_getvnode() will use the descriptor for us */
	if ((error = fd_getvnode(fd, &fp)) != 0)
		return (error);
	mp = fp->f_vnode->v_mount;
	error = dostatvfs(mp, sb, curlwp, flags, 1);
	fd_putfile(fd);
	return error;
}

I think the answer is no, nothing here precludes a concurrent
vcache_reclaim from writing to fp->f_vnode->v_mount at the same time
do_sys_fstatvfs is reading from it.  Although both the before and
after states are OK for dostatvfs, if this concurrent read/write is
supposed to be allowed, it should be done with atomic_load/store_* --
and the same needs to apply to all other use of v_mount that isn't,
e.g., serialized by the vnode lock.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.