4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2011, Joyent, Inc. All rights reserved.
24 */
25
26 #include <sys/types.h>
27 #include <sys/param.h>
28 #include <sys/sysmacros.h>
29 #include <sys/kmem.h>
30 #include <sys/time.h>
31 #include <sys/pathname.h>
32 #include <sys/vfs.h>
33 #include <sys/vfs_opreg.h>
34 #include <sys/vnode.h>
35 #include <sys/stat.h>
36 #include <sys/uio.h>
37 #include <sys/stat.h>
38 #include <sys/errno.h>
39 #include <sys/cmn_err.h>
40 #include <sys/cred.h>
41 #include <sys/statvfs.h>
42 #include <sys/mount.h>
43 #include <sys/debug.h>
569 else
570 zp = tm->tm_vfsp->vfs_zone;
571
572 if (zp == NULL)
573 eff_zid = GLOBAL_ZONEUNIQID;
574 else
575 eff_zid = zp->zone_id;
576
577 sbp->f_bsize = PAGESIZE;
578 sbp->f_frsize = PAGESIZE;
579
580 /*
581 * Find the amount of available physical and memory swap
582 */
583 mutex_enter(&anoninfo_lock);
584 ASSERT(k_anoninfo.ani_max >= k_anoninfo.ani_phys_resv);
585 blocks = (ulong_t)CURRENT_TOTAL_AVAILABLE_SWAP;
586 mutex_exit(&anoninfo_lock);
587
588 /*
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);
595 else
596 sbp->f_bfree = 0;
597
598 sbp->f_bavail = sbp->f_bfree;
599
600 /*
601 * Total number of blocks is what's available plus what's been used
602 */
603 sbp->f_blocks = (fsblkcnt64_t)(sbp->f_bfree + tm->tm_anonmem);
604
605 if (eff_zid != GLOBAL_ZONEUNIQID &&
606 zp->zone_max_swap_ctl != UINT64_MAX) {
607 /*
608 * If the fs is used by a non-global zone with a swap cap,
609 * then report the capped size.
610 */
611 rctl_qty_t cap, used;
612 pgcnt_t pgcap, pgused;
613
614 mutex_enter(&zp->zone_mem_lock);
615 cap = zp->zone_max_swap_ctl;
616 used = zp->zone_max_swap;
617 mutex_exit(&zp->zone_mem_lock);
618
619 pgcap = btop(cap);
620 pgused = btop(used);
621
622 sbp->f_bfree = MIN(pgcap - pgused, sbp->f_bfree);
623 sbp->f_bavail = sbp->f_bfree;
624 sbp->f_blocks = MIN(pgcap, sbp->f_blocks);
625 }
626
627 /*
628 * 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 /
640 (sizeof (struct tmpnode) + sizeof (struct tdirent));
641 sbp->f_favail = (fsfilcnt64_t)(sbp->f_ffree);
642 (void) cmpldev(&d32, vfsp->vfs_dev);
643 sbp->f_fsid = d32;
644 (void) strcpy(sbp->f_basetype, vfssw[tmpfsfstype].vsw_name);
645 (void) strncpy(sbp->f_fstr, tm->tm_mntpath, sizeof (sbp->f_fstr));
646 /*
647 * ensure null termination
648 */
649 sbp->f_fstr[sizeof (sbp->f_fstr) - 1] = '\0';
650 sbp->f_flag = vf_to_stf(vfsp->vfs_flag);
651 sbp->f_namemax = MAXNAMELEN - 1;
652 return (0);
653 }
654
655 static int
656 tmp_vget(struct vfs *vfsp, struct vnode **vpp, struct fid *fidp)
657 {
658 struct tfid *tfid;
659 struct tmount *tm = (struct tmount *)VFSTOTM(vfsp);
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2011, Joyent, Inc. All rights reserved.
24 * Copyright 2016 RackTop Systems.
25 */
26
27 #include <sys/types.h>
28 #include <sys/param.h>
29 #include <sys/sysmacros.h>
30 #include <sys/kmem.h>
31 #include <sys/time.h>
32 #include <sys/pathname.h>
33 #include <sys/vfs.h>
34 #include <sys/vfs_opreg.h>
35 #include <sys/vnode.h>
36 #include <sys/stat.h>
37 #include <sys/uio.h>
38 #include <sys/stat.h>
39 #include <sys/errno.h>
40 #include <sys/cmn_err.h>
41 #include <sys/cred.h>
42 #include <sys/statvfs.h>
43 #include <sys/mount.h>
44 #include <sys/debug.h>
570 else
571 zp = tm->tm_vfsp->vfs_zone;
572
573 if (zp == NULL)
574 eff_zid = GLOBAL_ZONEUNIQID;
575 else
576 eff_zid = zp->zone_id;
577
578 sbp->f_bsize = PAGESIZE;
579 sbp->f_frsize = PAGESIZE;
580
581 /*
582 * Find the amount of available physical and memory swap
583 */
584 mutex_enter(&anoninfo_lock);
585 ASSERT(k_anoninfo.ani_max >= k_anoninfo.ani_phys_resv);
586 blocks = (ulong_t)CURRENT_TOTAL_AVAILABLE_SWAP;
587 mutex_exit(&anoninfo_lock);
588
589 /*
590 * Compare the amount of space that should be free to this mount
591 * (which may be limited by tm_anonmax) with the amount of space
592 * that's actually free to all tmpfs and use the lowest value.
593 */
594 if (tm->tm_anonmax == ULONG_MAX)
595 sbp->f_bfree = MAX(blocks - tmpfs_minfree, 0);
596 else if (blocks > tmpfs_minfree && tm->tm_anonmax > tm->tm_anonmem)
597 sbp->f_bfree = MIN(blocks - tmpfs_minfree,
598 tm->tm_anonmax - tm->tm_anonmem);
599 else
600 sbp->f_bfree = 0;
601
602 sbp->f_bavail = sbp->f_bfree;
603
604 /*
605 * Total number of blocks is what's available plus what's been used
606 */
607 sbp->f_blocks = (fsblkcnt64_t)(sbp->f_bfree + tm->tm_anonmem);
608
609 if (eff_zid != GLOBAL_ZONEUNIQID &&
610 zp->zone_max_swap_ctl != UINT64_MAX) {
611 /*
612 * If the fs is used by a non-global zone with a swap cap,
613 * then report the capped size.
614 */
615 rctl_qty_t cap, used;
616 pgcnt_t pgcap, pgused;
617
618 mutex_enter(&zp->zone_mem_lock);
619 cap = zp->zone_max_swap_ctl;
620 used = zp->zone_max_swap;
621 mutex_exit(&zp->zone_mem_lock);
622
623 pgcap = btop(cap);
624 pgused = btop(used);
625
626 sbp->f_bfree = MIN(pgcap - pgused, sbp->f_bfree);
627 sbp->f_bavail = sbp->f_bfree;
628 sbp->f_blocks = MIN(pgcap, sbp->f_blocks);
629 }
630
631 /*
632 * The maximum number of files available is approximately the number
633 * of tmpnodes we can allocate from the number of blocks available
634 * to this mount. This is fairly inaccurate since it doesn't take
635 * into account the names stored in the directory entries.
636 */
637 sbp->f_ffree = sbp->f_bfree == 0 ? 0 : sbp->f_bfree /
638 (sizeof (struct tmpnode) + sizeof (struct tdirent));
639 sbp->f_files = sbp->f_blocks == 0 ? 0 : sbp->f_blocks /
640 (sizeof (struct tmpnode) + sizeof (struct tdirent));
641 sbp->f_favail = (fsfilcnt64_t)(sbp->f_ffree);
642 (void) cmpldev(&d32, vfsp->vfs_dev);
643 sbp->f_fsid = d32;
644 (void) strcpy(sbp->f_basetype, vfssw[tmpfsfstype].vsw_name);
645 (void) strncpy(sbp->f_fstr, tm->tm_mntpath, sizeof (sbp->f_fstr));
646 /*
647 * ensure null termination
648 */
649 sbp->f_fstr[sizeof (sbp->f_fstr) - 1] = '\0';
650 sbp->f_flag = vf_to_stf(vfsp->vfs_flag);
651 sbp->f_namemax = MAXNAMELEN - 1;
652 return (0);
653 }
654
655 static int
656 tmp_vget(struct vfs *vfsp, struct vnode **vpp, struct fid *fidp)
657 {
658 struct tfid *tfid;
659 struct tmount *tm = (struct tmount *)VFSTOTM(vfsp);
|