Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Jan 2021 15:33:23 GMT
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 5753be8e432f - main - fd: add refcount argument to falloc_noinstall
Message-ID:  <202101131533.10DFXN1x064582@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=5753be8e432f26b02c0bd06d7dd84316ddc50ed5

commit 5753be8e432f26b02c0bd06d7dd84316ddc50ed5
Author:     Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2021-01-13 14:16:38 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2021-01-13 15:29:34 +0000

    fd: add refcount argument to falloc_noinstall
    
    This lets callers avoid atomic ops by initializing the count to required
    value from the get go.
    
    While here add falloc_abort to backpedal from this without having to
    fdrop.
---
 sys/kern/kern_descrip.c | 29 +++++++++++++++++++++--------
 sys/kern/vfs_syscalls.c |  4 ++--
 sys/sys/filedesc.h      |  4 +++-
 3 files changed, 26 insertions(+), 11 deletions(-)

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 407280d79850..257b1de2a6ac 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1979,13 +1979,14 @@ falloc_caps(struct thread *td, struct file **resultfp, int *resultfd, int flags,
 	MPASS(resultfp != NULL);
 	MPASS(resultfd != NULL);
 
-	error = falloc_noinstall(td, &fp);
-	if (error)
-		return (error);		/* no reference held on error */
+	error = _falloc_noinstall(td, &fp, 2);
+	if (__predict_false(error != 0)) {
+		return (error);
+	}
 
-	error = finstall(td, fp, &fd, flags, fcaps);
-	if (error) {
-		fdrop(fp, td);		/* one reference (fp only) */
+	error = finstall_refed(td, fp, &fd, flags, fcaps);
+	if (__predict_false(error != 0)) {
+		falloc_abort(td, fp);
 		return (error);
 	}
 
@@ -1999,7 +2000,7 @@ falloc_caps(struct thread *td, struct file **resultfp, int *resultfd, int flags,
  * Create a new open file structure without allocating a file descriptor.
  */
 int
-falloc_noinstall(struct thread *td, struct file **resultfp)
+_falloc_noinstall(struct thread *td, struct file **resultfp, u_int n)
 {
 	struct file *fp;
 	int maxuserfiles = maxfiles - (maxfiles / 20);
@@ -2008,6 +2009,7 @@ falloc_noinstall(struct thread *td, struct file **resultfp)
 	static int curfail;
 
 	KASSERT(resultfp != NULL, ("%s: resultfp == NULL", __func__));
+	MPASS(n > 0);
 
 	openfiles_new = atomic_fetchadd_int(&openfiles, 1) + 1;
 	if ((openfiles_new >= maxuserfiles &&
@@ -2022,13 +2024,24 @@ falloc_noinstall(struct thread *td, struct file **resultfp)
 	}
 	fp = uma_zalloc(file_zone, M_WAITOK);
 	bzero(fp, sizeof(*fp));
-	refcount_init(&fp->f_count, 1);
+	refcount_init(&fp->f_count, n);
 	fp->f_cred = crhold(td->td_ucred);
 	fp->f_ops = &badfileops;
 	*resultfp = fp;
 	return (0);
 }
 
+void
+falloc_abort(struct thread *td, struct file *fp)
+{
+
+	/*
+	 * For assertion purposes.
+	 */
+	refcount_init(&fp->f_count, 0);
+	_fdrop(fp, td);
+}
+
 /*
  * Install a file in a file descriptor table.
  */
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index c1b6c70ab0ac..35a56510e9ef 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1214,14 +1214,14 @@ success:
 		}
 	} else {
 		filecaps_free(&nd.ni_filecaps);
-		fdrop_close(fp, td);
+		falloc_abort(td, fp);
 	}
 
 	td->td_retval[0] = indx;
 	return (0);
 bad:
 	KASSERT(indx == -1, ("indx=%d, should be -1", indx));
-	fdrop_close(fp, td);
+	falloc_abort(td, fp);
 	return (error);
 }
 
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index f0cae3ed6911..9b65c7a66054 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -229,7 +229,9 @@ int	dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
 	    int openerror, int *indxp);
 int	falloc_caps(struct thread *td, struct file **resultfp, int *resultfd,
 	    int flags, struct filecaps *fcaps);
-int	falloc_noinstall(struct thread *td, struct file **resultfp);
+void	falloc_abort(struct thread *td, struct file *fp);
+int	_falloc_noinstall(struct thread *td, struct file **resultfp, u_int n);
+#define	falloc_noinstall(td, resultfp) _falloc_noinstall(td, resultfp, 1)
 void	_finstall(struct filedesc *fdp, struct file *fp, int fd, int flags,
 	    struct filecaps *fcaps);
 int	finstall(struct thread *td, struct file *fp, int *resultfd, int flags,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101131533.10DFXN1x064582>