summaryrefslogtreecommitdiff
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2021-02-11 12:08:22 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2021-02-11 12:08:22 +0000
commitf6082ed8ab6399e6b33c8b468176bca55cfaf36e (patch)
tree3acb31eb3f99b11611afc344790c78993e9d30f8 /sys/kern/vfs_syscalls.c
parent6f6dc611d58d14115e5d81974850c24899a94980 (diff)
In the various open functions reduce the fdplock() to only span over the
function which need the lock (falloc, fdinsert, fdremove). In most cases it is not correct to hold the lock while calling VFS functions or e.g. closef since those aquire or release long lived VFS locks. OK visa@ mvs@
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 3bab69b15ac..840ea5453e1 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.348 2020/10/02 15:45:22 deraadt Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.349 2021/02/11 12:08:21 claudio Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -1104,8 +1104,10 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
cloexec = (oflags & O_CLOEXEC) ? UF_EXCLOSE : 0;
fdplock(fdp);
- if ((error = falloc(p, &fp, &indx)) != 0)
- goto out;
+ if ((error = falloc(p, &fp, &indx)) != 0) {
+ fdpunlock(fdp);
+ return (error);
+ }
fdpunlock(fdp);
flags = FFLAGS(oflags);
@@ -1139,15 +1141,17 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
p->p_dupfd >= 0 && /* XXX from fdopen */
(error =
dupfdopen(p, indx, flags)) == 0) {
+ fdpunlock(fdp);
closef(fp, p);
*retval = indx;
- goto out;
+ return (error);
}
if (error == ERESTART)
error = EINTR;
fdremove(fdp, indx);
+ fdpunlock(fdp);
closef(fp, p);
- goto out;
+ return (error);
}
p->p_dupfd = 0;
vp = nd.ni_vp;
@@ -1172,8 +1176,9 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
fdplock(fdp);
/* closef will vn_close the file for us. */
fdremove(fdp, indx);
+ fdpunlock(fdp);
closef(fp, p);
- goto out;
+ return (error);
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
atomic_setbits_int(&fp->f_iflags, FIF_HASLOCK);
@@ -1195,17 +1200,17 @@ doopenat(struct proc *p, int fd, const char *path, int oflags, mode_t mode,
fdplock(fdp);
/* closef will close the file for us. */
fdremove(fdp, indx);
+ fdpunlock(fdp);
closef(fp, p);
- goto out;
+ return (error);
}
}
VOP_UNLOCK(vp);
*retval = indx;
fdplock(fdp);
fdinsert(fdp, indx, cloexec, fp);
- FRELE(fp, p);
-out:
fdpunlock(fdp);
+ FRELE(fp, p);
return (error);
}
@@ -1235,8 +1240,10 @@ sys___tmpfd(struct proc *p, void *v, register_t *retval)
cloexec = (oflags & O_CLOEXEC) ? UF_EXCLOSE : 0;
fdplock(fdp);
- if ((error = falloc(p, &fp, &indx)) != 0)
- goto out;
+ if ((error = falloc(p, &fp, &indx)) != 0) {
+ fdpunlock(fdp);
+ return (error);
+ }
fdpunlock(fdp);
flags = FFLAGS(oflags);
@@ -1250,12 +1257,13 @@ sys___tmpfd(struct proc *p, void *v, register_t *retval)
cmode = 0600;
NDINITAT(&nd, 0, KERNELPATH, UIO_SYSSPACE, AT_FDCWD, path, p);
if ((error = vn_open(&nd, flags, cmode)) != 0) {
- fdplock(fdp);
if (error == ERESTART)
error = EINTR;
+ fdplock(fdp);
fdremove(fdp, indx);
+ fdpunlock(fdp);
closef(fp, p);
- goto out;
+ return (error);
}
vp = nd.ni_vp;
fp->f_flag = flags & FMASK;
@@ -1266,6 +1274,7 @@ sys___tmpfd(struct proc *p, void *v, register_t *retval)
*retval = indx;
fdplock(fdp);
fdinsert(fdp, indx, cloexec, fp);
+ fdpunlock(fdp);
FRELE(fp, p);
/* unlink it */
@@ -1288,8 +1297,6 @@ sys___tmpfd(struct proc *p, void *v, register_t *retval)
}
}
-out:
- fdpunlock(fdp);
return (error);
}
@@ -1370,9 +1377,11 @@ sys_fhopen(struct proc *p, void *v, register_t *retval)
fdplock(fdp);
if ((error = falloc(p, &fp, &indx)) != 0) {
+ fdpunlock(fdp);
fp = NULL;
goto bad;
}
+ fdpunlock(fdp);
if ((error = copyin(SCARG(uap, fhp), &fh, sizeof(fhandle_t))) != 0)
goto bad;
@@ -1449,6 +1458,7 @@ sys_fhopen(struct proc *p, void *v, register_t *retval)
}
VOP_UNLOCK(vp);
*retval = indx;
+ fdplock(fdp);
fdinsert(fdp, indx, cloexec, fp);
fdpunlock(fdp);
FRELE(fp, p);
@@ -1456,12 +1466,13 @@ sys_fhopen(struct proc *p, void *v, register_t *retval)
bad:
if (fp) {
+ fdplock(fdp);
fdremove(fdp, indx);
+ fdpunlock(fdp);
closef(fp, p);
if (vp != NULL)
vput(vp);
}
- fdpunlock(fdp);
return (error);
}