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