svn commit: r220400 - in head/sys: fs/fdescfs kern

Edward Tomasz Napierala trasz at FreeBSD.org
Wed Apr 6 19:13:04 UTC 2011


Author: trasz
Date: Wed Apr  6 19:13:04 2011
New Revision: 220400
URL: http://svn.freebsd.org/changeset/base/220400

Log:
  Add RACCT_NOFILE accounting.
  
  Sponsored by:	The FreeBSD Foundation
  Reviewed by:	kib (earlier version)

Modified:
  head/sys/fs/fdescfs/fdesc_vfsops.c
  head/sys/kern/kern_descrip.c

Modified: head/sys/fs/fdescfs/fdesc_vfsops.c
==============================================================================
--- head/sys/fs/fdescfs/fdesc_vfsops.c	Wed Apr  6 19:08:50 2011	(r220399)
+++ head/sys/fs/fdescfs/fdesc_vfsops.c	Wed Apr  6 19:13:04 2011	(r220400)
@@ -47,6 +47,7 @@
 #include <sys/malloc.h>
 #include <sys/mount.h>
 #include <sys/proc.h>
+#include <sys/racct.h>
 #include <sys/resourcevar.h>
 #include <sys/vnode.h>
 
@@ -186,6 +187,7 @@ fdesc_statfs(mp, sbp)
 	int i;
 	int last;
 	int freefd;
+	uint64_t limit;
 
 	td = curthread;
 
@@ -200,6 +202,9 @@ fdesc_statfs(mp, sbp)
 	PROC_UNLOCK(td->td_proc);
 	fdp = td->td_proc->p_fd;
 	FILEDESC_SLOCK(fdp);
+	limit = racct_get_limit(td->td_proc, RACCT_NOFILE);
+	if (lim > limit)
+		lim = limit;
 	last = min(fdp->fd_nfiles, lim);
 	freefd = 0;
 	for (i = fdp->fd_freefile; i < last; i++)

Modified: head/sys/kern/kern_descrip.c
==============================================================================
--- head/sys/kern/kern_descrip.c	Wed Apr  6 19:08:50 2011	(r220399)
+++ head/sys/kern/kern_descrip.c	Wed Apr  6 19:13:04 2011	(r220400)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/protosw.h>
+#include <sys/racct.h>
 #include <sys/resourcevar.h>
 #include <sys/signalvar.h>
 #include <sys/socketvar.h>
@@ -276,11 +277,15 @@ int
 getdtablesize(struct thread *td, struct getdtablesize_args *uap)
 {
 	struct proc *p = td->td_proc;
+	uint64_t lim;
 
 	PROC_LOCK(p);
 	td->td_retval[0] =
 	    min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
+	lim = racct_get_limit(td->td_proc, RACCT_NOFILE);
 	PROC_UNLOCK(p);
+	if (lim < td->td_retval[0])
+		td->td_retval[0] = lim;
 	return (0);
 }
 
@@ -793,8 +798,25 @@ do_dup(struct thread *td, int flags, int
 	 * out for a race.
 	 */
 	if (flags & DUP_FIXED) {
-		if (new >= fdp->fd_nfiles)
+		if (new >= fdp->fd_nfiles) {
+			/*
+			 * The resource limits are here instead of e.g. fdalloc(),
+			 * because the file descriptor table may be shared between
+			 * processes, so we can't really use racct_add()/racct_sub().
+			 * Instead of counting the number of actually allocated
+			 * descriptors, just put the limit on the size of the file
+			 * descriptor table.
+			 */
+			PROC_LOCK(p);
+			error = racct_set(p, RACCT_NOFILE, new + 1);
+			PROC_UNLOCK(p);
+			if (error != 0) {
+				FILEDESC_XUNLOCK(fdp);
+				fdrop(fp, td);
+				return (EMFILE);
+			}
 			fdgrowtable(fdp, new + 1);
+		}
 		if (fdp->fd_ofiles[new] == NULL)
 			fdused(fdp, new);
 	} else {
@@ -1440,7 +1462,7 @@ fdalloc(struct thread *td, int minfd, in
 {
 	struct proc *p = td->td_proc;
 	struct filedesc *fdp = p->p_fd;
-	int fd = -1, maxfd;
+	int fd = -1, maxfd, error;
 
 	FILEDESC_XLOCK_ASSERT(fdp);
 
@@ -1463,6 +1485,11 @@ fdalloc(struct thread *td, int minfd, in
 			return (EMFILE);
 		if (fd < fdp->fd_nfiles)
 			break;
+		PROC_LOCK(p);
+		error = racct_set(p, RACCT_NOFILE, min(fdp->fd_nfiles * 2, maxfd));
+		PROC_UNLOCK(p);
+		if (error != 0)
+			return (EMFILE);
 		fdgrowtable(fdp, min(fdp->fd_nfiles * 2, maxfd));
 	}
 
@@ -1494,6 +1521,11 @@ fdavail(struct thread *td, int n)
 
 	FILEDESC_LOCK_ASSERT(fdp);
 
+	/*
+	 * XXX: This is only called from uipc_usrreq.c:unp_externalize();
+	 *      call racct_add() from there instead of dealing with containers
+	 *      here.
+	 */
 	PROC_LOCK(p);
 	lim = min((int)lim_cur(p, RLIMIT_NOFILE), maxfilesperproc);
 	PROC_UNLOCK(p);
@@ -1742,6 +1774,10 @@ fdfree(struct thread *td)
 	if (fdp == NULL)
 		return;
 
+	PROC_LOCK(td->td_proc);
+	racct_set(td->td_proc, RACCT_NOFILE, 0);
+	PROC_UNLOCK(td->td_proc);
+
 	/* Check for special need to clear POSIX style locks */
 	fdtol = td->td_proc->p_fdtol;
 	if (fdtol != NULL) {


More information about the svn-src-all mailing list