FreeBSD/sys/fs/unionfs/union_subr.c
/*
 * Copy file from lower to upper.
 * 
 * If you need copy of the contents, set 1 to docopy. Otherwise, set 0 to
 * docopy.
 * 
 * If no error returned, unp will be updated.
 */
Copy file from lower to upper.

If you need copy of the contents, set 1 to docopy. Otherwise, set 0 to
docopy.

If no error returned, unp will be updated.
Copy file from lower to upper . If you need copy of the contents set 1 to docopy . Otherwise set 0 to docopy . If no error returned unp will be updated .
int
unionfs_copyfile(struct unionfs_node *unp, int docopy, struct ucred *cred,
		 struct thread *td)
{
	int		error;
	struct mount   *mp;
	struct vnode   *udvp;
	struct vnode   *lvp;
	struct vnode   *uvp;
	struct vattr	uva;
	lvp = unp->un_lowervp;
	uvp = NULLVP;
	if ((UNIONFSTOV(unp)->v_mount->mnt_flag & MNT_RDONLY))
		return (EROFS);
	if (unp->un_dvp == NULLVP)
		return (EINVAL);
	if (unp->un_uppervp != NULLVP)
		return (EEXIST);
	udvp = VTOUNIONFS(unp->un_dvp)->un_uppervp;
	if (udvp == NULLVP)
		return (EROFS);
	if ((udvp->v_mount->mnt_flag & MNT_RDONLY))
		return (EROFS);
	error = VOP_ACCESS(lvp, VREAD, cred, td);
	if (error != 0)
		return (error);
	if ((error = vn_start_write(udvp, &mp, V_WAIT | PCATCH)) != 0)
		return (error);
	error = unionfs_vn_create_on_upper(&uvp, udvp, unp, &uva, td);
	if (error != 0) {
		vn_finished_write(mp);
		return (error);
	}
	if (docopy != 0) {
		error = VOP_OPEN(lvp, FREAD, cred, td, NULL);
		if (error == 0) {
			error = unionfs_copyfile_core(lvp, uvp, cred, td);
			VOP_CLOSE(lvp, FREAD, cred, td);
		}
	}
	VOP_CLOSE(uvp, FWRITE, cred, td);
	VOP_ADD_WRITECOUNT(uvp, -1);
	CTR3(KTR_VFS, "%s: vp %p v_writecount decreased to %d", __func__, uvp,
	    uvp->v_writecount);
	vn_finished_write(mp);
	if (error == 0) {
		uva.va_type = VNON;
		VOP_SETATTR(uvp, &uva, cred);
	}
	unionfs_node_update(unp, uvp, td);
	return (error);
}
int unionfs_copyfile ( struct unionfs_node * unp , int docopy , struct ucred * cred , struct thread * td ) { int error ; struct mount * mp ; struct vnode * udvp ; struct vnode * lvp ; struct vnode * uvp ; struct vattr uva ; lvp = unp -> un_lowervp ; uvp = NULLVP ; if ( ( UNIONFSTOV ( unp ) -> v_mount -> mnt_flag & MNT_RDONLY ) ) return ( EROFS ) ; if ( unp -> un_dvp == NULLVP ) return ( EINVAL ) ; if ( unp -> un_uppervp != NULLVP ) return ( EEXIST ) ; udvp = VTOUNIONFS ( unp -> un_dvp ) -> un_uppervp ; if ( udvp == NULLVP ) return ( EROFS ) ; if ( ( udvp -> v_mount -> mnt_flag & MNT_RDONLY ) ) return ( EROFS ) ; error = VOP_ACCESS ( lvp , VREAD , cred , td ) ; if ( error != 0 ) return ( error ) ; if ( ( error = vn_start_write ( udvp , & mp , V_WAIT | PCATCH ) ) != 0 ) return ( error ) ; error = unionfs_vn_create_on_upper ( & uvp , udvp , unp , & uva , td ) ; if ( error != 0 ) { vn_finished_write ( mp ) ; return ( error ) ; } if ( docopy != 0 ) { error = VOP_OPEN ( lvp , FREAD , cred , td , NULL ) ; if ( error == 0 ) { error = unionfs_copyfile_core ( lvp , uvp , cred , td ) ; VOP_CLOSE ( lvp , FREAD , cred , td ) ; } } VOP_CLOSE ( uvp , FWRITE , cred , td ) ; VOP_ADD_WRITECOUNT ( uvp , -1 ) ; CTR3 ( KTR_VFS , " " , __func__ , uvp , uvp -> v_writecount ) ; vn_finished_write ( mp ) ; if ( error == 0 ) { uva . va_type = VNON ; VOP_SETATTR ( uvp , & uva , cred ) ; } unionfs_node_update ( unp , uvp , td ) ; return ( error ) ; }
Copy file from lower to upper.
Copy file from lower to upper .
/* Reset the attributes. Ignore errors. */