git: e260058f33c9 - stable/14 - descriptors: add fget_remote_foreach()

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Mon, 07 Apr 2025 01:29:03 UTC
The branch stable/14 has been updated by kib:

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

commit e260058f33c93f9728879b7eaa893239bd4cf006
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-03-18 02:10:03 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-04-07 01:28:21 +0000

    descriptors: add fget_remote_foreach()
    
    (cherry picked from commit 4b69f1fab66db4fd3f874e78a457e317cd498d36)
---
 sys/kern/kern_descrip.c | 41 +++++++++++++++++++++++++++++++++++++++++
 sys/sys/file.h          |  2 ++
 2 files changed, 43 insertions(+)

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index c21e34f7e805..7fa03e002ad7 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -2995,6 +2995,47 @@ fget_remote(struct thread *td, struct proc *p, int fd, struct file **fpp)
 	return (error);
 }
 
+int
+fget_remote_foreach(struct thread *td, struct proc *p,
+    int (*fn)(struct proc *, int, struct file *, void *), void *arg)
+{
+	struct filedesc *fdp;
+	struct fdescenttbl *fdt;
+	struct file *fp;
+	int error, error1, fd, highfd;
+
+	error = 0;
+	PROC_LOCK(p);
+	fdp = fdhold(p);
+	PROC_UNLOCK(p);
+	if (fdp == NULL)
+		return (ENOENT);
+
+	FILEDESC_SLOCK(fdp);
+	if (refcount_load(&fdp->fd_refcnt) != 0) {
+		fdt = atomic_load_ptr(&fdp->fd_files);
+		highfd = fdt->fdt_nfiles - 1;
+		FILEDESC_SUNLOCK(fdp);
+	} else {
+		error = ENOENT;
+		FILEDESC_SUNLOCK(fdp);
+		goto out;
+	}
+
+	for (fd = 0; fd <= highfd; fd++) {
+		error1 = fget_remote(td, p, fd, &fp);
+		if (error1 != 0)
+			continue;
+		error = fn(p, fd, fp, arg);
+		fdrop(fp, td);
+		if (error != 0)
+			break;
+	}
+out:
+	fddrop(fdp);
+	return (error);
+}
+
 #ifdef CAPABILITIES
 int
 fgetvp_lookup_smr(struct nameidata *ndp, struct vnode **vpp, bool *fsearch)
diff --git a/sys/sys/file.h b/sys/sys/file.h
index da96f3e332fc..bef21d39e641 100644
--- a/sys/sys/file.h
+++ b/sys/sys/file.h
@@ -266,6 +266,8 @@ int fget_fcntl(struct thread *td, int fd, cap_rights_t *rightsp,
     int needfcntl, struct file **fpp);
 int _fdrop(struct file *fp, struct thread *td);
 int fget_remote(struct thread *td, struct proc *p, int fd, struct file **fpp);
+int fget_remote_foreach(struct thread *td, struct proc *p,
+    int (*fn)(struct proc *, int, struct file *, void *), void *arg);
 
 fo_rdwr_t	invfo_rdwr;
 fo_truncate_t	invfo_truncate;