git: 9c3e516ad081 - main - Add proc_nfiles(9)

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 27 Sep 2024 15:03:25 UTC
The branch main has been updated by kib:

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

commit 9c3e516ad08145ad47248633b54fd1b7fc0ef981
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-09-20 16:28:23 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-09-27 15:01:56 +0000

    Add proc_nfiles(9)
    
    which returns a snapshot of the count of the opened files in the
    process.
    
    Reviewed by:    markj, olce
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D46747
---
 sys/kern/kern_descrip.c | 44 +++++++++++++++++++++++++++++++++-----------
 sys/sys/filedesc.h      |  2 ++
 2 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index ef7aea82a609..09eeb158f1f5 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -4329,21 +4329,13 @@ filedesc_to_leader_share(struct filedesc_to_leader *fdtol, struct filedesc *fdp)
 }
 
 static int
-sysctl_kern_proc_nfds(SYSCTL_HANDLER_ARGS)
+filedesc_nfiles(struct filedesc *fdp)
 {
 	NDSLOTTYPE *map;
-	struct filedesc *fdp;
-	u_int namelen;
 	int count, off, minoff;
 
-	namelen = arg2;
-	if (namelen != 1)
-		return (EINVAL);
-
-	if (*(int *)arg1 != 0)
-		return (EINVAL);
-
-	fdp = curproc->p_fd;
+	if (fdp == NULL)
+		return (0);
 	count = 0;
 	FILEDESC_SLOCK(fdp);
 	map = fdp->fd_map;
@@ -4351,7 +4343,37 @@ sysctl_kern_proc_nfds(SYSCTL_HANDLER_ARGS)
 	for (minoff = NDSLOT(0); off >= minoff; --off)
 		count += bitcountl(map[off]);
 	FILEDESC_SUNLOCK(fdp);
+	return (count);
+}
+
+int
+proc_nfiles(struct proc *p)
+{
+	struct filedesc *fdp;
+	int res;
+
+	PROC_LOCK(p);
+	fdp = fdhold(p);
+	PROC_UNLOCK(p);
+	res = filedesc_nfiles(fdp);
+	fddrop(fdp);
+	return (res);
+}
+
+static int
+sysctl_kern_proc_nfds(SYSCTL_HANDLER_ARGS)
+{
+	u_int namelen;
+	int count;
+
+	namelen = arg2;
+	if (namelen != 1)
+		return (EINVAL);
+
+	if (*(int *)arg1 != 0)
+		return (EINVAL);
 
+	count = filedesc_nfiles(curproc->p_fd);
 	return (SYSCTL_OUT(req, &count, sizeof(count)));
 }
 
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index 53034acb1b54..242f5b8831fd 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -335,6 +335,8 @@ fd_modified(struct filedesc *fdp, int fd, seqc_t seqc)
 }
 #endif
 
+int	proc_nfiles(struct proc *p);
+
 /* cdir/rdir/jdir manipulation functions. */
 struct pwddesc *pdcopy(struct pwddesc *pdp);
 void	pdescfree(struct thread *td);