X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..8f6c56a50524aa785f7e596d52dddfb331e18961:/bsd/miscfs/union/union_subr.c diff --git a/bsd/miscfs/union/union_subr.c b/bsd/miscfs/union/union_subr.c index 85c41ad1e..80b3a0386 100644 --- a/bsd/miscfs/union/union_subr.c +++ b/bsd/miscfs/union/union_subr.c @@ -1,16 +1,19 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER @@ -20,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ /* @@ -64,18 +67,20 @@ #include #include -#include +#include +#include #include #include -#include +#include #include #include #include #include #include -#include +#include #include #include +#include #include #if DIAGNOSTIC @@ -140,7 +145,7 @@ union_updatevp(un, uppervp, lowervp) int ohash = UNION_HASH(un->un_uppervp, un->un_lowervp); int nhash = UNION_HASH(uppervp, lowervp); int docache = (lowervp != NULLVP || uppervp != NULLVP); - int lhash, hhash, uhash; + int lhash, uhash; /* * Ensure locking is ordered from lower to higher @@ -173,13 +178,13 @@ union_updatevp(un, uppervp, lowervp) if (un->un_lowervp != lowervp) { if (un->un_lowervp) { - vrele(un->un_lowervp); + vnode_put(un->un_lowervp); if (un->un_path) { _FREE(un->un_path, M_TEMP); un->un_path = 0; } if (un->un_dirvp) { - vrele(un->un_dirvp); + vnode_put(un->un_dirvp); un->un_dirvp = NULLVP; } } @@ -189,7 +194,7 @@ union_updatevp(un, uppervp, lowervp) if (un->un_uppervp != uppervp) { if (un->un_uppervp) - vrele(un->un_uppervp); + vnode_put(un->un_uppervp); un->un_uppervp = uppervp; un->un_uppersz = VNOVAL; @@ -258,8 +263,7 @@ union_newsize(vp, uppersz, lowersz) printf("union: %s size now %ld\n", uppersz != VNOVAL ? "upper" : "lower", (long) sz); #endif - if (UBCISVALID(vp)) - ubc_setsize(vp, sz); /* XXX check error */ + ubc_setsize(vp, sz); } } @@ -275,7 +279,7 @@ union_newsize(vp, uppersz, lowersz) * being mapped. either, but not both, can be nil. * if supplied, (uppervp) is locked. * the reference is either maintained in the new union_node - * object which is allocated, or they are vrele'd. + * object which is allocated, or they are vnode_put'd. * * all union_nodes are maintained on a singly-linked * list. new nodes are only allocated when they cannot @@ -289,7 +293,7 @@ union_newsize(vp, uppersz, lowersz) * vnode. this lock is only taken if we are going to * call getnewvnode, since the kernel itself is single-threaded. * - * if an entry is found on the list, then call vget() to + * if an entry is found on the list, then call vnode_get() to * take a reference. this is done because there may be * zero references to it and so it needs to removed from * the vnode free list. @@ -311,9 +315,11 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp, docache) struct vnode *xlowervp = NULLVP; struct union_mount *um = MOUNTTOUNIONMOUNT(mp); int hash; - int vflag; + int markroot; int try; struct union_node *unp; + struct vnode_fsparam vfsp; + enum vtype vtype; if (uppervp == NULLVP && lowervp == NULLVP) panic("union: unidentifiable allocation"); @@ -324,15 +330,15 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp, docache) } /* detect the root vnode (and aliases) */ - vflag = 0; + markroot = 0; if ((uppervp == um->um_uppervp) && ((lowervp == NULLVP) || lowervp == um->um_lowervp)) { if (lowervp == NULLVP) { lowervp = um->um_lowervp; if (lowervp != NULLVP) - VREF(lowervp); + vnode_get(lowervp); } - vflag = VROOT; + markroot = VROOT; } loop: @@ -369,8 +375,7 @@ loop: (un->un_uppervp == uppervp || un->un_uppervp == NULLVP) && (UNIONTOV(un)->v_mount == mp)) { - if (vget(UNIONTOV(un), 0, - cnp ? cnp->cn_proc : NULL)) { + if (vnode_get(UNIONTOV(un))) { union_list_unlock(hash); goto loop; } @@ -390,7 +395,7 @@ loop: * uppervp is locked, though un->un_uppervp * may not be. this doesn't break the locking * hierarchy since in the case that un->un_uppervp - * is not yet locked it will be vrele'd and replaced + * is not yet locked it will be vnode_put'd and replaced * with uppervp. */ @@ -410,7 +415,7 @@ loop: #endif } else { if (un->un_flags & UN_LOCKED) { - vrele(UNIONTOV(un)); + vnode_put(UNIONTOV(un)); un->un_flags |= UN_WANT; sleep((caddr_t) &un->un_flags, PINOD); goto loop; @@ -437,7 +442,7 @@ loop: if (uppervp != un->un_uppervp) { union_newupper(un, uppervp); } else if (uppervp) { - vrele(uppervp); + vnode_put(uppervp); } if (un->un_uppervp) { @@ -460,11 +465,11 @@ loop: bcopy(cnp->cn_nameptr, un->un_path, cnp->cn_namelen); un->un_path[cnp->cn_namelen] = '\0'; - VREF(dvp); + vnode_get(dvp); un->un_dirvp = dvp; } } else if (lowervp) { - vrele(lowervp); + vnode_put(lowervp); } *vpp = UNIONTOV(un); return (0); @@ -482,31 +487,38 @@ loop: } MALLOC(unp, void *, sizeof(struct union_node), M_TEMP, M_WAITOK); - error = getnewvnode(VT_UNION, mp, union_vnodeop_p, vpp); + + if (uppervp) + vtype = uppervp->v_type; + else + vtype = lowervp->v_type; + //bzero(&vfsp, sizeof(struct vnode_fsparam)); + vfsp.vnfs_mp = mp; + vfsp.vnfs_vtype = vtype; + vfsp.vnfs_str = "unionfs"; + vfsp.vnfs_dvp = dvp; + vfsp.vnfs_fsnode = unp; + vfsp.vnfs_cnp = cnp; + vfsp.vnfs_vops = union_vnodeop_p; + vfsp.vnfs_rdev = 0; + vfsp.vnfs_filesize = 0; + vfsp.vnfs_flags = VNFS_NOCACHE | VNFS_CANTCACHE; + vfsp.vnfs_marksystem = 0; + vfsp.vnfs_markroot = markroot; + + error = vnode_create(VNCREATE_FLAVOR, VCREATESIZE, &vfsp, vpp); if (error) { FREE(unp, M_TEMP); if (uppervp) { - if (dvp == uppervp) - vrele(uppervp); - else - vput(uppervp); + vnode_put(uppervp); } if (lowervp) - vrele(lowervp); + vnode_put(lowervp); goto out; } - (*vpp)->v_data = unp; - (*vpp)->v_flag |= vflag; - if (uppervp) - (*vpp)->v_type = uppervp->v_type; - else - (*vpp)->v_type = lowervp->v_type; - - if ((*vpp)->v_type == VREG) - ubc_info_init(*vpp); - + (*vpp)->v_tag = VT_UNION; un = VTOUNION(*vpp); un->un_vnode = *vpp; un->un_uppervp = uppervp; @@ -515,7 +527,7 @@ loop: un->un_lowersz = VNOVAL; un->un_pvp = undvp; if (undvp != NULLVP) - VREF(undvp); + vnode_get(undvp); un->un_dircache = 0; un->un_openl = 0; un->un_flags = UN_LOCKED; @@ -532,7 +544,7 @@ loop: un->un_path = _MALLOC(cnp->cn_namelen+1, M_TEMP, M_WAITOK); bcopy(cnp->cn_nameptr, un->un_path, cnp->cn_namelen); un->un_path[cnp->cn_namelen] = '\0'; - VREF(dvp); + vnode_get(dvp); un->un_dirvp = dvp; } else { un->un_hash = 0; @@ -546,7 +558,7 @@ loop: } if (xlowervp) - vrele(xlowervp); + vnode_put(xlowervp); out: if (docache) @@ -567,13 +579,13 @@ union_freevp(vp) } if (un->un_pvp != NULLVP) - vrele(un->un_pvp); + vnode_put(un->un_pvp); if (un->un_uppervp != NULLVP) - vrele(un->un_uppervp); + vnode_put(un->un_uppervp); if (un->un_lowervp != NULLVP) - vrele(un->un_lowervp); + vnode_put(un->un_lowervp); if (un->un_dirvp != NULLVP) - vrele(un->un_dirvp); + vnode_put(un->un_dirvp); if (un->un_path) _FREE(un->un_path, M_TEMP); @@ -589,15 +601,13 @@ union_freevp(vp) * and (tvp) are locked on entry and exit. */ int -union_copyfile(fvp, tvp, cred, p) - struct vnode *fvp; - struct vnode *tvp; - struct ucred *cred; - struct proc *p; +union_copyfile(struct vnode *fvp, struct vnode *tvp, kauth_cred_t cred, + struct proc *p) { - char *buf; + char *bufp; struct uio uio; - struct iovec iov; + struct iovec_32 iov; + struct vfs_context context; int error = 0; /* @@ -608,51 +618,50 @@ union_copyfile(fvp, tvp, cred, p) * give up at the first sign of trouble. */ - uio.uio_procp = p; + context.vc_proc = p; + context.vc_ucred = cred; + +#if 1 /* LP64todo - can't use new segment flags until the drivers are ready */ uio.uio_segflg = UIO_SYSSPACE; +#else + uio.uio_segflg = UIO_SYSSPACE32; +#endif uio.uio_offset = 0; - VOP_UNLOCK(fvp, 0, p); /* XXX */ - VOP_LEASE(fvp, p, cred, LEASE_READ); - vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, p); /* XXX */ - VOP_UNLOCK(tvp, 0, p); /* XXX */ - VOP_LEASE(tvp, p, cred, LEASE_WRITE); - vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY, p); /* XXX */ - - buf = _MALLOC(MAXPHYSIO, M_TEMP, M_WAITOK); + bufp = _MALLOC(MAXPHYSIO, M_TEMP, M_WAITOK); /* ugly loop follows... */ do { off_t offset = uio.uio_offset; - uio.uio_iov = &iov; + uio.uio_iovs.iov32p = &iov; uio.uio_iovcnt = 1; - iov.iov_base = buf; + iov.iov_base = (uintptr_t)bufp; iov.iov_len = MAXPHYSIO; - uio.uio_resid = iov.iov_len; + uio_setresid(&uio, iov.iov_len); uio.uio_rw = UIO_READ; - error = VOP_READ(fvp, &uio, 0, cred); + error = VNOP_READ(fvp, &uio, 0, &context); if (error == 0) { - uio.uio_iov = &iov; + uio.uio_iovs.iov32p = &iov; uio.uio_iovcnt = 1; - iov.iov_base = buf; - iov.iov_len = MAXPHYSIO - uio.uio_resid; + iov.iov_base = (uintptr_t)bufp; + iov.iov_len = MAXPHYSIO - uio_resid(&uio); uio.uio_offset = offset; uio.uio_rw = UIO_WRITE; - uio.uio_resid = iov.iov_len; + uio_setresid(&uio, iov.iov_len); - if (uio.uio_resid == 0) + if (uio_resid(&uio) == 0) break; do { - error = VOP_WRITE(tvp, &uio, 0, cred); - } while ((uio.uio_resid > 0) && (error == 0)); + error = VNOP_WRITE(tvp, &uio, 0, &context); + } while ((uio_resid(&uio) > 0) && (error == 0)); } } while (error == 0); - _FREE(buf, M_TEMP); + _FREE(bufp, M_TEMP); return (error); } @@ -661,19 +670,20 @@ union_copyfile(fvp, tvp, cred, p) * locked on exit. */ int -union_copyup(un, docopy, cred, p) - struct union_node *un; - int docopy; - struct ucred *cred; - struct proc *p; +union_copyup(struct union_node *un, int docopy, kauth_cred_t cred, + struct proc *p) { int error; struct vnode *lvp, *uvp; + struct vfs_context context; error = union_vn_create(&uvp, un, p); if (error) return (error); + context.vc_proc = p; + context.vc_ucred = cred; + /* at this point, uppervp is locked */ union_newupper(un, uvp); un->un_flags |= UN_ULOCK; @@ -683,14 +693,12 @@ union_copyup(un, docopy, cred, p) if (docopy) { /* * XX - should not ignore errors - * from VOP_CLOSE + * from vnop_close */ - vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY, p); - error = VOP_OPEN(lvp, FREAD, cred, p); + error = VNOP_OPEN(lvp, FREAD, &context); if (error == 0) { error = union_copyfile(lvp, uvp, cred, p); - VOP_UNLOCK(lvp, 0, p); - (void) VOP_CLOSE(lvp, FREAD, cred, p); + (void) VNOP_CLOSE(lvp, FREAD, &context); } #ifdef UNION_DIAGNOSTIC if (error == 0) @@ -699,9 +707,7 @@ union_copyup(un, docopy, cred, p) } un->un_flags &= ~UN_ULOCK; - VOP_UNLOCK(uvp, 0, p); union_vn_close(uvp, FWRITE, cred, p); - vn_lock(uvp, LK_EXCLUSIVE | LK_RETRY, p); un->un_flags |= UN_ULOCK; /* @@ -716,8 +722,8 @@ union_copyup(un, docopy, cred, p) int i; for (i = 0; i < un->un_openl; i++) { - (void) VOP_CLOSE(lvp, FREAD, cred, p); - (void) VOP_OPEN(uvp, FREAD, cred, p); + (void) VNOP_CLOSE(lvp, FREAD, &context); + (void) VNOP_OPEN(uvp, FREAD, &context); } un->un_openl = 0; } @@ -744,10 +750,8 @@ union_relookup(um, dvp, vpp, cnp, cn, path, pathlen) * from or what it is being used for. This must duplicate * some of the work done by NDINIT, some of the work done * by namei, some of the work done by lookup and some of - * the work done by VOP_LOOKUP when given a CREATE flag. + * the work done by vnop_lookup when given a CREATE flag. * Conclusion: Horrible. - * - * The pathname buffer will be FREEed by VOP_MKDIR. */ cn->cn_namelen = pathlen; cn->cn_pnbuf = _MALLOC_ZONE(cn->cn_namelen+1, M_NAMEI, M_WAITOK); @@ -757,19 +761,22 @@ union_relookup(um, dvp, vpp, cnp, cn, path, pathlen) cn->cn_nameiop = CREATE; cn->cn_flags = (LOCKPARENT|HASBUF|SAVENAME|SAVESTART|ISLASTCN); +#ifdef XXX_HELP_ME cn->cn_proc = cnp->cn_proc; if (um->um_op == UNMNT_ABOVE) cn->cn_cred = cnp->cn_cred; else cn->cn_cred = um->um_cred; +#endif + cn->cn_context = cnp->cn_context; /* XXX !UNMNT_ABOVE case ??? */ cn->cn_nameptr = cn->cn_pnbuf; cn->cn_hash = cnp->cn_hash; cn->cn_consume = cnp->cn_consume; - VREF(dvp); + vnode_get(dvp); error = relookup(dvp, vpp, cn); if (!error) - vrele(dvp); + vnode_put(dvp); return (error); } @@ -794,8 +801,7 @@ union_mkshadow(um, dvp, cnp, vpp) struct vnode **vpp; { int error; - struct vattr va; - struct proc *p = cnp->cn_proc; + struct vnode_attr va; struct componentname cn; error = union_relookup(um, dvp, vpp, cnp, &cn, @@ -804,9 +810,7 @@ union_mkshadow(um, dvp, cnp, vpp) return (error); if (*vpp) { - VOP_ABORTOP(dvp, &cn); - VOP_UNLOCK(dvp, 0, p); - vrele(*vpp); + vnode_put(*vpp); *vpp = NULLVP; return (EEXIST); } @@ -818,15 +822,11 @@ union_mkshadow(um, dvp, cnp, vpp) * 777 modified by umask (ie mostly identical to the * mkdir syscall). (jsp, kb) */ + VATTR_INIT(&va); + VATTR_SET(&va, va_type, VDIR); + VATTR_SET(&va, va_mode, um->um_cmode); - VATTR_NULL(&va); - va.va_type = VDIR; - va.va_mode = um->um_cmode; - - /* VOP_LEASE: dvp is locked */ - VOP_LEASE(dvp, p, cn.cn_cred, LEASE_WRITE); - - error = VOP_MKDIR(dvp, vpp, &cn, &va); + error = vn_create(dvp, vpp, &cn, &va, 0, cnp->cn_context); return (error); } @@ -847,33 +847,22 @@ union_mkwhiteout(um, dvp, cnp, path) char *path; { int error; - struct vattr va; - struct proc *p = cnp->cn_proc; struct vnode *wvp; struct componentname cn; - VOP_UNLOCK(dvp, 0, p); error = union_relookup(um, dvp, &wvp, cnp, &cn, path, strlen(path)); if (error) { - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p); return (error); } - if (wvp) { - VOP_ABORTOP(dvp, &cn); - vrele(dvp); - vrele(wvp); + vnode_put(dvp); + vnode_put(wvp); return (EEXIST); } - /* VOP_LEASE: dvp is locked */ - VOP_LEASE(dvp, p, p->p_ucred, LEASE_WRITE); - - error = VOP_WHITEOUT(dvp, &cn, CREATE); - if (error) - VOP_ABORTOP(dvp, &cn); + error = VNOP_WHITEOUT(dvp, &cn, CREATE, cnp->cn_context); - vrele(dvp); + vnode_put(dvp); return (error); } @@ -893,9 +882,10 @@ union_vn_create(vpp, un, p) struct proc *p; { struct vnode *vp; - struct ucred *cred = p->p_ucred; - struct vattr vat; - struct vattr *vap = &vat; + kauth_cred_t cred = p->p_ucred; + struct vnode_attr vat; + struct vnode_attr *vap = &vat; + struct vfs_context context; int fmode = FFLAGS(O_WRONLY|O_CREAT|O_TRUNC|O_EXCL); int error; int cmode = UN_FILEMODE & ~p->p_fd->fd_cmask; @@ -904,6 +894,9 @@ union_vn_create(vpp, un, p) *vpp = NULLVP; + context.vc_proc = p; + context.vc_ucred = p->p_ucred; + /* * Build a new componentname structure (for the same * reasons outlines in union_mkshadow). @@ -920,24 +913,19 @@ union_vn_create(vpp, un, p) bcopy(un->un_path, cn.cn_pnbuf, cn.cn_namelen+1); cn.cn_nameiop = CREATE; cn.cn_flags = (LOCKPARENT|HASBUF|SAVENAME|SAVESTART|ISLASTCN); - cn.cn_proc = p; - cn.cn_cred = p->p_ucred; + cn.cn_context = &context; cn.cn_nameptr = cn.cn_pnbuf; cn.cn_hash = un->un_hash; cn.cn_consume = 0; - VREF(un->un_dirvp); + vnode_get(un->un_dirvp); if (error = relookup(un->un_dirvp, &vp, &cn)) return (error); - vrele(un->un_dirvp); + vnode_put(un->un_dirvp); if (vp) { - VOP_ABORTOP(un->un_dirvp, &cn); - if (un->un_dirvp == vp) - vrele(un->un_dirvp); - else - vput(un->un_dirvp); - vrele(vp); + vnode_put(un->un_dirvp); + vnode_put(vp); return (EEXIST); } @@ -949,37 +937,46 @@ union_vn_create(vpp, un, p) * it is unioned, will require access to the top *and* * bottom files. Access when not unioned will simply * require access to the top-level file. + * * TODO: confirm choice of access permissions. + * decide on authorisation behaviour */ - VATTR_NULL(vap); - vap->va_type = VREG; - vap->va_mode = cmode; - VOP_LEASE(un->un_dirvp, p, cred, LEASE_WRITE); - if (error = VOP_CREATE(un->un_dirvp, &vp, &cn, vap)) + + VATTR_INIT(vap); + VATTR_SET(vap, va_type, VREG); + VATTR_SET(vap, va_mode, cmode); + + if (error = vn_create(un->un_dirvp, &vp, &cn, vap, 0, &context)) return (error); - if (error = VOP_OPEN(vp, fmode, cred, p)) { - vput(vp); + if (error = VNOP_OPEN(vp, fmode, &context)) { + vnode_put(vp); return (error); } + vnode_lock(vp); if (++vp->v_writecount <= 0) panic("union: v_writecount"); + vnode_unlock(vp); *vpp = vp; return (0); } int -union_vn_close(vp, fmode, cred, p) - struct vnode *vp; - int fmode; - struct ucred *cred; - struct proc *p; +union_vn_close(struct vnode *vp, int fmode, kauth_cred_t cred, + struct proc *p) { + struct vfs_context context; - if (fmode & FWRITE) + context.vc_proc = p; + context.vc_ucred = cred; + + if (fmode & FWRITE) { + vnode_lock(vp); --vp->v_writecount; - return (VOP_CLOSE(vp, fmode, cred, p)); + vnode_unlock(vp); + } + return (VNOP_CLOSE(vp, fmode, &context)); } void @@ -996,7 +993,6 @@ union_removed_upper(un) if (un->un_flags & UN_ULOCK) { un->un_flags &= ~UN_ULOCK; - VOP_UNLOCK(un->un_uppervp, 0, p); } } @@ -1009,7 +1005,7 @@ union_lowervp(vp) if ((un->un_lowervp != NULLVP) && (vp->v_type == un->un_lowervp->v_type)) { - if (vget(un->un_lowervp, 0, current_proc()) == 0) + if (vnode_get(un->un_lowervp) == 0) return (un->un_lowervp); } @@ -1022,17 +1018,16 @@ union_lowervp(vp) * during a remove/rmdir operation. */ int -union_dowhiteout(un, cred, p) - struct union_node *un; - struct ucred *cred; - struct proc *p; +union_dowhiteout(struct union_node *un, vfs_context_t ctx) { - struct vattr va; + struct vnode_attr va; if (un->un_lowervp != NULLVP) return (1); - if (VOP_GETATTR(un->un_uppervp, &va, cred, p) == 0 && + VATTR_INIT(&va); + VATTR_WANTED(&va, va_flags); + if (vnode_getattr(un->un_uppervp, &va, ctx) == 0 && (va.va_flags & OPAQUE)) return (1); @@ -1049,7 +1044,7 @@ union_dircache_r(vp, vppp, cntp) if (vp->v_op != union_vnodeop_p) { if (vppp) { - VREF(vp); + vnode_get(vp); *(*vppp)++ = vp; if (--(*cntp) == 0) panic("union: dircache table too small"); @@ -1072,27 +1067,26 @@ union_dircache(vp, p) struct vnode *vp; struct proc *p; { - int cnt; + int count; struct vnode *nvp; struct vnode **vpp; struct vnode **dircache; struct union_node *un; int error; - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); dircache = VTOUNION(vp)->un_dircache; nvp = NULLVP; if (dircache == 0) { - cnt = 0; - union_dircache_r(vp, 0, &cnt); - cnt++; + count = 0; + union_dircache_r(vp, 0, &count); + count++; dircache = (struct vnode **) - _MALLOC(cnt * sizeof(struct vnode *), + _MALLOC(count * sizeof(struct vnode *), M_TEMP, M_WAITOK); vpp = dircache; - union_dircache_r(vp, &vpp, &cnt); + union_dircache_r(vp, &vpp, &count); *vpp = NULLVP; vpp = dircache + 1; } else { @@ -1106,8 +1100,7 @@ union_dircache(vp, p) if (*vpp == NULLVP) goto out; - vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, p); - VREF(*vpp); + vnode_get(*vpp); error = union_allocvp(&nvp, vp->v_mount, NULLVP, NULLVP, 0, *vpp, NULLVP, 0); if (error) goto out; @@ -1117,6 +1110,5 @@ union_dircache(vp, p) un->un_dircache = dircache; out: - VOP_UNLOCK(vp, 0, p); return (nvp); }