summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_vnops.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-02-10 02:22:35 +0000
committerdyson <dyson@FreeBSD.org>1997-02-10 02:22:35 +0000
commit10f666af84d48e89e4e2960415c9b616fce4077f (patch)
tree88a944de263165091f0a18abeedbaaccec532407 /sys/kern/vfs_vnops.c
parent0960d7e91af3428ffba89b42228d82d8afaa0389 (diff)
downloadFreeBSD-src-10f666af84d48e89e4e2960415c9b616fce4077f.zip
FreeBSD-src-10f666af84d48e89e4e2960415c9b616fce4077f.tar.gz
This is the kernel Lite/2 commit. There are some requisite userland
changes, so don't expect to be able to run the kernel as-is (very well) without the appropriate Lite/2 userland changes. The system boots and can mount UFS filesystems. Untested: ext2fs, msdosfs, NFS Known problems: Incorrect Berkeley ID strings in some files. Mount_std mounts will not work until the getfsent library routine is changed. Reviewed by: various people Submitted by: Jeffery Hsu <hsu@freebsd.org>
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r--sys/kern/vfs_vnops.c78
1 files changed, 57 insertions, 21 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 0ba5c45..98842c6 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -96,10 +96,11 @@ 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);
- error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp,
- &ndp->ni_cnd, vap);
- if (error)
+ 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);
fmode &= ~O_TRUNC;
vp = ndp->ni_vp;
@@ -149,9 +150,9 @@ vn_open(ndp, fmode, cmode)
}
}
if (fmode & O_TRUNC) {
- VOP_UNLOCK(vp); /* XXX */
- LEASE_CHECK(vp, p, cred, LEASE_WRITE);
- VOP_LOCK(vp); /* XXX */
+ 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;
error = VOP_SETATTR(vp, vap, cred, p);
@@ -179,8 +180,7 @@ bad:
/*
* Check for write permissions on the specified vnode.
- * The read-only status of the file system is checked.
- * Also, prototype text segments cannot be written.
+ * Prototype text segments cannot be written.
*/
int
vn_writechk(vp)
@@ -237,7 +237,7 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, p)
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;
@@ -258,7 +258,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);
}
@@ -271,12 +271,13 @@ vn_read(fp, uio, cred)
struct uio *uio;
struct ucred *cred;
{
- 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;
int flag, seq;
- LEASE_CHECK(vp, uio->uio_procp, cred, LEASE_READ);
- 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;
flag = 0;
@@ -313,7 +314,7 @@ vn_read(fp, uio, cred)
error = VOP_READ(vp, uio, flag, cred);
fp->f_offset += count - uio->uio_resid;
fp->f_nextread = fp->f_offset;
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -326,15 +327,19 @@ vn_write(fp, uio, cred)
struct uio *uio;
struct ucred *cred;
{
- 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;
- LEASE_CHECK(vp, uio->uio_procp, cred, LEASE_WRITE);
- VOP_LOCK(vp);
+ if ((fp->f_flag & O_FSYNC) ||
+ (vp->v_mount && (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;
error = VOP_WRITE(vp, uio, ioflag, cred);
@@ -342,7 +347,7 @@ vn_write(fp, uio, cred)
fp->f_offset = uio->uio_offset;
else
fp->f_offset += count - uio->uio_resid;
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -402,7 +407,7 @@ vn_stat(vp, sb, p)
sb->st_rdev = vap->va_rdev;
sb->st_size = vap->va_size;
sb->st_atimespec = vap->va_atime;
- sb->st_mtimespec= vap->va_mtime;
+ sb->st_mtimespec = vap->va_mtime;
sb->st_ctimespec = vap->va_ctime;
sb->st_blksize = vap->va_blocksize;
sb->st_flags = vap->va_flags;
@@ -495,3 +500,34 @@ vn_closefile(fp, p)
return (vn_close(((struct vnode *)fp->f_data), fp->f_flag,
fp->f_cred, p));
}
+
+/*
+ * Check that the vnode is still valid, and if so
+ * acquire requested lock.
+ */
+int
+vn_lock(vp, flags, p)
+ struct vnode *vp;
+ int flags;
+ struct proc *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);
+}
OpenPOWER on IntegriCloud