git: 513c7a6e0cd8 - main - fd: make fget_unlocked take a thread argument

From: Mateusz Guzik <mjg_at_FreeBSD.org>
Date: Fri, 11 Feb 2022 13:58:06 UTC
The branch main has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=513c7a6e0cd8c13f765fda6fa1b2de53c1973753

commit 513c7a6e0cd8c13f765fda6fa1b2de53c1973753
Author:     Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2022-02-11 12:02:02 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2022-02-11 12:29:26 +0000

    fd: make fget_unlocked take a thread argument
    
    Just like other fget routines. This enables embedding fd table pointer
    in struct thread, avoiding taking a trip through proc.
---
 sys/compat/linux/linux.c                        |  5 +--
 sys/compat/linuxkpi/common/include/linux/file.h |  9 ++---
 sys/kern/kern_descrip.c                         | 54 +++++++++++++------------
 sys/kern/sys_generic.c                          |  8 ++--
 sys/kern/vfs_syscalls.c                         |  2 +-
 sys/sys/filedesc.h                              |  2 +-
 6 files changed, 38 insertions(+), 42 deletions(-)

diff --git a/sys/compat/linux/linux.c b/sys/compat/linux/linux.c
index 8cc678e1ec7d..81ceb964662f 100644
--- a/sys/compat/linux/linux.c
+++ b/sys/compat/linux/linux.c
@@ -633,8 +633,6 @@ void
 linux_to_bsd_poll_events(struct thread *td, int fd, short lev,
     short *bev)
 {
-	struct proc *p = td->td_proc;
-	struct filedesc *fdp;
 	struct file *fp;
 	int error;
 	short bits = 0;
@@ -666,8 +664,7 @@ linux_to_bsd_poll_events(struct thread *td, int fd, short lev,
 		 * on non-socket file descriptors unlike FreeBSD, where
 		 * events bits is more strictly checked (POLLSTANDARD).
 		 */
-		fdp = p->p_fd;
-		error = fget_unlocked(fdp, fd, &cap_no_rights, &fp);
+		error = fget_unlocked(td, fd, &cap_no_rights, &fp);
 		if (error == 0) {
 			/*
 			 * XXX. On FreeBSD POLLRDHUP applies only to
diff --git a/sys/compat/linuxkpi/common/include/linux/file.h b/sys/compat/linuxkpi/common/include/linux/file.h
index 43027979061e..32db72d771fc 100644
--- a/sys/compat/linuxkpi/common/include/linux/file.h
+++ b/sys/compat/linuxkpi/common/include/linux/file.h
@@ -53,8 +53,7 @@ linux_fget(unsigned int fd)
 	struct file *file;
 
 	/* lookup file pointer by file descriptor index */
-	if (fget_unlocked(curthread->td_proc->p_fd, fd,
-	    &cap_no_rights, &file) != 0)
+	if (fget_unlocked(curthread, fd, &cap_no_rights, &file) != 0)
 		return (NULL);
 
 	/* check if file handle really belongs to us */
@@ -89,8 +88,7 @@ put_unused_fd(unsigned int fd)
 {
 	struct file *file;
 
-	if (fget_unlocked(curthread->td_proc->p_fd, fd,
-	    &cap_no_rights, &file) != 0) {
+	if (fget_unlocked(curthread, fd, &cap_no_rights, &file) != 0) {
 		return;
 	}
 	/*
@@ -109,8 +107,7 @@ fd_install(unsigned int fd, struct linux_file *filp)
 {
 	struct file *file;
 
-	if (fget_unlocked(curthread->td_proc->p_fd, fd,
-	    &cap_no_rights, &file) != 0) {
+	if (fget_unlocked(curthread, fd, &cap_no_rights, &file) != 0) {
 		filp->_file = NULL;
 	} else {
 		filp->_file = file;
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index e5ffdb01255f..0f640f395ba4 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -115,7 +115,7 @@ static void	fdgrowtable(struct filedesc *fdp, int nfd);
 static void	fdgrowtable_exp(struct filedesc *fdp, int nfd);
 static void	fdunused(struct filedesc *fdp, int fd);
 static void	fdused(struct filedesc *fdp, int fd);
-static int	fget_unlocked_seq(struct filedesc *fdp, int fd,
+static int	fget_unlocked_seq(struct thread *td, int fd,
 		    cap_rights_t *needrightsp, struct file **fpp, seqc_t *seqp);
 static int	getmaxfd(struct thread *td);
 static u_long	*filecaps_copy_prep(const struct filecaps *src);
@@ -617,7 +617,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 			break;
 		}
 
-		error = fget_unlocked(fdp, fd, &cap_flock_rights, &fp);
+		error = fget_unlocked(td, fd, &cap_flock_rights, &fp);
 		if (error != 0)
 			break;
 		if (fp->f_type != DTYPE_VNODE || fp->f_ops == &path_fileops) {
@@ -704,7 +704,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 		 * that the closing thread was a bit slower and that the
 		 * advisory lock succeeded before the close.
 		 */
-		error = fget_unlocked(fdp, fd, &cap_no_rights, &fp2);
+		error = fget_unlocked(td, fd, &cap_no_rights, &fp2);
 		if (error != 0) {
 			fdrop(fp, td);
 			break;
@@ -722,7 +722,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 		break;
 
 	case F_GETLK:
-		error = fget_unlocked(fdp, fd, &cap_flock_rights, &fp);
+		error = fget_unlocked(td, fd, &cap_flock_rights, &fp);
 		if (error != 0)
 			break;
 		if (fp->f_type != DTYPE_VNODE || fp->f_ops == &path_fileops) {
@@ -756,7 +756,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 		break;
 
 	case F_ADD_SEALS:
-		error = fget_unlocked(fdp, fd, &cap_no_rights, &fp);
+		error = fget_unlocked(td, fd, &cap_no_rights, &fp);
 		if (error != 0)
 			break;
 		error = fo_add_seals(fp, arg);
@@ -764,7 +764,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 		break;
 
 	case F_GET_SEALS:
-		error = fget_unlocked(fdp, fd, &cap_no_rights, &fp);
+		error = fget_unlocked(td, fd, &cap_no_rights, &fp);
 		if (error != 0)
 			break;
 		if (fo_get_seals(fp, &seals) == 0)
@@ -778,7 +778,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 		arg = arg ? 128 * 1024: 0;
 		/* FALLTHROUGH */
 	case F_READAHEAD:
-		error = fget_unlocked(fdp, fd, &cap_no_rights, &fp);
+		error = fget_unlocked(td, fd, &cap_no_rights, &fp);
 		if (error != 0)
 			break;
 		if (fp->f_type != DTYPE_VNODE || fp->f_ops == &path_fileops) {
@@ -829,7 +829,7 @@ kern_fcntl(struct thread *td, int fd, int cmd, intptr_t arg)
 		 * horrible kludge facilitates the current behavior in a much
 		 * cheaper manner until someone(tm) sorts this out.
 		 */
-		error = fget_unlocked(fdp, fd, &cap_no_rights, &fp);
+		error = fget_unlocked(td, fd, &cap_no_rights, &fp);
 		if (error != 0)
 			break;
 		if (fp->f_type != DTYPE_VNODE) {
@@ -2880,7 +2880,7 @@ fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp,
 
 	*fpp = NULL;
 	for (;;) {
-		error = fget_unlocked_seq(fdp, fd, needrightsp, &fp, &seq);
+		error = fget_unlocked_seq(td, fd, needrightsp, &fp, &seq);
 		if (error != 0)
 			return (error);
 
@@ -2913,10 +2913,8 @@ int
 fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp,
     struct file **fpp, struct filecaps *havecapsp)
 {
-	struct filedesc *fdp = td->td_proc->p_fd;
 	int error;
-
-	error = fget_unlocked(fdp, fd, needrightsp, fpp);
+	error = fget_unlocked(td, fd, needrightsp, fpp);
 	if (havecapsp != NULL && error == 0)
 		filecaps_fill(havecapsp);
 
@@ -3041,9 +3039,10 @@ fgetvp_lookup_smr(int fd, struct nameidata *ndp, struct vnode **vpp, bool *fsear
  */
 #ifdef CAPABILITIES
 static int
-fget_unlocked_seq(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+fget_unlocked_seq(struct thread *td, int fd, cap_rights_t *needrightsp,
     struct file **fpp, seqc_t *seqp)
 {
+	struct filedesc *fdp;
 	const struct filedescent *fde;
 	const struct fdescenttbl *fdt;
 	struct file *fp;
@@ -3051,6 +3050,7 @@ fget_unlocked_seq(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
 	cap_rights_t haverights;
 	int error;
 
+	fdp = td->td_proc->p_fd;
 	fdt = fdp->fd_files;
 	if (__predict_false((u_int)fd >= fdt->fdt_nfiles))
 		return (EBADF);
@@ -3085,7 +3085,7 @@ fget_unlocked_seq(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
 		fdt = fdp->fd_files;
 		if (seqc_consistent_nomb(fd_seqc(fdt, fd), seq))
 			break;
-		fdrop(fp, curthread);
+		fdrop(fp, td);
 	}
 	*fpp = fp;
 	if (seqp != NULL) {
@@ -3095,12 +3095,14 @@ fget_unlocked_seq(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
 }
 #else
 static int
-fget_unlocked_seq(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+fget_unlocked_seq(struct thread *td, int fd, cap_rights_t *needrightsp,
     struct file **fpp, seqc_t *seqp __unused)
 {
+	struct filedesc *fdp;
 	const struct fdescenttbl *fdt;
 	struct file *fp;
 
+	fdp = td->td_proc->p_fd;
 	fdt = fdp->fd_files;
 	if (__predict_false((u_int)fd >= fdt->fdt_nfiles))
 		return (EBADF);
@@ -3121,7 +3123,7 @@ fget_unlocked_seq(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
 		fdt = fdp->fd_files;
 		if (__predict_true(fp == fdt->fdt_ofiles[fd].fde_file))
 			break;
-		fdrop(fp, curthread);
+		fdrop(fp, td);
 	}
 	*fpp = fp;
 	return (0);
@@ -3136,9 +3138,10 @@ fget_unlocked_seq(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
  * racing with itself.
  */
 int
-fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+fget_unlocked(struct thread *td, int fd, cap_rights_t *needrightsp,
     struct file **fpp)
 {
+	struct filedesc *fdp;
 #ifdef CAPABILITIES
 	const struct filedescent *fde;
 #endif
@@ -3149,6 +3152,7 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
 	const cap_rights_t *haverights;
 #endif
 
+	fdp = td->td_proc->p_fd;
 	fdt = fdp->fd_files;
 	if (__predict_false((u_int)fd >= fdt->fdt_nfiles)) {
 		*fpp = NULL;
@@ -3186,10 +3190,10 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
 	*fpp = fp;
 	return (0);
 out_fdrop:
-	fdrop(fp, curthread);
+	fdrop(fp, td);
 out_fallback:
 	*fpp = NULL;
-	return (fget_unlocked_seq(fdp, fd, needrightsp, fpp, NULL));
+	return (fget_unlocked_seq(td, fd, needrightsp, fpp, NULL));
 }
 
 /*
@@ -3271,13 +3275,11 @@ static __inline int
 _fget(struct thread *td, int fd, struct file **fpp, int flags,
     cap_rights_t *needrightsp)
 {
-	struct filedesc *fdp;
 	struct file *fp;
 	int error;
 
 	*fpp = NULL;
-	fdp = td->td_proc->p_fd;
-	error = fget_unlocked(fdp, fd, needrightsp, &fp);
+	error = fget_unlocked(td, fd, needrightsp, &fp);
 	if (__predict_false(error != 0))
 		return (error);
 	if (__predict_false(fp->f_ops == &badfileops)) {
@@ -3343,7 +3345,7 @@ fget_mmap(struct thread *td, int fd, cap_rights_t *rightsp, vm_prot_t *maxprotp,
 	fdp = td->td_proc->p_fd;
 	MPASS(cap_rights_is_set(rightsp, CAP_MMAP));
 	for (;;) {
-		error = fget_unlocked_seq(fdp, fd, rightsp, &fp, &seq);
+		error = fget_unlocked_seq(td, fd, rightsp, &fp, &seq);
 		if (__predict_false(error != 0))
 			return (error);
 		if (__predict_false(fp->f_ops == &badfileops)) {
@@ -3385,10 +3387,10 @@ int
 fget_fcntl(struct thread *td, int fd, cap_rights_t *rightsp, int needfcntl,
     struct file **fpp)
 {
-	struct filedesc *fdp = td->td_proc->p_fd;
 #ifndef CAPABILITIES
-	return (fget_unlocked(fdp, fd, rightsp, fpp));
+	return (fget_unlocked(td, fd, rightsp, fpp));
 #else
+	struct filedesc *fdp = td->td_proc->p_fd;
 	struct file *fp;
 	int error;
 	seqc_t seq;
@@ -3396,7 +3398,7 @@ fget_fcntl(struct thread *td, int fd, cap_rights_t *rightsp, int needfcntl,
 	*fpp = NULL;
 	MPASS(cap_rights_is_set(rightsp, CAP_FCNTL));
 	for (;;) {
-		error = fget_unlocked_seq(fdp, fd, rightsp, &fp, &seq);
+		error = fget_unlocked_seq(td, fd, rightsp, &fp, &seq);
 		if (error != 0)
 			return (error);
 		error = cap_fcntl_check(fdp, fd, needfcntl);
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 41e9c556f73f..276dd4acd26d 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1406,7 +1406,7 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits)
 		if (only_user)
 			error = fget_only_user(fdp, fd, &cap_event_rights, &fp);
 		else
-			error = fget_unlocked(fdp, fd, &cap_event_rights, &fp);
+			error = fget_unlocked(td, fd, &cap_event_rights, &fp);
 		if (__predict_false(error != 0))
 			return (error);
 		idx = fd / NFDBITS;
@@ -1452,7 +1452,7 @@ selscan(struct thread *td, fd_mask **ibits, fd_mask **obits, int nfd)
 			if (only_user)
 				error = fget_only_user(fdp, fd, &cap_event_rights, &fp);
 			else
-				error = fget_unlocked(fdp, fd, &cap_event_rights, &fp);
+				error = fget_unlocked(td, fd, &cap_event_rights, &fp);
 			if (__predict_false(error != 0))
 				return (error);
 			selfdalloc(td, (void *)(uintptr_t)fd);
@@ -1659,7 +1659,7 @@ pollrescan(struct thread *td)
 		if (only_user)
 			error = fget_only_user(fdp, fd->fd, &cap_event_rights, &fp);
 		else
-			error = fget_unlocked(fdp, fd->fd, &cap_event_rights, &fp);
+			error = fget_unlocked(td, fd->fd, &cap_event_rights, &fp);
 		if (__predict_false(error != 0)) {
 			fd->revents = POLLNVAL;
 			n++;
@@ -1722,7 +1722,7 @@ pollscan(struct thread *td, struct pollfd *fds, u_int nfd)
 		if (only_user)
 			error = fget_only_user(fdp, fds->fd, &cap_event_rights, &fp);
 		else
-			error = fget_unlocked(fdp, fds->fd, &cap_event_rights, &fp);
+			error = fget_unlocked(td, fds->fd, &cap_event_rights, &fp);
 		if (__predict_false(error != 0)) {
 			fds->revents = POLLNVAL;
 			n++;
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 5549cae570f8..19e06732a9d0 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -4318,7 +4318,7 @@ getvnode_path(struct thread *td, int fd, cap_rights_t *rightsp,
 	struct file *fp;
 	int error;
 
-	error = fget_unlocked(td->td_proc->p_fd, fd, rightsp, &fp);
+	error = fget_unlocked(td, fd, rightsp, &fp);
 	if (error != 0)
 		return (error);
 
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index f003c0ff3c4b..426f0ef9ab75 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -270,7 +270,7 @@ int	fget_cap_locked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
 int	fget_cap(struct thread *td, int fd, cap_rights_t *needrightsp,
 	    struct file **fpp, struct filecaps *havecapsp);
 /* Return a referenced file from an unlocked descriptor. */
-int	fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
+int	fget_unlocked(struct thread *td, int fd, cap_rights_t *needrightsp,
 	    struct file **fpp);
 /* Return a file pointer without a ref. FILEDESC_IS_ONLY_USER must be true.  */
 int	fget_only_user(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,