Index: VOP_RENAME.9 =================================================================== --- VOP_RENAME.9 (revision 190481) +++ VOP_RENAME.9 (working copy) @@ -72,205 +72,6 @@ .Xr vput 9 both prior to returning. -.Sh PSEUDOCODE -.Bd -literal -int -vop_rename(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp, - struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp) -{ - int doingdirectory = 0; - int error = 0; - - /* - * Check for cross-device rename. - */ - if (fvp->v_mount != tdvp->v_mount) { - error = EXDEV; - abortit: - if (tdvp == tvp) - vrele(tdvp); - else - vput(tdvp); - if (tvp) - vput(tvp); - vrele(fdvp); - vrele(fvp); - return error; - } - - if (tvp exists and is immutable) { - error = EPERM; - goto abortit; - } - - /* - * POSIX: "If the old argument and the new argument - * both refer to links to the same existing file, - * the rename() function shall return successfully - * and perform no other action." - * The upper layers already handle this case. - */ - KASSERT(fvp != tvp, ("vop_rename: source and destination are the same")); - - if (fvp is immutable) { - error = EPERM; - goto abortit; - } - - error = VOP_LOCK(fvp); - if (error) - goto abortit; - - if (vp is a directory) { - /* - * Avoid ".", "..", and aliases of "." for obvious reasons. - */ - if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') - || fdvp == fvp - || ((fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT)) { - VOP_UNLOCK(fvp); - error = EINVAL; - goto abortit; - } - doingdirectory = 1; - } - vrele(fdvp); - - /* - * Bump link count on fvp while we are moving stuff around. If we - * crash before completing the work, the link count may be wrong - * but correctable. - */ - ...; - - /* - * If ".." must be changed (ie the directory gets a new - * parent) then the source directory must not be in the - * directory hierarchy above the target, as this would - * orphan everything below the source directory. Also - * the user must have write permission in the source so - * as to be able to change "..". - */ - error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_thread); - VOP_UNLOCK(fvp); - if (doingdirectory && fdvp != tdvp) { - /* - * Check for pathname conflict. - */ - ...; - } - - /* - * If the target doesn't exist, link the target to the source and - * unlink the source. Otherwise, rewrite the target directory to - * reference the source and remove the original entry. - */ - if (tvp == NULL) { - /* - * Account for ".." in new directory. - */ - if (doingdirectory && fdvp != tdvp) { - /* - * Increase link count of tdvp. - */ - ...; - } - - /* - * Add name in new directory. - */ - ...; - - if (error) { - if (doingdirectory && fdvp != tdvp) { - /* - * Decrease link count if tdvp. - */ - ...; - } - goto bad; - } - vput(tdvp); - } else { - /* - * Target must be empty if a directory and have no links - * to it. Also, ensure source and target are compatible - * (both directories, or both not directories). - */ - if (tvp is a directory) { - if (tvp is not empty) { - error = ENOTEMPTY; - goto bad; - } - if (!doingdirectory) { - error = ENOTDIR; - goto bad; - } - /* - * Update name cache since directory is going away. - */ - cache_purge(tdvp); - } else if (doingdirectory) { - error = ENOTDIR; - goto bad; - } - - /* - * Change name tcnp in tdvp to point at fvp. - */ - ...; - - /* - * If the target directory is in same directory as the source - * directory, decrement the link count on the parent of the - * target directory. This accounts for the fact that a - * directory links back to its parent with "..". - */ - if (doingdirectory && fdvp == tdvp) { - /* - * Decrement link count of tdvp. - */ - ...; - } - vput(tdvp); - - /* - * Decrement the link count of tvp since the directory no - * longer points at it. - */ - ...; - if (doingdirectory) { - /* - * Clean up the old directory tvp. - */ - ...; - } - vput(tvp); - } - - /* - * Unlink the source. If a directory was moved to a new parent, - * update its ".." entry. Gobs of ugly UFS code omitted here. - */ - ...; - -bad: - if (tvp) - vput(tvp); - vput(tdvp); -out: - if (VOP_LOCK(fvp) == 0) { - /* - * Decrement link count of fvp. - */ - ...; - vput(fvp); - } else - vrele(fvp); - - return error; -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er EPERM Index: VOP_RDWR.9 =================================================================== --- VOP_RDWR.9 (revision 190481) +++ VOP_RDWR.9 (working copy) @@ -85,141 +85,6 @@ The file should be locked on entry and will still be locked on exit. .Sh RETURN VALUES Zero is returned on success, otherwise an error code is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_read(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) -{ - struct buf *bp; - off_t bytesinfile; - daddr_t lbn, nextlbn; - long size, xfersize, blkoffset; - int error; - - size = block size of file system; - - for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) { - bytesinfile = size of file - uio->uio_offset; - if (bytesinfile <= 0) - break; - - lbn = uio->uio_offset / size; - blkoffset = uio->uio_offset - lbn * size; - - xfersize = size - blkoffset; - if (uio->uio_resid < xfersize) - xfersize = uio->uio_resid; - if (bytesinfile < xfersize) - xfersize = bytesinfile; - - error = bread(vp, lbn, size, NOCRED, &bp); - if (error) { - brelse(bp); - bp = NULL; - break; - } - - /* - * We should only get non-zero b_resid when an I/O error - * has occurred, which should cause us to break above. - * However, if the short read did not cause an error, - * then we want to ensure that we do not uiomove bad - * or uninitialized data. - */ - size -= bp->b_resid; - if (size < xfersize) { - if (size == 0) - break; - xfersize = size; - } - - error = uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio); - if (error) - break; - - bqrelse(bp); - } - if (bp != NULL) - bqrelse(bp); - - return (error); -} - -int -vop_write(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred) -{ - struct buf *bp; - off_t bytesinfile; - daddr_t lbn, nextlbn; - off_t osize; - long size, resid, xfersize, blkoffset; - int flags; - int error; - - osize = size of file; - size = block size of file system; - resid = uio->uio_resid; - if (ioflag & IO_SYNC) - flags = B_SYNC; - else - flags = 0; - - for (error = 0; uio->uio_resid > 0;) { - lbn = uio->uio_offset / size; - blkoffset = uio->uio_offset - lbn * size; - - xfersize = size - blkoffset; - if (uio->uio_resid < xfersize) - xfersize = uio->uio_resid; - - if (uio->uio_offset + xfersize > size of file) - vnode_pager_setsize(vp, uio->uio_offset + xfersize); - - if (size > xfersize) - flags |= B_CLRBUF; - else - flags &= ~B_CLRBUF; - - error = find_block_in_file(vp, lbn, blkoffset + xfersize, - cred, &bp, flags); - if (error) - break; - - if (uio->uio_offset + xfersize > size of file) - set size of file to uio->uio_offset + xfersize; - - error = uiomove((char *)bp->b_data + blkoffset, (int) xfersize, uio); - /* XXX ufs does not check the error here. Why? */ - - if (ioflag & IO_VMIO) - bp->b_flags |= B_RELBUF; /* ??? */ - - if (ioflag & IO_SYNC) - bwrite(bp); - else if (xfersize + blkoffset == size) - bawrite(bp); - else - bdwrite(bp); - - if (error || xfersize == 0) - break; - } - - if (error) { - if (ioflag & IO_UNIT) { - /* call private routine to truncate file. */ - your_truncate(vp, osize, ioflag & IO_SYNC, cred, uio->uio_td); - uio->uio_offset -= resid - uio->uio_resid; - uio->uio_resid = resid; - } - } else if (resid > uio->uio_resid && (ioflag & IO_SYNC)) { - struct timeval tv; - error = VOP_UPDATE(vp, &tv, &tv, 1); /* XXX what does this do? */ - } - - return (error); -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er EFBIG Index: VOP_ATTRIB.9 =================================================================== --- VOP_ATTRIB.9 (revision 190481) +++ VOP_ATTRIB.9 (working copy) @@ -84,68 +84,6 @@ .Fn VOP_SETATTR returns zero if the attributes were changed successfully, otherwise an appropriate error is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_getattr(struct vnode *vp, struct vattr *vap, struct ucred *cred) -{ - - /* - * Fill in the contents of *vap with information from - * the file system. - */ - ...; - - return 0; -} - -int -vop_setattr(struct vnode *vp, struct vattr *vap, struct ucred *cred) -{ - - /* - * Check for unsettable attributes. - */ - if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) || - (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) || - (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) || - ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) { - return (EINVAL); - } - - if (vap->va_flags != VNOVAL) { - /* - * Set the immutable and append flags of the file. - */ - } - - if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) { - /* - * Change owner and/or group of the file. - */ - } - - if (vap->va_size != VNOVAL) { - /* - * Truncate the file to the specified size. - */ - } - - if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { - /* - * Change access and/or modification time of file. - */ - } - - if (vap->va_mode != (mode_t)VNOVAL) { - /* - * Change permissions of file. - */ - } - - return 0; -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er EPERM Index: VOP_LOCK.9 =================================================================== --- VOP_LOCK.9 (revision 190481) +++ VOP_LOCK.9 (working copy) @@ -116,72 +116,6 @@ assumes curthread to be used. .Sh RETURN VALUES Zero is returned on success, otherwise an error is returned. -.Sh PSEUDOCODE -.Bd -literal -struct vopnode { - int von_flag; - /* - * Other file system specific data. - */ - ...; -}; -#define VON_LOCKED 1 -#define VON_WANTED 2 -#define VTOVON(vp) ((struct vopnode *) (vp)->v_data) - -int -vop_lock(struct vnode *vp) -{ - struct vopnode* vop; - -start: - while (vp->v_flag & VXLOCK) { - vp->v_flag |= VXWANT; - tsleep((caddr_t)vp, PINOD, "voplk1", 0); - } - if (vp->v_tag == VT_NON) - return ENOENT; - - vop = VTOVON(vp); - if (vop->von_flag & VON_LOCKED) { - vop->von_flag |= VON_WANTED; - tsleep((caddr_t) vop, PINOD, "voplk2", 0); - goto start; - } - - vop->von_flag |= VON_LOCKED; - - return 0; -} - -int -vop_unlock(struct vnode *vp) -{ - struct vopnode *vop = VTOVON(vp); - - if ((vop->von_flag & VON_LOCKED) == 0) { - panic("vop_unlock not locked"); - } - vop->von_flag &= ~VON_LOCKED; - if (vop->von_flag & VON_WANTED) { - vop->von_flag &= ~VON_WANTED; - wakeup((caddr_t) vop); - } - - return 0; -} - -int -vop_islocked(struct vnode *vp) -{ - struct vopnode *vop = VTOVON(vp); - - if (vop->von_flag & VON_LOCKED) - return 1; - else - return 0; -} -.Ed .Sh SEE ALSO .Xr vnode 9 .Sh AUTHORS Index: VOP_ACCESS.9 =================================================================== --- VOP_ACCESS.9 (revision 190481) +++ VOP_ACCESS.9 (working copy) @@ -68,40 +68,6 @@ .Sh RETURN VALUES If the file is accessible in the specified way, then zero is returned, otherwise an appropriate error code is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_access(struct vnode *vp, accmode_t accmode, struct ucred *cred, struct thread *td) -{ - int error; - - /* - * Disallow write attempts on read-only file systems; - * unless the file is a socket, fifo, or a block or - * character device resident on the filesystem. - */ - if (accmode & VWRITE) { - switch (vp->v_type) { - case VDIR: - case VLNK: - case VREG: - if (vp->v_mount->mnt_flag & MNT_RDONLY) - return EROFS; - - break; - } - } - - /* If immutable bit set, nobody gets to write it. */ - if ((accmode & VWRITE) && vp has immutable bit set) - return (EPERM); - - error = vaccess(vp->v_type, mode of vp, owner of vp, - group of vp, ap->a_accmode, ap->a_cred, NULL); - - return (error); -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er EPERM Index: VOP_INACTIVE.9 =================================================================== --- VOP_INACTIVE.9 (revision 190481) +++ VOP_INACTIVE.9 (working copy) @@ -74,38 +74,6 @@ For VOP_RECLAIM, the .Fa vp will not be locked on entry and should be left unlocked on return. -.Sh PSEUDOCODE -.Bd -literal -int -vop_inactive(struct vnode *vp, struct thread *td) -{ - if (link count of vp == 0) { - /* - * Reclaim space in file system for vp. - */ - ...; - } - VOP_UNLOCK(vp, 0, td); - - return 0; -} - -int -vop_reclaim(struct vnode *vp, struct thread *td) -{ - /* - * Clean out the name cache. - */ - cache_purge(vp); - - /* - * Free file system related data. - */ - ...; - - return 0; -} -.Ed .Sh SEE ALSO .Xr vnode 9 .Sh AUTHORS Index: VOP_IOCTL.9 =================================================================== --- VOP_IOCTL.9 (revision 190481) +++ VOP_IOCTL.9 (working copy) @@ -67,16 +67,6 @@ If the ioctl is not recognized or not handled, .Er ENOTTY should be returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_ioctl(struct vnode *vp, int command, caddr_t data, int fflag, - struct ucred *cred, struct thread *td) -{ - - return ENOTTY; -} -.Ed .Sh SEE ALSO .Xr vnode 9 .Sh AUTHORS Index: VOP_OPENCLOSE.9 =================================================================== --- VOP_OPENCLOSE.9 (revision 190481) +++ VOP_OPENCLOSE.9 (working copy) @@ -94,18 +94,6 @@ to returning. .Sh RETURN VALUES Zero is returned on success, otherwise an error code is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_open(struct vnode *vp, int mode, struct ucred *cred, struct thread *td, - struct file *fp) -{ - /* - * Most file systems don't do much here. - */ - return 0; -} -.Ed .Sh SEE ALSO .Xr vnode 9 , .Xr VOP_LOOKUP 9 Index: VOP_VPTOCNP.9 =================================================================== --- VOP_VPTOCNP.9 (revision 190481) +++ VOP_VPTOCNP.9 (working copy) @@ -70,30 +70,6 @@ will have its hold count incremented. .Sh RETURN VALUES Zero is returned on success, otherwise an error code is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_vptocnp(struct vnode *vp, struct vnode **dvp, char *buf, int *buflen) -{ - int error = 0; - - /* - * Translate the vnode to its component name. - * - * Decrement the component name's length from buflen. - * - * Obtain the vnode's parent directory vnode. - */ - ...; - - /* - * Increment the parent directory's hold count. - */ - vhold(*dvp); - - return error; -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er ENOMEM Index: VOP_FSYNC.9 =================================================================== --- VOP_FSYNC.9 (revision 190481) +++ VOP_FSYNC.9 (working copy) @@ -79,61 +79,6 @@ .Sh RETURN VALUES Zero is returned if the call is successful, otherwise an appropriate error code is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_fsync(struct vnode *vp, int waitfor, struct thread *td) -{ - struct buf *bp; - struct buf *nbp; - struct timeval tv; - int s; - -loop: - s = splbio(); - for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) { - nbp = bp->b_vnbufs.le_next; - - /* - * Ignore buffers which are already being written. - */ - if (bp->b_flags & B_BUSY) - continue; - - /* - * Make sure the buffer is dirty. - */ - if ((bp->b_flags & B_DELWRI) == 0) - panic("vop_fsync: not dirty"); - - vfs_bio_awrite(bp); - splx(s); - goto loop; - } - splx(s); - - if (waitfor == MNT_WAIT) { - s = splbio(); - while (vp->v_numoutput) { - vp->v_flag |= VBWAIT; - tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "vopfsn"); - } - splx(s); -#ifdef DIAGNOSTIC - if (vp->v_dirtyblkhd.lh_first) { - vprint("vop_fsync: dirty", vp); - goto loop; - } -#endif - } - - /* - * Write out the on-disc version of the vnode. - */ - tv = time; - return VOP_UPDATE(vp, &tv, &tv, waitfor == MNT_WAIT); -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er ENOSPC Index: VOP_READDIR.9 =================================================================== --- VOP_READDIR.9 (revision 190481) +++ VOP_READDIR.9 (working copy) @@ -96,70 +96,6 @@ *cookies = (u_int*)# malloc(*ncookies * sizeof(u_int), M_TEMP, M_WAITOK); .Ed -.Sh PSEUDOCODE -.Bd -literal -int -vop_readdir(struct vnode *vp, struct uio *uio, struct ucred *cred, - int *eofflag, int *ncookies, u_int **cookies) -{ - off_t off; - int error = 0; - - /* - * Remember the original offset to use later in generating cookies. - */ - off = uio->uio_offset; - - /* - * Read directory contents starting at uio->uio_offset into buffer - * pointed to by uio. - */ - ...; - - if (!error && ncookies != NULL) { - struct dirent *dpStart; - struct dirent *dpEnd; - struct dirent *dp; - int count; - u_int *cookiebuf; - u_int *cookiep; - - if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) - panic("vop_readdir: unexpected uio from NFS server"); - - /* - * Parse the stuff just read into the uio. - */ - dpStart = (struct dirent *) - ((char *)uio->uio_iov->iov_base - (uio->uio_offset - off)); - dpEnd = (struct dirent *) uio->uio_iov->iov_base; - - /* - * Count number of entries. - */ - for (dp = dpStart, count = 0; - dp < dpEnd; - dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) - count++; - - cookiebuf = (u_int *) malloc(count * sizeof(u_int), M_TEMP, M_WAITOK); - for (dp = dpStart; cookiep = cookiebuf; - dp < dpEnd; - dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) { - off += dp->d_reclen; - *cookiep++ = (u_int) off; - } - *ncookies = count; - *cookies = cookiebuf; - } - - if (eofflag && uio->uio_offset is past the end of the directory) { - *eofflag = TRUE; - } - - return error; -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er EINVAL Index: VOP_LINK.9 =================================================================== --- VOP_LINK.9 (revision 190481) +++ VOP_LINK.9 (working copy) @@ -66,37 +66,6 @@ .Sh RETURN VALUES Zero is returned if the file was linked successfully, otherwise an error is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_link(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) -{ - int error = 0; - - if (vp->v_mount != dvp->v_mount) - return (EXDEV); - - if (vp would have too many links) - return (EMLINK); - - if (vp is immutable) - return (EPERM); - - /* - * Increment link count of vp and write back the on-disc version of it. - */ - ...; - - if (!error) { - /* - * Add the new name to the directory. - */ - ...; - } - - return error; -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er EMLINK Index: VOP_CREATE.9 =================================================================== --- VOP_CREATE.9 (revision 190481) +++ VOP_CREATE.9 (working copy) @@ -80,67 +80,6 @@ .Fa *vpp and zero is returned. Otherwise, an appropriate error is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_create(struct vnode *dvp, - struct vnode **vpp, - struct componentname *cnp - struct vattr *vap) -{ - int mode = MAKEIMODE(vap->va_type, vap->va_mode); - struct vnode *vp; - int error; - - *vpp = NULL; - if ((mode & IFMT) == 0) - mode |= IFREG; - - error = SOMEFS_VALLOC(dvp, mode, cnp->cn_cred, &vp); - if (error) - return error; - - /* - * Update the permissions for the new vnode, including - * copying the group from the directory. - */ - ...; - -#ifdef QUOTA - /* - * Possibly check quota information. - */ - ...; -#endif - - /* - * Enter new vnode in directory, taking care that the vnode - * hits the disk before the directory contents are changed. - */ - error = ...; - - if (error) - goto bad; - - *vpp = vp; - - return 0; - -bad: - /* - * Write error occurred trying to update the inode - * or the directory so must deallocate the inode. - */ - vput(vp); - - /* - * Deallocate file system resources for vp. - */ - ...; - - return error; -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er ENOSPC Index: VOP_LOOKUP.9 =================================================================== --- VOP_LOOKUP.9 (revision 190481) +++ VOP_LOOKUP.9 (working copy) @@ -156,260 +156,6 @@ .Er EJUSTRETURN is returned. Otherwise, an appropriate error code is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_lookup(struct vnode *dvp, - struct vnode **vpp, - struct componentname *cnp) -{ - int error; - int nameiop = cnp->cn_nameiop; - int flags = cnp->cn_flags; - int lockparent = flags & LOCKPARENT; - int islastcn = flags & ISLASTCN; - struct vnode *vp = NULL; - - /* - * Check accessibility of directory. - */ - if (dvp->v_type != VDIR) - return ENOTDIR; - - error = VOP_ACCESS(dvp, VEXEC, cred, cnp->cn_thread); - if (error) - return (error); - - if (islastcn && (dvp->v_mount->mnt_flag & MNT_RDONLY) && - (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) - return (EROFS); - - /* - * Check name cache for directory/name pair. This returns ENOENT - * if the name is known not to exist, -1 if the name was found, or - * zero if not. - */ - error = cache_lookup(dvp, vpp, cnp); - if (error) { - int vpid; - - if (error = ENOENT) - return error; - - vp = *vpp; - if (dvp == vp) { /* lookup on "." */ - VREF(vp); - error = 0; - } else if (flags & ISDOTDOT) { - /* - * We need to unlock the directory before getting - * the locked vnode for ".." to avoid deadlocks. - */ - VOP_UNLOCK(dvp); - error = vget(vp, 1); - if (!error) { - if (lockparent && islastcn) - error = VOP_LOCK(dvp); - } - } else { - error = vget(vp, 1); - if (error || !(lockparent && islastcn)) { - VOP_UNLOCK(dvp); - } - } - - /* - * Check that the capability number did not change - * while we were waiting for the lock. - */ - if (!error) { - if (vpid == vp->v_id) { - /* - * dvp is locked if lockparent && islastcn. - * vp is locked. - */ - return (0); - } - vput(vp); - - if (dvp != vp && lockparent && islastcn) - VOP_UNLOCK(pdp); - } - - /* - * Re-lock dvp for the directory search below. - */ - error = VOP_LOCK(dvp); - if (error) { - return (error); - } - - *vpp = NULL; - } - - /* - * Search dvp for the component cnp->cn_nameptr. - */ - ...; - - if (!found) { - if ((nameiop == CREATE || nameiop == RENAME) - && islastcn - && directory dvp has not been removed) { - /* - * Check for write access on directory. - */ - - /* - * Possibly record the position of a slot in the directory - * large enough for the new component name. This can be - * recorded in the vnode private data for dvp. - * Set the SAVENAME flag to hold onto the pathname for use - * later in VOP_CREATE or VOP_RENAME. - */ - cnp->cn_flags |= SAVENAME; - if (!lockparent) - /* - * Note that the extra data recorded above is only - * useful if lockparent is specified. - */ - VOP_UNLOCK(dvp); - - return EJUSTRETURN; - } - - /* - * Consider inserting name into cache. - */ - if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) - cache_enter(dvp, NULL, cnp); - - return ENOENT; - } else { - /* - * If deleting, and at end of pathname, return parameters - * which can be used to remove file. If the wantparent flag - * isn't set, we return only the directory, otherwise we go on - * and lock the inode, being careful with ".". - */ - if (nameiop == DELETE && islastcn) { - /* - * Check for write access on directory. - */ - error = VOP_ACCESS(dvp, VWRITE, cred, cnp->cn_thread); - if (error) - return (error); - - if (found entry is same as dvp) { - VREF(dvp); - *vpp = dvp; - return 0; - } - - error = VFS_VGET(dvp->v_mount, ..., &vp); - if (error) - return error; - - if (directory is sticky - && cred->cr_uid != 0 - && cred->cr_uid != owner of dvp - && owner of vp != cred->cr_uid) { - vput(vp); - return EPERM; - } - *vpp = vp; - if (!lockparent) - VOP_UNLOCK(dvp); - - return 0; - } - - /* - * If rewriting (RENAME), return the inode and the - * information required to rewrite the present directory - * Must get inode of directory entry to verify it's a - * regular file, or empty directory. - */ - if (nameiop == RENAME && wantparent && islastcn) { - error = VOP_ACCESS(dvp, VWRITE, cred, cnp->cn_thread); - if (error) - return (error); - - /* - * Check for "." - */ - if (found entry is same as dvp) - return EISDIR; - - error = VFS_VGET(dvp->v_mount, ..., &vp); - if (error) - return error; - *vpp = vp; - /* - * Save the name for use in VOP_RENAME later. - */ - cnp->cn_flags |= SAVENAME; - if (!lockparent) - VOP_UNLOCK(dvp); - - return 0; - } - - /* - * Step through the translation in the name. We do not `vput' the - * directory because we may need it again if a symbolic link - * is relative to the current directory. Instead we save it - * unlocked as "pdp". We must get the target inode before unlocking - * the directory to insure that the inode will not be removed - * before we get it. We prevent deadlock by always fetching - * inodes from the root, moving down the directory tree. Thus - * when following backward pointers ".." we must unlock the - * parent directory before getting the requested directory. - * There is a potential race condition here if both the current - * and parent directories are removed before the VFS_VGET for the - * inode associated with ".." returns. We hope that this occurs - * infrequently since we cannot avoid this race condition without - * implementing a sophisticated deadlock detection algorithm. - * Note also that this simple deadlock detection scheme will not - * work if the file system has any hard links other than ".." - * that point backwards in the directory structure. - */ - if (flags & ISDOTDOT) { - VOP_UNLOCK(dvp); /* race to get the inode */ - error = VFS_VGET(dvp->v_mount, ..., &vp); - if (error) { - VOP_LOCK(dvp); - return (error); - } - if (lockparent && islastcn) { - error = VOP_LOCK(dvp); - if (error) { - vput(vp); - return error; - } - } - *vpp = vp; - } else if (found entry is same as dvp) { - VREF(dvp); /* we want ourself, ie "." */ - *vpp = dvp; - } else { - error = VFS_VGET(dvp->v_mount, ..., &vp); - if (error) - return (error); - if (!lockparent || !islastcn) - VOP_UNLOCK(dvp); - *vpp = vp; - } - - /* - * Insert name into cache if appropriate. - */ - if (cnp->cn_flags & MAKEENTRY) - cache_enter(dvp, *vpp, cnp); - return (0); - } -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er ENOTDIR Index: VOP_READLINK.9 =================================================================== --- VOP_READLINK.9 (revision 190481) +++ VOP_READLINK.9 (working copy) @@ -54,21 +54,6 @@ The vnode should be locked on entry and will still be locked on exit. .Sh RETURN VALUES Zero is returned on success, otherwise an error code is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_readlink(struct vnode *vp, struct uio *uio, struct ucred *cred) -{ - int error = 0; - - /* - * Read the target of the symlink. - */ - ...; - - return error; -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er EIO Index: VOP_REMOVE.9 =================================================================== --- VOP_REMOVE.9 (revision 190481) +++ VOP_REMOVE.9 (working copy) @@ -62,27 +62,6 @@ should be locked on entry and remain locked on return. .Sh RETURN VALUES Zero is returned on success, otherwise an error code is returned. -.Sh PSEUDOCODE -.Bd -literal -int -vop_remove(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) -{ - int error = 0; - - if (vp is immutable) { - error = EPERM; - goto out; - } - - /* - * Remove name cnp->cn_nameptr from directory and update link count - * of vp. - */ - ...; - - return error; -} -.Ed .Sh ERRORS .Bl -tag -width Er .It Bq Er EPERM