aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2021-01-12 16:11:15 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2021-01-13 03:30:38 +0000
commit5171310e661d6c85f6208d86c6f651e3d499e346 (patch)
treef88f481732706847502f48862beb934a8ed884eb
parent530b699a62ad0f1e5718825d60ddb1ec9b214489 (diff)
downloadsrc-5171310e661d6c85f6208d86c6f651e3d499e346.tar.gz
src-5171310e661d6c85f6208d86c6f651e3d499e346.zip
vfs: use finstall_refed in openat
This avoids 2 atomic ops in the common case: 1 to grab an extra reference and 1 to release it.
-rw-r--r--sys/kern/vfs_syscalls.c16
1 files changed, 4 insertions, 12 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 560a003765d5..c1b6c70ab0ac 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1129,15 +1129,11 @@ kern_openat(struct thread *td, int fd, const char *path, enum uio_seg pathseg,
/*
* Allocate a file structure. The descriptor to reference it
- * is allocated and set by finstall() below.
+ * is allocated and used by finstall_refed() below.
*/
error = falloc_noinstall(td, &fp);
if (error != 0)
return (error);
- /*
- * An extra reference on `fp' has been held for us by
- * falloc_noinstall().
- */
/* Set the flags early so the finit in devfs can pick them up. */
fp->f_flag = flags & FMASK;
cmode = ((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT;
@@ -1210,21 +1206,17 @@ success:
else
#endif
fcaps = NULL;
- error = finstall(td, fp, &indx, flags, fcaps);
- /* On success finstall() consumes fcaps. */
+ error = finstall_refed(td, fp, &indx, flags, fcaps);
+ /* On success finstall_refed() consumes fcaps. */
if (error != 0) {
filecaps_free(&nd.ni_filecaps);
goto bad;
}
} else {
filecaps_free(&nd.ni_filecaps);
+ fdrop_close(fp, td);
}
- /*
- * Release our private reference, leaving the one associated with
- * the descriptor table intact.
- */
- fdrop(fp, td);
td->td_retval[0] = indx;
return (0);
bad: