The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kernel/acct.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  *  linux/kernel/acct.c
    3  *
    4  *  BSD Process Accounting for Linux
    5  *
    6  *  Author: Marco van Wieringen <mvw@planets.elm.net>
    7  *
    8  *  Some code based on ideas and code from:
    9  *  Thomas K. Dyas <tdyas@eden.rutgers.edu>
   10  *
   11  *  This file implements BSD-style process accounting. Whenever any
   12  *  process exits, an accounting record of type "struct acct" is
   13  *  written to the file specified with the acct() system call. It is
   14  *  up to user-level programs to do useful things with the accounting
   15  *  log. The kernel just provides the raw accounting information.
   16  *
   17  * (C) Copyright 1995 - 1997 Marco van Wieringen - ELM Consultancy B.V.
   18  *
   19  *  Plugged two leaks. 1) It didn't return acct_file into the free_filps if
   20  *  the file happened to be read-only. 2) If the accounting was suspended
   21  *  due to the lack of space it happily allowed to reopen it and completely
   22  *  lost the old acct_file. 3/10/98, Al Viro.
   23  *
   24  *  Now we silently close acct_file on attempt to reopen. Cleaned sys_acct().
   25  *  XTerms and EMACS are manifestations of pure evil. 21/10/98, AV.
   26  *
   27  *  Fixed a nasty interaction with with sys_umount(). If the accointing
   28  *  was suspeneded we failed to stop it on umount(). Messy.
   29  *  Another one: remount to readonly didn't stop accounting.
   30  *      Question: what should we do if we have CAP_SYS_ADMIN but not
   31  *  CAP_SYS_PACCT? Current code does the following: umount returns -EBUSY
   32  *  unless we are messing with the root. In that case we are getting a
   33  *  real mess with do_remount_sb(). 9/11/98, AV.
   34  *
   35  *  Fixed a bunch of races (and pair of leaks). Probably not the best way,
   36  *  but this one obviously doesn't introduce deadlocks. Later. BTW, found
   37  *  one race (and leak) in BSD implementation.
   38  *  OK, that's better. ANOTHER race and leak in BSD variant. There always
   39  *  is one more bug... 10/11/98, AV.
   40  *
   41  *      Oh, fsck... Oopsable SMP race in do_process_acct() - we must hold
   42  * ->mmap_sem to walk the vma list of current->mm. Nasty, since it leaks
   43  * a struct file opened for write. Fixed. 2/6/2000, AV.
   44  */
   45 
   46 #include <linux/mm.h>
   47 #include <linux/slab.h>
   48 #include <linux/acct.h>
   49 #include <linux/capability.h>
   50 #include <linux/file.h>
   51 #include <linux/tty.h>
   52 #include <linux/security.h>
   53 #include <linux/vfs.h>
   54 #include <linux/jiffies.h>
   55 #include <linux/times.h>
   56 #include <linux/syscalls.h>
   57 #include <linux/mount.h>
   58 #include <asm/uaccess.h>
   59 #include <asm/div64.h>
   60 #include <linux/blkdev.h> /* sector_div */
   61 #include <linux/pid_namespace.h>
   62 
   63 /*
   64  * These constants control the amount of freespace that suspend and
   65  * resume the process accounting system, and the time delay between
   66  * each check.
   67  * Turned into sysctl-controllable parameters. AV, 12/11/98
   68  */
   69 
   70 int acct_parm[3] = {4, 2, 30};
   71 #define RESUME          (acct_parm[0])  /* >foo% free space - resume */
   72 #define SUSPEND         (acct_parm[1])  /* <foo% free space - suspend */
   73 #define ACCT_TIMEOUT    (acct_parm[2])  /* foo second timeout between checks */
   74 
   75 /*
   76  * External references and all of the globals.
   77  */
   78 static void do_acct_process(struct bsd_acct_struct *acct,
   79                 struct pid_namespace *ns, struct file *);
   80 
   81 /*
   82  * This structure is used so that all the data protected by lock
   83  * can be placed in the same cache line as the lock.  This primes
   84  * the cache line to have the data after getting the lock.
   85  */
   86 struct bsd_acct_struct {
   87         int                     active;
   88         unsigned long           needcheck;
   89         struct file             *file;
   90         struct pid_namespace    *ns;
   91         struct list_head        list;
   92 };
   93 
   94 static DEFINE_SPINLOCK(acct_lock);
   95 static LIST_HEAD(acct_list);
   96 
   97 /*
   98  * Check the amount of free space and suspend/resume accordingly.
   99  */
  100 static int check_free_space(struct bsd_acct_struct *acct, struct file *file)
  101 {
  102         struct kstatfs sbuf;
  103         int res;
  104         int act;
  105         u64 resume;
  106         u64 suspend;
  107 
  108         spin_lock(&acct_lock);
  109         res = acct->active;
  110         if (!file || time_is_before_jiffies(acct->needcheck))
  111                 goto out;
  112         spin_unlock(&acct_lock);
  113 
  114         /* May block */
  115         if (vfs_statfs(&file->f_path, &sbuf))
  116                 return res;
  117         suspend = sbuf.f_blocks * SUSPEND;
  118         resume = sbuf.f_blocks * RESUME;
  119 
  120         do_div(suspend, 100);
  121         do_div(resume, 100);
  122 
  123         if (sbuf.f_bavail <= suspend)
  124                 act = -1;
  125         else if (sbuf.f_bavail >= resume)
  126                 act = 1;
  127         else
  128                 act = 0;
  129 
  130         /*
  131          * If some joker switched acct->file under us we'ld better be
  132          * silent and _not_ touch anything.
  133          */
  134         spin_lock(&acct_lock);
  135         if (file != acct->file) {
  136                 if (act)
  137                         res = act>0;
  138                 goto out;
  139         }
  140 
  141         if (acct->active) {
  142                 if (act < 0) {
  143                         acct->active = 0;
  144                         printk(KERN_INFO "Process accounting paused\n");
  145                 }
  146         } else {
  147                 if (act > 0) {
  148                         acct->active = 1;
  149                         printk(KERN_INFO "Process accounting resumed\n");
  150                 }
  151         }
  152 
  153         acct->needcheck = jiffies + ACCT_TIMEOUT*HZ;
  154         res = acct->active;
  155 out:
  156         spin_unlock(&acct_lock);
  157         return res;
  158 }
  159 
  160 /*
  161  * Close the old accounting file (if currently open) and then replace
  162  * it with file (if non-NULL).
  163  *
  164  * NOTE: acct_lock MUST be held on entry and exit.
  165  */
  166 static void acct_file_reopen(struct bsd_acct_struct *acct, struct file *file,
  167                 struct pid_namespace *ns)
  168 {
  169         struct file *old_acct = NULL;
  170         struct pid_namespace *old_ns = NULL;
  171 
  172         if (acct->file) {
  173                 old_acct = acct->file;
  174                 old_ns = acct->ns;
  175                 acct->active = 0;
  176                 acct->file = NULL;
  177                 acct->ns = NULL;
  178                 list_del(&acct->list);
  179         }
  180         if (file) {
  181                 acct->file = file;
  182                 acct->ns = ns;
  183                 acct->needcheck = jiffies + ACCT_TIMEOUT*HZ;
  184                 acct->active = 1;
  185                 list_add(&acct->list, &acct_list);
  186         }
  187         if (old_acct) {
  188                 mnt_unpin(old_acct->f_path.mnt);
  189                 spin_unlock(&acct_lock);
  190                 do_acct_process(acct, old_ns, old_acct);
  191                 filp_close(old_acct, NULL);
  192                 spin_lock(&acct_lock);
  193         }
  194 }
  195 
  196 static int acct_on(struct filename *pathname)
  197 {
  198         struct file *file;
  199         struct vfsmount *mnt;
  200         struct pid_namespace *ns;
  201         struct bsd_acct_struct *acct = NULL;
  202 
  203         /* Difference from BSD - they don't do O_APPEND */
  204         file = file_open_name(pathname, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
  205         if (IS_ERR(file))
  206                 return PTR_ERR(file);
  207 
  208         if (!S_ISREG(file->f_path.dentry->d_inode->i_mode)) {
  209                 filp_close(file, NULL);
  210                 return -EACCES;
  211         }
  212 
  213         if (!file->f_op->write) {
  214                 filp_close(file, NULL);
  215                 return -EIO;
  216         }
  217 
  218         ns = task_active_pid_ns(current);
  219         if (ns->bacct == NULL) {
  220                 acct = kzalloc(sizeof(struct bsd_acct_struct), GFP_KERNEL);
  221                 if (acct == NULL) {
  222                         filp_close(file, NULL);
  223                         return -ENOMEM;
  224                 }
  225         }
  226 
  227         spin_lock(&acct_lock);
  228         if (ns->bacct == NULL) {
  229                 ns->bacct = acct;
  230                 acct = NULL;
  231         }
  232 
  233         mnt = file->f_path.mnt;
  234         mnt_pin(mnt);
  235         acct_file_reopen(ns->bacct, file, ns);
  236         spin_unlock(&acct_lock);
  237 
  238         mntput(mnt); /* it's pinned, now give up active reference */
  239         kfree(acct);
  240 
  241         return 0;
  242 }
  243 
  244 /**
  245  * sys_acct - enable/disable process accounting
  246  * @name: file name for accounting records or NULL to shutdown accounting
  247  *
  248  * Returns 0 for success or negative errno values for failure.
  249  *
  250  * sys_acct() is the only system call needed to implement process
  251  * accounting. It takes the name of the file where accounting records
  252  * should be written. If the filename is NULL, accounting will be
  253  * shutdown.
  254  */
  255 SYSCALL_DEFINE1(acct, const char __user *, name)
  256 {
  257         int error = 0;
  258 
  259         if (!capable(CAP_SYS_PACCT))
  260                 return -EPERM;
  261 
  262         if (name) {
  263                 struct filename *tmp = getname(name);
  264                 if (IS_ERR(tmp))
  265                         return (PTR_ERR(tmp));
  266                 error = acct_on(tmp);
  267                 putname(tmp);
  268         } else {
  269                 struct bsd_acct_struct *acct;
  270 
  271                 acct = task_active_pid_ns(current)->bacct;
  272                 if (acct == NULL)
  273                         return 0;
  274 
  275                 spin_lock(&acct_lock);
  276                 acct_file_reopen(acct, NULL, NULL);
  277                 spin_unlock(&acct_lock);
  278         }
  279 
  280         return error;
  281 }
  282 
  283 /**
  284  * acct_auto_close - turn off a filesystem's accounting if it is on
  285  * @m: vfsmount being shut down
  286  *
  287  * If the accounting is turned on for a file in the subtree pointed to
  288  * to by m, turn accounting off.  Done when m is about to die.
  289  */
  290 void acct_auto_close_mnt(struct vfsmount *m)
  291 {
  292         struct bsd_acct_struct *acct;
  293 
  294         spin_lock(&acct_lock);
  295 restart:
  296         list_for_each_entry(acct, &acct_list, list)
  297                 if (acct->file && acct->file->f_path.mnt == m) {
  298                         acct_file_reopen(acct, NULL, NULL);
  299                         goto restart;
  300                 }
  301         spin_unlock(&acct_lock);
  302 }
  303 
  304 /**
  305  * acct_auto_close - turn off a filesystem's accounting if it is on
  306  * @sb: super block for the filesystem
  307  *
  308  * If the accounting is turned on for a file in the filesystem pointed
  309  * to by sb, turn accounting off.
  310  */
  311 void acct_auto_close(struct super_block *sb)
  312 {
  313         struct bsd_acct_struct *acct;
  314 
  315         spin_lock(&acct_lock);
  316 restart:
  317         list_for_each_entry(acct, &acct_list, list)
  318                 if (acct->file && acct->file->f_path.dentry->d_sb == sb) {
  319                         acct_file_reopen(acct, NULL, NULL);
  320                         goto restart;
  321                 }
  322         spin_unlock(&acct_lock);
  323 }
  324 
  325 void acct_exit_ns(struct pid_namespace *ns)
  326 {
  327         struct bsd_acct_struct *acct = ns->bacct;
  328 
  329         if (acct == NULL)
  330                 return;
  331 
  332         spin_lock(&acct_lock);
  333         if (acct->file != NULL)
  334                 acct_file_reopen(acct, NULL, NULL);
  335         spin_unlock(&acct_lock);
  336 
  337         kfree(acct);
  338 }
  339 
  340 /*
  341  *  encode an unsigned long into a comp_t
  342  *
  343  *  This routine has been adopted from the encode_comp_t() function in
  344  *  the kern_acct.c file of the FreeBSD operating system. The encoding
  345  *  is a 13-bit fraction with a 3-bit (base 8) exponent.
  346  */
  347 
  348 #define MANTSIZE        13                      /* 13 bit mantissa. */
  349 #define EXPSIZE         3                       /* Base 8 (3 bit) exponent. */
  350 #define MAXFRACT        ((1 << MANTSIZE) - 1)   /* Maximum fractional value. */
  351 
  352 static comp_t encode_comp_t(unsigned long value)
  353 {
  354         int exp, rnd;
  355 
  356         exp = rnd = 0;
  357         while (value > MAXFRACT) {
  358                 rnd = value & (1 << (EXPSIZE - 1));     /* Round up? */
  359                 value >>= EXPSIZE;      /* Base 8 exponent == 3 bit shift. */
  360                 exp++;
  361         }
  362 
  363         /*
  364          * If we need to round up, do it (and handle overflow correctly).
  365          */
  366         if (rnd && (++value > MAXFRACT)) {
  367                 value >>= EXPSIZE;
  368                 exp++;
  369         }
  370 
  371         /*
  372          * Clean it up and polish it off.
  373          */
  374         exp <<= MANTSIZE;               /* Shift the exponent into place */
  375         exp += value;                   /* and add on the mantissa. */
  376         return exp;
  377 }
  378 
  379 #if ACCT_VERSION==1 || ACCT_VERSION==2
  380 /*
  381  * encode an u64 into a comp2_t (24 bits)
  382  *
  383  * Format: 5 bit base 2 exponent, 20 bits mantissa.
  384  * The leading bit of the mantissa is not stored, but implied for
  385  * non-zero exponents.
  386  * Largest encodable value is 50 bits.
  387  */
  388 
  389 #define MANTSIZE2       20                      /* 20 bit mantissa. */
  390 #define EXPSIZE2        5                       /* 5 bit base 2 exponent. */
  391 #define MAXFRACT2       ((1ul << MANTSIZE2) - 1) /* Maximum fractional value. */
  392 #define MAXEXP2         ((1 <<EXPSIZE2) - 1)    /* Maximum exponent. */
  393 
  394 static comp2_t encode_comp2_t(u64 value)
  395 {
  396         int exp, rnd;
  397 
  398         exp = (value > (MAXFRACT2>>1));
  399         rnd = 0;
  400         while (value > MAXFRACT2) {
  401                 rnd = value & 1;
  402                 value >>= 1;
  403                 exp++;
  404         }
  405 
  406         /*
  407          * If we need to round up, do it (and handle overflow correctly).
  408          */
  409         if (rnd && (++value > MAXFRACT2)) {
  410                 value >>= 1;
  411                 exp++;
  412         }
  413 
  414         if (exp > MAXEXP2) {
  415                 /* Overflow. Return largest representable number instead. */
  416                 return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
  417         } else {
  418                 return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
  419         }
  420 }
  421 #endif
  422 
  423 #if ACCT_VERSION==3
  424 /*
  425  * encode an u64 into a 32 bit IEEE float
  426  */
  427 static u32 encode_float(u64 value)
  428 {
  429         unsigned exp = 190;
  430         unsigned u;
  431 
  432         if (value==0) return 0;
  433         while ((s64)value > 0){
  434                 value <<= 1;
  435                 exp--;
  436         }
  437         u = (u32)(value >> 40) & 0x7fffffu;
  438         return u | (exp << 23);
  439 }
  440 #endif
  441 
  442 /*
  443  *  Write an accounting entry for an exiting process
  444  *
  445  *  The acct_process() call is the workhorse of the process
  446  *  accounting system. The struct acct is built here and then written
  447  *  into the accounting file. This function should only be called from
  448  *  do_exit() or when switching to a different output file.
  449  */
  450 
  451 /*
  452  *  do_acct_process does all actual work. Caller holds the reference to file.
  453  */
  454 static void do_acct_process(struct bsd_acct_struct *acct,
  455                 struct pid_namespace *ns, struct file *file)
  456 {
  457         struct pacct_struct *pacct = &current->signal->pacct;
  458         acct_t ac;
  459         mm_segment_t fs;
  460         unsigned long flim;
  461         u64 elapsed;
  462         u64 run_time;
  463         struct timespec uptime;
  464         struct tty_struct *tty;
  465         const struct cred *orig_cred;
  466 
  467         /* Perform file operations on behalf of whoever enabled accounting */
  468         orig_cred = override_creds(file->f_cred);
  469 
  470         /*
  471          * First check to see if there is enough free_space to continue
  472          * the process accounting system.
  473          */
  474         if (!check_free_space(acct, file))
  475                 goto out;
  476 
  477         /*
  478          * Fill the accounting struct with the needed info as recorded
  479          * by the different kernel functions.
  480          */
  481         memset(&ac, 0, sizeof(acct_t));
  482 
  483         ac.ac_version = ACCT_VERSION | ACCT_BYTEORDER;
  484         strlcpy(ac.ac_comm, current->comm, sizeof(ac.ac_comm));
  485 
  486         /* calculate run_time in nsec*/
  487         do_posix_clock_monotonic_gettime(&uptime);
  488         run_time = (u64)uptime.tv_sec*NSEC_PER_SEC + uptime.tv_nsec;
  489         run_time -= (u64)current->group_leader->start_time.tv_sec * NSEC_PER_SEC
  490                        + current->group_leader->start_time.tv_nsec;
  491         /* convert nsec -> AHZ */
  492         elapsed = nsec_to_AHZ(run_time);
  493 #if ACCT_VERSION==3
  494         ac.ac_etime = encode_float(elapsed);
  495 #else
  496         ac.ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ?
  497                                (unsigned long) elapsed : (unsigned long) -1l);
  498 #endif
  499 #if ACCT_VERSION==1 || ACCT_VERSION==2
  500         {
  501                 /* new enlarged etime field */
  502                 comp2_t etime = encode_comp2_t(elapsed);
  503                 ac.ac_etime_hi = etime >> 16;
  504                 ac.ac_etime_lo = (u16) etime;
  505         }
  506 #endif
  507         do_div(elapsed, AHZ);
  508         ac.ac_btime = get_seconds() - elapsed;
  509         /* we really need to bite the bullet and change layout */
  510         ac.ac_uid = from_kuid_munged(file->f_cred->user_ns, orig_cred->uid);
  511         ac.ac_gid = from_kgid_munged(file->f_cred->user_ns, orig_cred->gid);
  512 #if ACCT_VERSION==2
  513         ac.ac_ahz = AHZ;
  514 #endif
  515 #if ACCT_VERSION==1 || ACCT_VERSION==2
  516         /* backward-compatible 16 bit fields */
  517         ac.ac_uid16 = ac.ac_uid;
  518         ac.ac_gid16 = ac.ac_gid;
  519 #endif
  520 #if ACCT_VERSION==3
  521         ac.ac_pid = task_tgid_nr_ns(current, ns);
  522         rcu_read_lock();
  523         ac.ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent), ns);
  524         rcu_read_unlock();
  525 #endif
  526 
  527         spin_lock_irq(&current->sighand->siglock);
  528         tty = current->signal->tty;     /* Safe as we hold the siglock */
  529         ac.ac_tty = tty ? old_encode_dev(tty_devnum(tty)) : 0;
  530         ac.ac_utime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_utime)));
  531         ac.ac_stime = encode_comp_t(jiffies_to_AHZ(cputime_to_jiffies(pacct->ac_stime)));
  532         ac.ac_flag = pacct->ac_flag;
  533         ac.ac_mem = encode_comp_t(pacct->ac_mem);
  534         ac.ac_minflt = encode_comp_t(pacct->ac_minflt);
  535         ac.ac_majflt = encode_comp_t(pacct->ac_majflt);
  536         ac.ac_exitcode = pacct->ac_exitcode;
  537         spin_unlock_irq(&current->sighand->siglock);
  538         ac.ac_io = encode_comp_t(0 /* current->io_usage */);    /* %% */
  539         ac.ac_rw = encode_comp_t(ac.ac_io / 1024);
  540         ac.ac_swaps = encode_comp_t(0);
  541 
  542         /*
  543          * Kernel segment override to datasegment and write it
  544          * to the accounting file.
  545          */
  546         fs = get_fs();
  547         set_fs(KERNEL_DS);
  548         /*
  549          * Accounting records are not subject to resource limits.
  550          */
  551         flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
  552         current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
  553         file->f_op->write(file, (char *)&ac,
  554                                sizeof(acct_t), &file->f_pos);
  555         current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
  556         set_fs(fs);
  557 out:
  558         revert_creds(orig_cred);
  559 }
  560 
  561 /**
  562  * acct_collect - collect accounting information into pacct_struct
  563  * @exitcode: task exit code
  564  * @group_dead: not 0, if this thread is the last one in the process.
  565  */
  566 void acct_collect(long exitcode, int group_dead)
  567 {
  568         struct pacct_struct *pacct = &current->signal->pacct;
  569         unsigned long vsize = 0;
  570 
  571         if (group_dead && current->mm) {
  572                 struct vm_area_struct *vma;
  573                 down_read(&current->mm->mmap_sem);
  574                 vma = current->mm->mmap;
  575                 while (vma) {
  576                         vsize += vma->vm_end - vma->vm_start;
  577                         vma = vma->vm_next;
  578                 }
  579                 up_read(&current->mm->mmap_sem);
  580         }
  581 
  582         spin_lock_irq(&current->sighand->siglock);
  583         if (group_dead)
  584                 pacct->ac_mem = vsize / 1024;
  585         if (thread_group_leader(current)) {
  586                 pacct->ac_exitcode = exitcode;
  587                 if (current->flags & PF_FORKNOEXEC)
  588                         pacct->ac_flag |= AFORK;
  589         }
  590         if (current->flags & PF_SUPERPRIV)
  591                 pacct->ac_flag |= ASU;
  592         if (current->flags & PF_DUMPCORE)
  593                 pacct->ac_flag |= ACORE;
  594         if (current->flags & PF_SIGNALED)
  595                 pacct->ac_flag |= AXSIG;
  596         pacct->ac_utime += current->utime;
  597         pacct->ac_stime += current->stime;
  598         pacct->ac_minflt += current->min_flt;
  599         pacct->ac_majflt += current->maj_flt;
  600         spin_unlock_irq(&current->sighand->siglock);
  601 }
  602 
  603 static void acct_process_in_ns(struct pid_namespace *ns)
  604 {
  605         struct file *file = NULL;
  606         struct bsd_acct_struct *acct;
  607 
  608         acct = ns->bacct;
  609         /*
  610          * accelerate the common fastpath:
  611          */
  612         if (!acct || !acct->file)
  613                 return;
  614 
  615         spin_lock(&acct_lock);
  616         file = acct->file;
  617         if (unlikely(!file)) {
  618                 spin_unlock(&acct_lock);
  619                 return;
  620         }
  621         get_file(file);
  622         spin_unlock(&acct_lock);
  623 
  624         do_acct_process(acct, ns, file);
  625         fput(file);
  626 }
  627 
  628 /**
  629  * acct_process - now just a wrapper around acct_process_in_ns,
  630  * which in turn is a wrapper around do_acct_process.
  631  *
  632  * handles process accounting for an exiting task
  633  */
  634 void acct_process(void)
  635 {
  636         struct pid_namespace *ns;
  637 
  638         /*
  639          * This loop is safe lockless, since current is still
  640          * alive and holds its namespace, which in turn holds
  641          * its parent.
  642          */
  643         for (ns = task_active_pid_ns(current); ns != NULL; ns = ns->parent)
  644                 acct_process_in_ns(ns);
  645 }

Cache object: 3fbfc1f3adf4a2b5e8fd756660e6762d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.