FreeBSD/sys/fs/unionfs/union_subr.c
/*
 * relookup
 * 
 * dvp should be locked on entry and will be locked on return.
 * 
 * If an error is returned, *vpp will be invalid, otherwise it will hold a
 * locked, referenced vnode. If *vpp == dvp then remember that only one
 * LK_EXCLUSIVE lock is held.
 */
relookup

dvp should be locked on entry and will be locked on return.

If an error is returned, *vpp will be invalid, otherwise it will hold a
locked, referenced vnode. If *vpp == dvp then remember that only one
LK_EXCLUSIVE lock is held.
relookup dvp should be locked on entry and will be locked on return . If an error is returned * vpp will be invalid otherwise it will hold a locked referenced vnode . If * vpp == dvp then remember that only one LK_EXCLUSIVE lock is held .
int
unionfs_relookup(struct vnode *dvp, struct vnode **vpp,
		 struct componentname *cnp, struct componentname *cn,
		 struct thread *td, char *path, int pathlen, u_long nameiop)
{
	int	error;
	cn->cn_namelen = pathlen;
	cn->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
	bcopy(path, cn->cn_pnbuf, pathlen);
	cn->cn_pnbuf[pathlen] = '\0';
	cn->cn_nameiop = nameiop;
	cn->cn_flags = (LOCKPARENT | LOCKLEAF | HASBUF | SAVENAME | ISLASTCN);
	cn->cn_lkflags = LK_EXCLUSIVE;
	cn->cn_thread = td;
	cn->cn_cred = cnp->cn_cred;
	cn->cn_nameptr = cn->cn_pnbuf;
	if (nameiop == DELETE)
		cn->cn_flags |= (cnp->cn_flags & (DOWHITEOUT | SAVESTART));
	else if (RENAME == nameiop)
		cn->cn_flags |= (cnp->cn_flags & SAVESTART);
	else if (nameiop == CREATE)
		cn->cn_flags |= NOCACHE;
	vref(dvp);
	VOP_UNLOCK(dvp, LK_RELEASE);
	if ((error = relookup(dvp, vpp, cn))) {
		uma_zfree(namei_zone, cn->cn_pnbuf);
		cn->cn_flags &= ~HASBUF;
		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
	} else
		vrele(dvp);
	return (error);
}
int unionfs_relookup ( struct vnode * dvp , struct vnode * * vpp , struct componentname * cnp , struct componentname * cn , struct thread * td , char * path , int pathlen , u_long nameiop ) { int error ; cn -> cn_namelen = pathlen ; cn -> cn_pnbuf = uma_zalloc ( namei_zone , M_WAITOK ) ; bcopy ( path , cn -> cn_pnbuf , pathlen ) ; cn -> cn_pnbuf [ pathlen ] = ' \0 ' ; cn -> cn_nameiop = nameiop ; cn -> cn_flags = ( LOCKPARENT | LOCKLEAF | HASBUF | SAVENAME | ISLASTCN ) ; cn -> cn_lkflags = LK_EXCLUSIVE ; cn -> cn_thread = td ; cn -> cn_cred = cnp -> cn_cred ; cn -> cn_nameptr = cn -> cn_pnbuf ; if ( nameiop == DELETE ) cn -> cn_flags |= ( cnp -> cn_flags & ( DOWHITEOUT | SAVESTART ) ) ; else if ( RENAME == nameiop ) cn -> cn_flags |= ( cnp -> cn_flags & SAVESTART ) ; else if ( nameiop == CREATE ) cn -> cn_flags |= NOCACHE ; vref ( dvp ) ; VOP_UNLOCK ( dvp , LK_RELEASE ) ; if ( ( error = relookup ( dvp , vpp , cn ) ) ) { uma_zfree ( namei_zone , cn -> cn_pnbuf ) ; cn -> cn_flags &= ~ HASBUF ; vn_lock ( dvp , LK_EXCLUSIVE | LK_RETRY ) ; } else vrele ( dvp ) ; return ( error ) ; }
relookup
relookup