git: 513c7a6e0cd8 - main - fd: make fget_unlocked take a thread argument
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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,