summaryrefslogtreecommitdiff
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c406
1 files changed, 224 insertions, 182 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 74d914ee7e8..f1e566ae6b8 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.25 1997/03/02 09:38:35 millert Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.26 1997/10/06 15:12:43 csapuntz Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -102,10 +102,11 @@ sys_mount(p, v, retval)
register struct vnode *vp;
register struct mount *mp;
int error, flag = 0;
- u_long fsindex = 0;
+ u_long fstypenum = 0;
char fstypename[MFSNAMELEN];
struct vattr va;
struct nameidata nd;
+ struct vfsconf *vfsp;
if (usermount == 0 && (error = suser(p->p_ucred, &p->p_acflag)))
return (error);
@@ -156,7 +157,7 @@ sys_mount(p, v, retval)
}
SCARG(uap, flags) |= MNT_NOSUID | MNT_NODEV;
}
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
goto update;
}
/*
@@ -195,12 +196,19 @@ sys_mount(p, v, retval)
* string, we check to see if it matches one of the historic
* filesystem types.
*/
- fsindex = (u_long)SCARG(uap, type);
- if (fsindex >= nvfssw || vfssw[fsindex] == NULL) {
- vput(vp);
- return (ENODEV);
+ fstypenum = (u_long)SCARG(uap, type);
+
+ if (fstypenum < maxvfsconf) {
+ for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next)
+ if (vfsp->vfc_typenum == fstypenum)
+ break;
+ if (vfsp == NULL) {
+ vput(vp);
+ return (ENODEV);
+ }
+ strncpy(fstypename, vfsp->vfc_name, MFSNAMELEN);
+
}
- strncpy(fstypename, vfssw[fsindex]->vfs_name, MFSNAMELEN);
#else
vput(vp);
return (error);
@@ -212,14 +220,16 @@ sys_mount(p, v, retval)
strncpy( fstypename, "ffs", MFSNAMELEN);
}
#endif
- for (fsindex = 0; fsindex < nvfssw; fsindex++)
- if (vfssw[fsindex] != NULL &&
- !strncmp(vfssw[fsindex]->vfs_name, fstypename, MFSNAMELEN))
+ for (vfsp = vfsconf; vfsp; vfsp = vfsp->vfc_next) {
+ if (!strcmp(vfsp->vfc_name, fstypename))
break;
- if (fsindex >= nvfssw) {
+ }
+
+ if (vfsp == NULL) {
vput(vp);
return (ENODEV);
}
+
if (vp->v_mountedhere != NULL) {
vput(vp);
return (EBUSY);
@@ -231,14 +241,14 @@ sys_mount(p, v, retval)
mp = (struct mount *)malloc((u_long)sizeof(struct mount),
M_MOUNT, M_WAITOK);
bzero((char *)mp, (u_long)sizeof(struct mount));
- mp->mnt_op = vfssw[fsindex];
- if ((error = vfs_lock(mp)) != 0) {
- free((caddr_t)mp, M_MOUNT);
- vput(vp);
- return (error);
- }
- /* Do this early in case we block later. */
- vfssw[fsindex]->vfs_refcount++;
+ lockinit(&mp->mnt_lock, PVFS, "vfslock", 0, 0);
+ vfs_busy(mp, LK_NOWAIT, 0, p);
+ mp->mnt_op = vfsp->vfc_vfsops;
+ mp->mnt_vfc = vfsp;
+ vfsp->vfc_refcount++;
+ mp->mnt_stat.f_type = vfsp->vfc_typenum;
+ mp->mnt_flag |= (vfsp->vfc_flags & MNT_VISFLAGMASK);
+ strncpy(mp->mnt_stat.f_fstypename, vfsp->vfc_name, MFSNAMELEN);
vp->v_mountedhere = mp;
mp->mnt_vnodecovered = vp;
mp->mnt_stat.f_owner = p->p_ucred->cr_uid;
@@ -266,6 +276,17 @@ update:
(MNT_UPDATE | MNT_RELOAD | MNT_FORCE | MNT_WANTRDWR);
if (error)
mp->mnt_flag = flag;
+
+ if ((mp->mnt_flag & MNT_RDONLY) == 0) {
+ if (mp->mnt_syncer == NULL)
+ error = vfs_allocate_syncvnode(mp);
+ } else {
+ if (mp->mnt_syncer != NULL)
+ vgone(mp->mnt_syncer);
+ mp->mnt_syncer = NULL;
+ }
+
+ vfs_unbusy(mp, p);
return (error);
}
/*
@@ -273,16 +294,20 @@ update:
*/
cache_purge(vp);
if (!error) {
+ simple_lock(&mountlist_slock);
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
+ simple_unlock(&mountlist_slock);
checkdirs(vp);
- VOP_UNLOCK(vp);
- vfs_unlock(mp);
+ VOP_UNLOCK(vp, 0, p);
+ if ((mp->mnt_flag & MNT_RDONLY) == 0)
+ error = vfs_allocate_syncvnode(mp);
+ vfs_unbusy(mp, p);
(void) VFS_STATFS(mp, &mp->mnt_stat, p);
- error = VFS_START(mp, 0, p);
+ if ((error = VFS_START(mp, 0, p)) != 0)
+ vrele(vp);
} else {
mp->mnt_vnodecovered->v_mountedhere = (struct mount *)0;
- vfssw[fsindex]->vfs_refcount--;
- vfs_unlock(mp);
+ vfs_unbusy(mp, p);
free((caddr_t)mp, M_MOUNT);
vput(vp);
}
@@ -397,36 +422,40 @@ dounmount(mp, flags, p)
struct vnode *coveredvp;
int error;
- coveredvp = mp->mnt_vnodecovered;
- if (vfs_busy(mp))
- return (EBUSY);
+ simple_lock(&mountlist_slock);
mp->mnt_flag |= MNT_UNMOUNT;
- if ((error = vfs_lock(mp)) != 0)
+ lockmgr(&mp->mnt_lock, LK_DRAIN | LK_INTERLOCK, &mountlist_slock, p);
+ mp->mnt_flag &=~ MNT_ASYNC;
+ vnode_pager_umount(mp); /* release cached vnodes */
+ cache_purgevfs(mp); /* remove cache entries for this file sys */
+ if (mp->mnt_syncer != NULL)
+ vgone(mp->mnt_syncer);
+ if (((mp->mnt_flag & MNT_RDONLY) ||
+ (error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0) ||
+ (flags & MNT_FORCE))
+ error = VFS_UNMOUNT(mp, flags, p);
+ simple_lock(&mountlist_slock);
+ if (error) {
+ if ((mp->mnt_flag & MNT_RDONLY) == 0 && mp->mnt_syncer == NULL)
+ (void) vfs_allocate_syncvnode(mp);
+ mp->mnt_flag &= ~MNT_UNMOUNT;
+ lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK | LK_REENABLE,
+ &mountlist_slock, p);
return (error);
-
- mp->mnt_flag &=~ MNT_ASYNC;
- vnode_pager_umount(mp); /* release cached vnodes */
- cache_purgevfs(mp); /* remove cache entries for this file sys */
- if ((error = VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p)) == 0 ||
- (flags & MNT_FORCE))
- error = VFS_UNMOUNT(mp, flags, p);
- mp->mnt_flag &= ~MNT_UNMOUNT;
- vfs_unbusy(mp);
- if (error) {
- vfs_unlock(mp);
- } else {
- CIRCLEQ_REMOVE(&mountlist, mp, mnt_list);
- if (coveredvp != NULLVP) {
- vrele(coveredvp);
- coveredvp->v_mountedhere = (struct mount *)0;
- }
- mp->mnt_op->vfs_refcount--;
- vfs_unlock(mp);
- if (mp->mnt_vnodelist.lh_first != NULL)
- panic("unmount: dangling vnode");
- free((caddr_t)mp, M_MOUNT);
}
- return (error);
+ CIRCLEQ_REMOVE(&mountlist, mp, mnt_list);
+ if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) {
+ coveredvp->v_mountedhere = (struct mount *)0;
+ vrele(coveredvp);
+ }
+ mp->mnt_vfc->vfc_refcount--;
+ if (mp->mnt_vnodelist.lh_first != NULL)
+ panic("unmount: dangling vnode");
+ lockmgr(&mp->mnt_lock, LK_RELEASE | LK_INTERLOCK, &mountlist_slock, p);
+ if (mp->mnt_flag & MNT_MWAIT)
+ wakeup((caddr_t)mp);
+ free((caddr_t)mp, M_MOUNT);
+ return (0);
}
/*
@@ -447,31 +476,25 @@ sys_sync(p, v, retval)
register struct mount *mp, *nmp;
int asyncflag;
+ simple_lock(&mountlist_slock);
for (mp = mountlist.cqh_last; mp != (void *)&mountlist; mp = nmp) {
- /*
- * Get the next pointer in case we hang on vfs_busy
- * while we are being unmounted.
- */
- nmp = mp->mnt_list.cqe_prev;
- /*
- * The lock check below is to avoid races with mount
- * and unmount.
- */
- if ((mp->mnt_flag & (MNT_MLOCK|MNT_RDONLY|MNT_MPBUSY)) == 0 &&
- !vfs_busy(mp)) {
+ if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
+ nmp = mp->mnt_list.cqe_next;
+ continue;
+ }
+ if ((mp->mnt_flag & MNT_RDONLY) == 0) {
asyncflag = mp->mnt_flag & MNT_ASYNC;
mp->mnt_flag &= ~MNT_ASYNC;
VFS_SYNC(mp, MNT_NOWAIT, p->p_ucred, p);
if (asyncflag)
mp->mnt_flag |= MNT_ASYNC;
- /*
- * Get the next pointer again, as the next filesystem
- * might have been unmounted while we were sync'ing.
- */
- nmp = mp->mnt_list.cqe_prev;
- vfs_unbusy(mp);
}
+ simple_lock(&mountlist_slock);
+ nmp = mp->mnt_list.cqe_next;
+ vfs_unbusy(mp, p);
}
+ simple_unlock(&mountlist_slock);
+
#ifdef DEBUG
if (syncprt)
vfs_bufstats();
@@ -596,7 +619,7 @@ sys_getfsstat(p, v, retval)
syscallarg(long) bufsize;
syscallarg(int) flags;
} */ *uap = v;
- register struct mount *mp;
+ register struct mount *mp, *nmp;
register struct statfs *sp;
caddr_t sfsp;
long count, maxcount, error;
@@ -604,20 +627,28 @@ sys_getfsstat(p, v, retval)
maxcount = SCARG(uap, bufsize) / sizeof(struct statfs);
sfsp = (caddr_t)SCARG(uap, buf);
- for (count = 0, mp = mountlist.cqh_first;
- mp != (void *)&mountlist;
- mp = mp->mnt_list.cqe_next) {
- if (sfsp && count < maxcount &&
- ((mp->mnt_flag & MNT_MLOCK) == 0)) {
+ count = 0;
+ simple_lock(&mountlist_slock);
+ for (mp = mountlist.cqh_first; mp != (void *)&mountlist; mp = nmp) {
+ if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) {
+ nmp = mp->mnt_list.cqe_next;
+ continue;
+ }
+ if (sfsp && count < maxcount) {
sp = &mp->mnt_stat;
/*
- * If MNT_NOWAIT is specified, do not refresh the
- * fsstat cache. MNT_WAIT overrides MNT_NOWAIT.
- */
- if (((SCARG(uap, flags) & MNT_NOWAIT) == 0 ||
+ * If MNT_NOWAIT or MNT_LAZY is specified, do not
+ * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
+ * overrides MNT_WAIT.
+ */
+ if (((SCARG(uap, flags) & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
(SCARG(uap, flags) & MNT_WAIT)) &&
- (error = VFS_STATFS(mp, sp, p)))
- continue;
+ (error = VFS_STATFS(mp, sp, p))) {
+ simple_lock(&mountlist_slock);
+ nmp = mp->mnt_list.cqe_next;
+ vfs_unbusy(mp, p);
+ continue;
+ }
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
if (suser(p->p_ucred, &p->p_acflag)) {
bcopy((caddr_t)sp, (caddr_t)&sb, sizeof(sb));
@@ -630,7 +661,11 @@ sys_getfsstat(p, v, retval)
sfsp += sizeof(*sp);
}
count++;
+ simple_lock(&mountlist_slock);
+ nmp = mp->mnt_list.cqe_next;
+ vfs_unbusy(mp, p);
}
+ simple_unlock(&mountlist_slock);
if (sfsp && count > maxcount)
*retval = maxcount;
else
@@ -661,7 +696,7 @@ sys_fchdir(p, v, retval)
return (error);
vp = (struct vnode *)fp->f_data;
VREF(vp);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_type != VDIR)
error = ENOTDIR;
else
@@ -677,11 +712,21 @@ sys_fchdir(p, v, retval)
vput(vp);
vp = tdp;
}
- VOP_UNLOCK(vp);
+ while (!error && (mp = vp->v_mountedhere) != NULL) {
+ if (vfs_busy(mp, 0, 0, p))
+ continue;
+ error = VFS_ROOT(mp, &tdp);
+ vfs_unbusy(mp, p);
+ if (error)
+ break;
+ vput(vp);
+ vp = tdp;
+ }
if (error) {
- vrele(vp);
+ vput(vp);
return (error);
}
+ VOP_UNLOCK(vp, 0, p);
vrele(fdp->fd_cdir);
fdp->fd_cdir = vp;
return (0);
@@ -768,9 +813,10 @@ change_dir(ndp, p)
error = ENOTDIR;
else
error = VOP_ACCESS(vp, VEXEC, p->p_ucred, p);
- VOP_UNLOCK(vp);
if (error)
- vrele(vp);
+ vput(vp);
+ else
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -837,7 +883,7 @@ sys_open(p, v, retval)
type = F_FLOCK;
if ((flags & FNONBLOCK) == 0)
type |= F_WAIT;
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
error = VOP_ADVLOCK(vp, (caddr_t)fp, F_SETLK, &lf, type);
if (error) {
(void) vn_close(vp, fp->f_flag, fp->f_cred, p);
@@ -845,10 +891,10 @@ sys_open(p, v, retval)
fdp->fd_ofiles[indx] = NULL;
return (error);
}
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
fp->f_flag |= FHASLOCK;
}
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
*retval = indx;
return (0);
}
@@ -1417,7 +1463,7 @@ sys_chflags(p, v, retval)
return (error);
vp = nd.ni_vp;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_mount->mnt_flag & MNT_RDONLY)
error = EROFS;
else {
@@ -1452,7 +1498,7 @@ sys_fchflags(p, v, retval)
return (error);
vp = (struct vnode *)fp->f_data;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_mount->mnt_flag & MNT_RDONLY)
error = EROFS;
else {
@@ -1460,7 +1506,7 @@ sys_fchflags(p, v, retval)
vattr.va_flags = SCARG(uap, flags);
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
}
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -1488,7 +1534,7 @@ sys_chmod(p, v, retval)
return (error);
vp = nd.ni_vp;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_mount->mnt_flag & MNT_RDONLY)
error = EROFS;
else {
@@ -1523,7 +1569,7 @@ sys_fchmod(p, v, retval)
return (error);
vp = (struct vnode *)fp->f_data;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_mount->mnt_flag & MNT_RDONLY)
error = EROFS;
else {
@@ -1531,7 +1577,7 @@ sys_fchmod(p, v, retval)
vattr.va_mode = SCARG(uap, mode) & ALLPERMS;
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
}
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -1561,7 +1607,7 @@ sys_chown(p, v, retval)
return (error);
vp = nd.ni_vp;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_mount->mnt_flag & MNT_RDONLY)
error = EROFS;
else {
@@ -1613,7 +1659,7 @@ sys_lchown(p, v, retval)
return (error);
vp = nd.ni_vp;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_mount->mnt_flag & MNT_RDONLY)
error = EROFS;
else {
@@ -1658,88 +1704,88 @@ sys_fchown(p, v, retval)
struct vattr vattr;
int error;
struct file *fp;
- u_short mode;
-
- if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
- return (error);
- vp = (struct vnode *)fp->f_data;
- VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- error = EROFS;
- else {
- if (suser(p->p_ucred, &p->p_acflag) ||
- suid_clear) {
- error = VOP_GETATTR(vp, &vattr, p->p_ucred, p);
- if (error)
- goto out;
- mode = vattr.va_mode & ~(VSUID | VSGID);
- if (mode == vattr.va_mode)
- mode = VNOVAL;
- }
- else
- mode = VNOVAL;
- VATTR_NULL(&vattr);
- vattr.va_uid = SCARG(uap, uid);
- vattr.va_gid = SCARG(uap, gid);
- vattr.va_mode = mode;
- error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
- }
+ u_short mode;
+
+ if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
+ return (error);
+ vp = (struct vnode *)fp->f_data;
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ error = EROFS;
+ else {
+ if (suser(p->p_ucred, &p->p_acflag) ||
+ suid_clear) {
+ error = VOP_GETATTR(vp, &vattr, p->p_ucred, p);
+ if (error)
+ goto out;
+ mode = vattr.va_mode & ~(VSUID | VSGID);
+ if (mode == vattr.va_mode)
+ mode = VNOVAL;
+ }
+ else
+ mode = VNOVAL;
+ VATTR_NULL(&vattr);
+ vattr.va_uid = SCARG(uap, uid);
+ vattr.va_gid = SCARG(uap, gid);
+ vattr.va_mode = mode;
+ error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+ }
out:
- VOP_UNLOCK(vp);
- return (error);
+ VOP_UNLOCK(vp, 0, p);
+ return (error);
}
-
/*
* Set the access and modification times given a path name.
*/
/* ARGSUSED */
int
sys_utimes(p, v, retval)
- struct proc *p;
- void *v;
- register_t *retval;
+ struct proc *p;
+ void *v;
+ register_t *retval;
{
- register struct sys_utimes_args /* {
- syscallarg(char *) path;
- syscallarg(struct timeval *) tptr;
- } */ *uap = v;
- register struct vnode *vp;
- struct timeval tv[2];
- struct vattr vattr;
- int error;
- struct nameidata nd;
-
- VATTR_NULL(&vattr);
- if (SCARG(uap, tptr) == NULL) {
- microtime(&tv[0]);
- tv[1] = tv[0];
- vattr.va_vaflags |= VA_UTIMES_NULL;
- } else {
- error = copyin((caddr_t)SCARG(uap, tptr), (caddr_t)tv,
- sizeof (tv));
- if (error)
- return (error);
- }
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
- if ((error = namei(&nd)) != 0)
- return (error);
- vp = nd.ni_vp;
- VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- error = EROFS;
- else {
- vattr.va_atime.tv_sec = tv[0].tv_sec;
- vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
- vattr.va_mtime.tv_sec = tv[1].tv_sec;
- vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;
- error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
- }
+ register struct sys_utimes_args /* {
+ syscallarg(char *) path;
+ syscallarg(struct timeval *) tptr;
+ } */ *uap = v;
+ register struct vnode *vp;
+ struct timeval tv[2];
+ struct vattr vattr;
+ int error;
+ struct nameidata nd;
+
+ VATTR_NULL(&vattr);
+ if (SCARG(uap, tptr) == NULL) {
+ microtime(&tv[0]);
+ tv[1] = tv[0];
+ vattr.va_vaflags |= VA_UTIMES_NULL;
+ } else {
+ error = copyin((caddr_t)SCARG(uap, tptr), (caddr_t)tv,
+ sizeof (tv));
+ if (error)
+ return (error);
+ }
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
+ if ((error = namei(&nd)) != 0)
+ return (error);
+ vp = nd.ni_vp;
+ VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
+ if (vp->v_mount->mnt_flag & MNT_RDONLY)
+ error = EROFS;
+ else {
+ vattr.va_atime.tv_sec = tv[0].tv_sec;
+ vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;
+ vattr.va_mtime.tv_sec = tv[1].tv_sec;
+ vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;
+ error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
+ }
vput(vp);
- return (error);
+ return (error);
}
+
/*
* Set the access and modification times given a file descriptor.
*/
@@ -1775,7 +1821,7 @@ sys_futimes(p, v, retval)
return (error);
vp = (struct vnode *)fp->f_data;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_mount->mnt_flag & MNT_RDONLY)
error = EROFS;
else {
@@ -1785,7 +1831,7 @@ sys_futimes(p, v, retval)
vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;
error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);
}
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -1814,7 +1860,7 @@ sys_truncate(p, v, retval)
return (error);
vp = nd.ni_vp;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_type == VDIR)
error = EISDIR;
else if ((error = vn_writechk(vp)) == 0 &&
@@ -1853,7 +1899,7 @@ sys_ftruncate(p, v, retval)
return (EINVAL);
vp = (struct vnode *)fp->f_data;
VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (vp->v_type == VDIR)
error = EISDIR;
else if ((error = vn_writechk(vp)) == 0) {
@@ -1861,7 +1907,7 @@ sys_ftruncate(p, v, retval)
vattr.va_size = SCARG(uap, length);
error = VOP_SETATTR(vp, &vattr, fp->f_cred, p);
}
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -1885,9 +1931,9 @@ sys_fsync(p, v, retval)
if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
return (error);
vp = (struct vnode *)fp->f_data;
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p);
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
return (error);
}
@@ -2108,11 +2154,11 @@ unionread:
auio.uio_segflg = UIO_USERSPACE;
auio.uio_procp = p;
auio.uio_resid = SCARG(uap, count);
- VOP_LOCK(vp);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
loff = auio.uio_offset = fp->f_offset;
- error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, (u_long *)0, 0);
+ error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, 0, 0);
fp->f_offset = auio.uio_offset;
- VOP_UNLOCK(vp);
+ VOP_UNLOCK(vp, 0, p);
if (error)
return (error);
if ((SCARG(uap, count) == auio.uio_resid) &&
@@ -2182,17 +2228,13 @@ sys_revoke(p, v, retval)
if ((error = namei(&nd)) != 0)
return (error);
vp = nd.ni_vp;
- if (vp->v_type != VCHR && vp->v_type != VBLK) {
- error = EINVAL;
- goto out;
- }
if ((error = VOP_GETATTR(vp, &vattr, p->p_ucred, p)) != 0)
goto out;
if (p->p_ucred->cr_uid != vattr.va_uid &&
(error = suser(p->p_ucred, &p->p_acflag)))
goto out;
if (vp->v_usecount > 1 || (vp->v_flag & VALIASED))
- vgoneall(vp);
+ VOP_REVOKE(vp, REVOKEALL);
out:
vrele(vp);
return (error);