Print this page
7178 tmpfs incorrectly calculates amount of free space

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c
          +++ new/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright (c) 2011, Joyent, Inc. All rights reserved.
       24 + * Copyright 2016 RackTop Systems.
  24   25   */
  25   26  
  26   27  #include <sys/types.h>
  27   28  #include <sys/param.h>
  28   29  #include <sys/sysmacros.h>
  29   30  #include <sys/kmem.h>
  30   31  #include <sys/time.h>
  31   32  #include <sys/pathname.h>
  32   33  #include <sys/vfs.h>
  33   34  #include <sys/vfs_opreg.h>
↓ open down ↓ 545 lines elided ↑ open up ↑
 579  580  
 580  581          /*
 581  582           * Find the amount of available physical and memory swap
 582  583           */
 583  584          mutex_enter(&anoninfo_lock);
 584  585          ASSERT(k_anoninfo.ani_max >= k_anoninfo.ani_phys_resv);
 585  586          blocks = (ulong_t)CURRENT_TOTAL_AVAILABLE_SWAP;
 586  587          mutex_exit(&anoninfo_lock);
 587  588  
 588  589          /*
 589      -         * If tm_anonmax for this mount is less than the available swap space
 590      -         * (minus the amount tmpfs can't use), use that instead
 591      -         */
 592      -        if (blocks > tmpfs_minfree)
 593      -                sbp->f_bfree = MIN(blocks - tmpfs_minfree,
 594      -                    tm->tm_anonmax - tm->tm_anonmem);
      590 +         * If tm_anonmax is unbounded (set to ULONG_MAX) use available
      591 +         * swap space (minus the amount tmpfs can't use) otherwise use
      592 +         * tm_anonmax - tm_anonmem.
      593 +         */
      594 +        if (tm->tm_anonmax == ULONG_MAX)
      595 +                sbp->f_bfree = MAX(blocks - tmpfs_minfree, 0);
      596 +        else if (blocks > tmpfs_minfree)
      597 +                sbp->f_bfree = MAX(tm->tm_anonmax - tm->tm_anonmem, 0);
 595  598          else
 596  599                  sbp->f_bfree = 0;
 597  600  
 598  601          sbp->f_bavail = sbp->f_bfree;
 599  602  
 600  603          /*
 601  604           * Total number of blocks is what's available plus what's been used
 602  605           */
 603  606          sbp->f_blocks = (fsblkcnt64_t)(sbp->f_bfree + tm->tm_anonmem);
 604  607  
↓ open down ↓ 14 lines elided ↑ open up ↑
 619  622                  pgcap = btop(cap);
 620  623                  pgused = btop(used);
 621  624  
 622  625                  sbp->f_bfree = MIN(pgcap - pgused, sbp->f_bfree);
 623  626                  sbp->f_bavail = sbp->f_bfree;
 624  627                  sbp->f_blocks = MIN(pgcap, sbp->f_blocks);
 625  628          }
 626  629  
 627  630          /*
 628  631           * The maximum number of files available is approximately the number
 629      -         * of tmpnodes we can allocate from the remaining kernel memory
 630      -         * available to tmpfs.  This is fairly inaccurate since it doesn't
 631      -         * take into account the names stored in the directory entries.
 632      -         */
 633      -        if (tmpfs_maxkmem > tmp_kmemspace)
 634      -                sbp->f_ffree = (tmpfs_maxkmem - tmp_kmemspace) /
 635      -                    (sizeof (struct tmpnode) + sizeof (struct tdirent));
 636      -        else
 637      -                sbp->f_ffree = 0;
 638      -
 639      -        sbp->f_files = tmpfs_maxkmem /
      632 +         * of tmpnodes we can allocate from the number of blocks available
      633 +         * to this mount.  This is fairly inaccurate since it doesn't take
      634 +         * into account the names stored in the directory entries.
      635 +         */
      636 +        sbp->f_ffree = sbp->f_bfree == 0 ? 0 : sbp->f_bfree /
      637 +            (sizeof (struct tmpnode) + sizeof (struct tdirent));
      638 +        sbp->f_files = sbp->f_blocks == 0 ? 0 : sbp->f_blocks /
 640  639              (sizeof (struct tmpnode) + sizeof (struct tdirent));
 641  640          sbp->f_favail = (fsfilcnt64_t)(sbp->f_ffree);
 642  641          (void) cmpldev(&d32, vfsp->vfs_dev);
 643  642          sbp->f_fsid = d32;
 644  643          (void) strcpy(sbp->f_basetype, vfssw[tmpfsfstype].vsw_name);
 645  644          (void) strncpy(sbp->f_fstr, tm->tm_mntpath, sizeof (sbp->f_fstr));
 646  645          /*
 647  646           * ensure null termination
 648  647           */
 649  648          sbp->f_fstr[sizeof (sbp->f_fstr) - 1] = '\0';
↓ open down ↓ 48 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX