FreeBSD/sys/kern/vfs_vnops.c
/*
 * Secondary suspension. Used by operations such as vop_inactive
 * routines that are needed by the higher level functions. These
 * are allowed to proceed until all the higher level functions have
 * completed (indicated by mnt_writeopcount dropping to zero). At that
 * time, these operations are halted until the suspension is over.
 */
Secondary suspension. Used by operations such as vop_inactive
routines that are needed by the higher level functions. These
are allowed to proceed until all the higher level functions have
completed (indicated by mnt_writeopcount dropping to zero). At that
time, these operations are halted until the suspension is over.
Secondary suspension . Used by operations such as vop_inactive routines that are needed by the higher level functions . These are allowed to proceed until all the higher level functions have completed ( indicated by mnt_writeopcount dropping to zero ) . At that time these operations are halted until the suspension is over .
int
vn_start_secondary_write(struct vnode *vp, struct mount **mpp, int flags)
{
	struct mount *mp;
	int error;
	KASSERT((flags & V_MNTREF) == 0 || (*mpp != NULL && vp == NULL),
	    ("V_MNTREF requires mp"));
 retry:
	if (vp != NULL) {
		if ((error = VOP_GETWRITEMOUNT(vp, mpp)) != 0) {
			*mpp = NULL;
			if (error != EOPNOTSUPP)
				return (error);
			return (0);
		}
	}
	if ((mp = *mpp) == NULL)
		return (0);
	if (!vn_suspendable(mp)) {
		if (vp != NULL || (flags & V_MNTREF) != 0)
			vfs_rel(mp);
		return (0);
	}
	MNT_ILOCK(mp);
	if (vp == NULL && (flags & V_MNTREF) == 0)
		MNT_REF(mp);
	if ((mp->mnt_kern_flag & (MNTK_SUSPENDED | MNTK_SUSPEND2)) == 0) {
		mp->mnt_secondary_writes++;
		mp->mnt_secondary_accwrites++;
		MNT_IUNLOCK(mp);
		return (0);
	}
	if (flags & V_NOWAIT) {
		MNT_REL(mp);
		MNT_IUNLOCK(mp);
		return (EWOULDBLOCK);
	}
	error = msleep(&mp->mnt_flag, MNT_MTX(mp), (PUSER - 1) | PDROP |
	    ((mp->mnt_vfc->vfc_flags & VFCF_SBDRY) != 0 ? (flags & PCATCH) : 0),
	    "suspfs", 0);
	vfs_rel(mp);
	if (error == 0)
		goto retry;
	return (error);
}
int vn_start_secondary_write ( struct vnode * vp , struct mount * * mpp , int flags ) { struct mount * mp ; int error ; KASSERT ( ( flags & V_MNTREF ) == 0 || ( * mpp != NULL && vp == NULL ) , ( " " ) ) ; retry : if ( vp != NULL ) { if ( ( error = VOP_GETWRITEMOUNT ( vp , mpp ) ) != 0 ) { * mpp = NULL ; if ( error != EOPNOTSUPP ) return ( error ) ; return ( 0 ) ; } } if ( ( mp = * mpp ) == NULL ) return ( 0 ) ; if ( ! vn_suspendable ( mp ) ) { if ( vp != NULL || ( flags & V_MNTREF ) != 0 ) vfs_rel ( mp ) ; return ( 0 ) ; } MNT_ILOCK ( mp ) ; if ( vp == NULL && ( flags & V_MNTREF ) == 0 ) MNT_REF ( mp ) ; if ( ( mp -> mnt_kern_flag & ( MNTK_SUSPENDED | MNTK_SUSPEND2 ) ) == 0 ) { mp -> mnt_secondary_writes ++ ; mp -> mnt_secondary_accwrites ++ ; MNT_IUNLOCK ( mp ) ; return ( 0 ) ; } if ( flags & V_NOWAIT ) { MNT_REL ( mp ) ; MNT_IUNLOCK ( mp ) ; return ( EWOULDBLOCK ) ; } error = msleep ( & mp -> mnt_flag , MNT_MTX ( mp ) , ( PUSER - 1 ) | PDROP | ( ( mp -> mnt_vfc -> vfc_flags & VFCF_SBDRY ) != 0 ? ( flags & PCATCH ) : 0 ) , " " , 0 ) ; vfs_rel ( mp ) ; if ( error == 0 ) goto retry ; return ( error ) ; }
Secondary suspension.
Secondary suspension .
/*
	 * If we are not suspended or have not yet reached suspended
	 * mode, then let the operation proceed.
	 */ /*
	 * VOP_GETWRITEMOUNT() returns with the mp refcount held through
	 * a vfs_ref().
	 * As long as a vnode is not provided we need to acquire a
	 * refcount for the provided mountpoint too, in order to
	 * emulate a vfs_ref().
	 */ /*
	 * Wait for the suspension to finish.
	 */