X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/e39dd239b7317811b3a0b244457de19faaacfe43..88191af74ed87fd4dfbc69469c29a77011d40d32:/usr/src/sys/kern/vfs_vnops.c diff --git a/usr/src/sys/kern/vfs_vnops.c b/usr/src/sys/kern/vfs_vnops.c index be57b39098..736c330582 100644 --- a/usr/src/sys/kern/vfs_vnops.c +++ b/usr/src/sys/kern/vfs_vnops.c @@ -1,24 +1,30 @@ /* - * Copyright (c) 1982, 1986, 1989 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1982, 1986, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. * * %sccs.include.redist.c% * - * @(#)vfs_vnops.c 7.40 (Berkeley) %G% + * @(#)vfs_vnops.c 8.12 (Berkeley) %G% */ -#include "param.h" -#include "systm.h" -#include "kernel.h" -#include "file.h" -#include "stat.h" -#include "buf.h" -#include "proc.h" -#include "mount.h" -#include "namei.h" -#include "vnode.h" -#include "ioctl.h" -#include "tty.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include struct fileops vnops = @@ -32,11 +38,6 @@ vn_open(ndp, fmode, cmode) register struct nameidata *ndp; int fmode, cmode; { - USES_VOP_ABORTOP; - USES_VOP_ACCESS; - USES_VOP_CREATE; - USES_VOP_OPEN; - USES_VOP_SETATTR; register struct vnode *vp; register struct proc *p = ndp->ni_cnd.cn_proc; register struct ucred *cred = p->p_ucred; @@ -55,7 +56,9 @@ vn_open(ndp, fmode, cmode) VATTR_NULL(vap); vap->va_type = VREG; vap->va_mode = cmode; - LEASE_CHECK(ndp->ni_dvp, p, cred, LEASE_WRITE); + if (fmode & O_EXCL) + vap->va_vaflags |= VA_EXCLUSIVE; + VOP_LEASE(ndp->ni_dvp, p, cred, LEASE_WRITE); if (error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, &ndp->ni_cnd, vap)) return (error); @@ -102,9 +105,11 @@ vn_open(ndp, fmode, cmode) } } if (fmode & O_TRUNC) { + VOP_UNLOCK(vp, 0, p); /* XXX */ + VOP_LEASE(vp, p, cred, LEASE_WRITE); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); /* XXX */ VATTR_NULL(vap); vap->va_size = 0; - LEASE_CHECK(vp, p, cred, LEASE_WRITE); if (error = VOP_SETATTR(vp, vap, cred, p)) goto bad; } @@ -157,7 +162,6 @@ vn_close(vp, flags, cred, p) struct ucred *cred; struct proc *p; { - USES_VOP_CLOSE; int error; if (flags & FWRITE) @@ -182,16 +186,12 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, p) int *aresid; struct proc *p; { - USES_VOP_LOCK; - USES_VOP_READ; - USES_VOP_UNLOCK; - USES_VOP_WRITE; struct uio auio; struct iovec aiov; int error; if ((ioflg & IO_NODELOCKED) == 0) - VOP_LOCK(vp); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); auio.uio_iov = &aiov; auio.uio_iovcnt = 1; aiov.iov_base = base; @@ -202,10 +202,8 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, p) auio.uio_rw = rw; auio.uio_procp = p; if (rw == UIO_READ) { - LEASE_CHECK(vp, p, cred, LEASE_READ); error = VOP_READ(vp, &auio, ioflg, cred); } else { - LEASE_CHECK(vp, p, cred, LEASE_WRITE); error = VOP_WRITE(vp, &auio, ioflg, cred); } if (aresid) @@ -214,7 +212,7 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, p) if (auio.uio_resid && error == 0) error = EIO; if ((ioflg & IO_NODELOCKED) == 0) - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); return (error); } @@ -226,20 +224,18 @@ vn_read(fp, uio, cred) struct uio *uio; struct ucred *cred; { - USES_VOP_LOCK; - USES_VOP_READ; - USES_VOP_UNLOCK; - register struct vnode *vp = (struct vnode *)fp->f_data; + struct vnode *vp = (struct vnode *)fp->f_data; + struct proc *p = uio->uio_procp; int count, error; - VOP_LOCK(vp); + VOP_LEASE(vp, p, cred, LEASE_READ); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); uio->uio_offset = fp->f_offset; count = uio->uio_resid; - LEASE_CHECK(vp, uio->uio_procp, cred, LEASE_READ); error = VOP_READ(vp, uio, (fp->f_flag & FNONBLOCK) ? IO_NDELAY : 0, cred); fp->f_offset += count - uio->uio_resid; - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); return (error); } @@ -251,26 +247,26 @@ vn_write(fp, uio, cred) struct uio *uio; struct ucred *cred; { - USES_VOP_LOCK; - USES_VOP_UNLOCK; - USES_VOP_WRITE; - register struct vnode *vp = (struct vnode *)fp->f_data; - int count, error, ioflag = 0; + struct vnode *vp = (struct vnode *)fp->f_data; + struct proc *p = uio->uio_procp; + int count, error, ioflag = IO_UNIT; if (vp->v_type == VREG && (fp->f_flag & O_APPEND)) ioflag |= IO_APPEND; if (fp->f_flag & FNONBLOCK) ioflag |= IO_NDELAY; - VOP_LOCK(vp); + if ((fp->f_flag & O_FSYNC) || (vp->v_mount->mnt_flag & MNT_SYNCHRONOUS)) + ioflag |= IO_SYNC; + VOP_LEASE(vp, p, cred, LEASE_WRITE); + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); uio->uio_offset = fp->f_offset; count = uio->uio_resid; - LEASE_CHECK(vp, uio->uio_procp, cred, LEASE_WRITE); error = VOP_WRITE(vp, uio, ioflag, cred); if (ioflag & IO_APPEND) fp->f_offset = uio->uio_offset; else fp->f_offset += count - uio->uio_resid; - VOP_UNLOCK(vp); + VOP_UNLOCK(vp, 0, p); return (error); } @@ -282,7 +278,6 @@ vn_stat(vp, sb, p) register struct stat *sb; struct proc *p; { - USES_VOP_GETATTR; struct vattr vattr; register struct vattr *vap; int error; @@ -329,12 +324,9 @@ vn_stat(vp, sb, p) sb->st_gid = vap->va_gid; sb->st_rdev = vap->va_rdev; sb->st_size = vap->va_size; - sb->st_atimespec.ts_sec = vap->va_atime.tv_sec; - sb->st_atimespec.ts_nsec = vap->va_atime.tv_usec * 1000; - sb->st_mtimespec.ts_sec = vap->va_mtime.tv_sec; - sb->st_mtimespec.ts_nsec = vap->va_mtime.tv_usec * 1000; - sb->st_ctimespec.ts_sec = vap->va_ctime.tv_sec; - sb->st_ctimespec.ts_nsec = vap->va_ctime.tv_usec * 1000; + sb->st_atimespec = vap->va_atime; + sb->st_mtimespec = vap->va_mtime; + sb->st_ctimespec = vap->va_ctime; sb->st_blksize = vap->va_blocksize; sb->st_flags = vap->va_flags; sb->st_gen = vap->va_gen; @@ -347,12 +339,10 @@ vn_stat(vp, sb, p) */ vn_ioctl(fp, com, data, p) struct file *fp; - int com; + u_long com; caddr_t data; struct proc *p; { - USES_VOP_GETATTR; - USES_VOP_IOCTL; register struct vnode *vp = ((struct vnode *)fp->f_data); struct vattr vattr; int error; @@ -364,7 +354,7 @@ vn_ioctl(fp, com, data, p) if (com == FIONREAD) { if (error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) return (error); - *(off_t *)data = vattr.va_size - fp->f_offset; + *(int *)data = vattr.va_size - fp->f_offset; return (0); } if (com == FIONBIO || com == FIOASYNC) /* XXX */ @@ -379,6 +369,8 @@ vn_ioctl(fp, com, data, p) case VBLK: error = VOP_IOCTL(vp, com, data, fp->f_flag, p->p_ucred, p); if (error == 0 && com == TIOCSCTTY) { + if (p->p_session->s_ttyvp) + vrele(p->p_session->s_ttyvp); p->p_session->s_ttyvp = vp; VREF(vp); } @@ -394,43 +386,49 @@ vn_select(fp, which, p) int which; struct proc *p; { - USES_VOP_SELECT; return (VOP_SELECT(((struct vnode *)fp->f_data), which, fp->f_flag, fp->f_cred, p)); } /* - * File table vnode close routine. + * Check that the vnode is still valid, and if so + * acquire requested lock. */ -vn_closefile(fp, p) - struct file *fp; +int +vn_lock(vp, flags, p) + struct vnode *vp; + int flags; struct proc *p; { - - return (vn_close(((struct vnode *)fp->f_data), fp->f_flag, - fp->f_cred, p)); + int error; + + do { + if ((flags & LK_INTERLOCK) == 0) + simple_lock(&vp->v_interlock); + if (vp->v_flag & VXLOCK) { + vp->v_flag |= VXWANT; + simple_unlock(&vp->v_interlock); + tsleep((caddr_t)vp, PINOD, "vn_lock", 0); + error = ENOENT; + } else { + error = VOP_LOCK(vp, flags | LK_INTERLOCK, p); + if (error == 0) + return (error); + } + flags &= ~LK_INTERLOCK; + } while (flags & LK_RETRY); + return (error); } /* - * vn_fhtovp() - convert a fh to a vnode ptr (optionally locked) - * - look up fsid in mount list (if not found ret error) - * - get vp by calling VFS_FHTOVP() macro - * - if lockflag lock it with VOP_LOCK() + * File table vnode close routine. */ -vn_fhtovp(fhp, lockflag, vpp) - fhandle_t *fhp; - int lockflag; - struct vnode **vpp; +vn_closefile(fp, p) + struct file *fp; + struct proc *p; { - USES_VOP_UNLOCK; - register struct mount *mp; - if ((mp = getvfs(&fhp->fh_fsid)) == NULL) - return (ESTALE); - if (VFS_FHTOVP(mp, &fhp->fh_fid, 0, vpp)) - return (ESTALE); - if (!lockflag) - VOP_UNLOCK(*vpp); - return (0); + return (vn_close(((struct vnode *)fp->f_data), fp->f_flag, + fp->f_cred, p)); }