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) {
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to