Index: vfs_syscalls.c =================================================================== RCS file: /usr/repo/src/sys/kern/vfs_syscalls.c,v retrieving revision 1.395 diff -u -p -r1.395 vfs_syscalls.c --- vfs_syscalls.c 24 Sep 2005 23:47:04 -0000 1.395 +++ vfs_syscalls.c 11 Dec 2005 03:15:31 -0000 @@ -1626,7 +1626,7 @@ int kern_unlink(struct thread *td, char *path, enum uio_seg pathseg) { struct mount *mp; - struct vnode *vp; + struct vnode *dvp, *vp; int error; struct nameidata nd; int vfslocked; @@ -1638,24 +1638,13 @@ restart: return (error); vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; + dvp = nd.ni_dvp; if (vp->v_type == VDIR) error = EPERM; /* POSIX */ - else { - /* - * The root of a mounted filesystem cannot be deleted. - * - * XXX: can this only be a VDIR case? - */ - if (vp->v_vflag & VV_ROOT) - error = EBUSY; - } if (error == 0) { - if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { + if (vn_start_write(dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); - if (vp == nd.ni_dvp) - vrele(vp); - else - vput(vp); + vput(vp); vput(nd.ni_dvp); VFS_UNLOCK_GIANT(vfslocked); if ((error = vn_start_write(NULL, &mp, @@ -1664,24 +1653,24 @@ restart: goto restart; } #ifdef MAC - error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp, + error = mac_check_vnode_delete(td->td_ucred, dvp, vp, &nd.ni_cnd); if (error) goto out; #endif - VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); - error = VOP_REMOVE(nd.ni_dvp, vp, &nd.ni_cnd); + VOP_LEASE(dvp, td, td->td_ucred, LEASE_WRITE); + error = VOP_REMOVE(dvp, vp, &nd.ni_cnd); #ifdef MAC out: #endif vn_finished_write(mp); } NDFREE(&nd, NDF_ONLY_PNBUF); - if (vp == nd.ni_dvp) + if (vp == dvp) vrele(vp); else vput(vp); - vput(nd.ni_dvp); + vput(dvp); VFS_UNLOCK_GIANT(vfslocked); return (error); } @@ -1860,7 +1849,6 @@ int kern_access(struct thread *td, char *path, enum uio_seg pathseg, int flags) { struct ucred *cred, *tmpcred; - register struct vnode *vp; struct nameidata nd; int vfslocked; int error; @@ -1877,15 +1865,13 @@ kern_access(struct thread *td, char *pat td->td_ucred = tmpcred; NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | MPSAFE, pathseg, path, td); if ((error = namei(&nd)) != 0) - goto out1; + goto out; vfslocked = NDHASGIANT(&nd); - vp = nd.ni_vp; - - error = vn_access(vp, flags, tmpcred, td); + error = vn_access(nd.ni_vp, flags, tmpcred, td); NDFREE(&nd, NDF_ONLY_PNBUF); - vput(vp); + vput(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); -out1: +out: td->td_ucred = cred; crfree(tmpcred); return (error); @@ -1909,7 +1895,6 @@ eaccess(td, uap) } */ *uap; { struct nameidata nd; - struct vnode *vp; int vfslocked; int error; @@ -1917,11 +1902,10 @@ eaccess(td, uap) uap->path, td); if ((error = namei(&nd)) != 0) return (error); - vp = nd.ni_vp; vfslocked = NDHASGIANT(&nd); - error = vn_access(vp, uap->flags, td->td_ucred, td); + error = vn_access(nd.ni_vp, uap->flags, td->td_ucred, td); NDFREE(&nd, NDF_ONLY_PNBUF); - vput(vp); + vput(nd.ni_vp); VFS_UNLOCK_GIANT(vfslocked); return (error); } @@ -3171,7 +3155,7 @@ int kern_rename(struct thread *td, char *from, char *to, enum uio_seg pathseg) { struct mount *mp = NULL; - struct vnode *tvp, *fvp, *tdvp; + struct vnode *fvp, *fdvp, *tvp, *tdvp; struct nameidata fromnd, tond; int tvfslocked; int fvfslocked; @@ -3196,24 +3180,25 @@ kern_rename(struct thread *td, char *fro VOP_UNLOCK(fromnd.ni_vp, 0, td); #endif fvp = fromnd.ni_vp; + fdvp = fromnd.ni_dvp; if (error == 0) error = vn_start_write(fvp, &mp, V_WAIT | PCATCH); if (error != 0) { NDFREE(&fromnd, NDF_ONLY_PNBUF); - vrele(fromnd.ni_dvp); + vrele(fdvp); vrele(fvp); goto out1; } NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | MPSAFE, pathseg, to, td); - if (fromnd.ni_vp->v_type == VDIR) + if (fvp->v_type == VDIR) tond.ni_cnd.cn_flags |= WILLBEDIR; if ((error = namei(&tond)) != 0) { /* Translate error code for rename("dir1", "dir2/."). */ if (error == EISDIR && fvp->v_type == VDIR) error = EINVAL; NDFREE(&fromnd, NDF_ONLY_PNBUF); - vrele(fromnd.ni_dvp); + vrele(fdvp); vrele(fvp); vn_finished_write(mp); goto out1; @@ -3240,20 +3225,18 @@ kern_rename(struct thread *td, char *fro error = -1; #ifdef MAC else - error = mac_check_vnode_rename_to(td->td_ucred, tdvp, - tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); + error = mac_check_vnode_rename_to(td->td_ucred, tdvp, tvp, + fdvp == tdvp, &tond.ni_cnd); #endif out: if (!error) { VOP_LEASE(tdvp, td, td->td_ucred, LEASE_WRITE); - if (fromnd.ni_dvp != tdvp) { - VOP_LEASE(fromnd.ni_dvp, td, td->td_ucred, LEASE_WRITE); - } - if (tvp) { + if (fdvp != tdvp) + VOP_LEASE(fdvp, td, td->td_ucred, LEASE_WRITE); + if (tvp != NULL) VOP_LEASE(tvp, td, td->td_ucred, LEASE_WRITE); - } - error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, - tond.ni_dvp, tond.ni_vp, &tond.ni_cnd); + error = VOP_RENAME(fdvp, fvp, &fromnd.ni_cnd, tdvp, tvp, + &tond.ni_cnd); NDFREE(&fromnd, NDF_ONLY_PNBUF); NDFREE(&tond, NDF_ONLY_PNBUF); } else { @@ -3265,7 +3248,7 @@ out: vrele(tdvp); else vput(tdvp); - vrele(fromnd.ni_dvp); + vrele(fdvp); vrele(fvp); } vrele(tond.ni_startdir); @@ -3390,7 +3373,7 @@ int kern_rmdir(struct thread *td, char *path, enum uio_seg pathseg) { struct mount *mp; - struct vnode *vp; + struct vnode *dvp, *vp; int error; struct nameidata nd; int vfslocked; @@ -3402,6 +3385,7 @@ restart: return (error); vfslocked = NDHASGIANT(&nd); vp = nd.ni_vp; + dvp = nd.ni_dvp; if (vp->v_type != VDIR) { error = ENOTDIR; goto out; @@ -3409,7 +3393,7 @@ restart: /* * No rmdir "." please. */ - if (nd.ni_dvp == vp) { + if (dvp == vp) { error = EINVAL; goto out; } @@ -3421,33 +3405,29 @@ restart: goto out; } #ifdef MAC - error = mac_check_vnode_delete(td->td_ucred, nd.ni_dvp, vp, - &nd.ni_cnd); + error = mac_check_vnode_delete(td->td_ucred, dvp, vp, &nd.ni_cnd); if (error) goto out; #endif - if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { + if (vn_start_write(dvp, &mp, V_NOWAIT) != 0) { NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp == vp) - vrele(nd.ni_dvp); - else - vput(nd.ni_dvp); + vput(dvp); vput(vp); VFS_UNLOCK_GIANT(vfslocked); if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) return (error); goto restart; } - VOP_LEASE(nd.ni_dvp, td, td->td_ucred, LEASE_WRITE); + VOP_LEASE(dvp, td, td->td_ucred, LEASE_WRITE); VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE); - error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd); + error = VOP_RMDIR(dvp, vp, &nd.ni_cnd); vn_finished_write(mp); out: NDFREE(&nd, NDF_ONLY_PNBUF); - if (nd.ni_dvp == vp) - vrele(nd.ni_dvp); + if (dvp == vp) + vrele(dvp); else - vput(nd.ni_dvp); + vput(dvp); vput(vp); VFS_UNLOCK_GIANT(vfslocked); return (error);