Print this page




   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 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2016 Joyent, Inc.
  29  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  30  * Copyright 2016 RackTop Systems.
  31  */
  32 
  33 #include <sys/types.h>
  34 #include <sys/param.h>
  35 #include <sys/t_lock.h>
  36 #include <sys/systm.h>
  37 #include <sys/sysmacros.h>
  38 #include <sys/user.h>
  39 #include <sys/time.h>
  40 #include <sys/vfs.h>
  41 #include <sys/vfs_opreg.h>
  42 #include <sys/vnode.h>
  43 #include <sys/file.h>
  44 #include <sys/fcntl.h>
  45 #include <sys/flock.h>
  46 #include <sys/kmem.h>
  47 #include <sys/uio.h>
  48 #include <sys/errno.h>


 568          * If we've already done a partial read, terminate
 569          * the read but return no error.
 570          */
 571         if (oresid != uio->uio_resid)
 572                 error = 0;
 573 
 574         TRACE_2(TR_FAC_TMPFS, TR_TMPFS_RWTMP_END,
 575             "tmp_rdtmp_end:vp %x error %d", vp, error);
 576         return (error);
 577 }
 578 
 579 /* ARGSUSED2 */
 580 static int
 581 tmp_read(struct vnode *vp, struct uio *uiop, int ioflag, cred_t *cred,
 582     struct caller_context *ct)
 583 {
 584         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
 585         struct tmount *tm = (struct tmount *)VTOTM(vp);
 586         int error;
 587 
 588         /* If the filesystem was umounted by force, return immediately. */
 589         if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
 590                 return (EIO);
 591 
 592         /*
 593          * We don't currently support reading non-regular files
 594          */
 595         if (vp->v_type == VDIR)
 596                 return (EISDIR);
 597         if (vp->v_type != VREG)
 598                 return (EINVAL);
 599         /*
 600          * tmp_rwlock should have already been called from layers above
 601          */
 602         ASSERT(RW_READ_HELD(&tp->tn_rwlock));
 603 
 604         rw_enter(&tp->tn_contents, RW_READER);
 605 
 606         error = rdtmp(tm, tp, uiop, ct);
 607 
 608         rw_exit(&tp->tn_contents);
 609 
 610         return (error);
 611 }
 612 
 613 static int
 614 tmp_write(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cred,
 615     struct caller_context *ct)
 616 {
 617         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
 618         struct tmount *tm = (struct tmount *)VTOTM(vp);
 619         int error;
 620 
 621         /* If the filesystem was umounted by force, return immediately. */
 622         if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
 623                 return (EIO);
 624 
 625         /*
 626          * We don't currently support writing to non-regular files
 627          */
 628         if (vp->v_type != VREG)
 629                 return (EINVAL);        /* XXX EISDIR? */
 630 
 631         /*
 632          * tmp_rwlock should have already been called from layers above
 633          */
 634         ASSERT(RW_WRITE_HELD(&tp->tn_rwlock));
 635 
 636         rw_enter(&tp->tn_contents, RW_WRITER);
 637 
 638         if (ioflag & FAPPEND) {
 639                 /*
 640                  * In append mode start at end of file.
 641                  */
 642                 uiop->uio_loffset = tp->tn_size;
 643         }
 644 


 830 }
 831 
 832 /* ARGSUSED3 */
 833 static int
 834 tmp_lookup(
 835         struct vnode *dvp,
 836         char *nm,
 837         struct vnode **vpp,
 838         struct pathname *pnp,
 839         int flags,
 840         struct vnode *rdir,
 841         struct cred *cred,
 842         caller_context_t *ct,
 843         int *direntflags,
 844         pathname_t *realpnp)
 845 {
 846         struct tmpnode *tp = (struct tmpnode *)VTOTN(dvp);
 847         struct tmpnode *ntp = NULL;
 848         int error;
 849 
 850         /* If the filesystem was umounted by force, return immediately. */
 851         if (dvp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
 852                 return (EIO);
 853 
 854         /* allow cd into @ dir */
 855         if (flags & LOOKUP_XATTR) {
 856                 struct tmpnode *xdp;
 857                 struct tmount *tm;
 858 
 859                 /*
 860                  * don't allow attributes if not mounted XATTR support
 861                  */
 862                 if (!(dvp->v_vfsp->vfs_flag & VFS_XATTR))
 863                         return (EINVAL);
 864 
 865                 if (tp->tn_flags & ISXATTR)
 866                         /* No attributes on attributes */
 867                         return (EINVAL);
 868 
 869                 rw_enter(&tp->tn_rwlock, RW_WRITER);
 870                 if (tp->tn_xattrdp == NULL) {
 871                         int err;
 872 
 873                         if (!(flags & CREATE_XATTR_DIR)) {
 874                                 rw_exit(&tp->tn_rwlock);
 875                                 return (ENOENT);
 876                         }
 877 
 878                         /*
 879                          * No attribute directory exists for this
 880                          * node - create the attr dir as a side effect
 881                          * of this lookup.
 882                          */
 883 
 884                         /*
 885                          * Make sure we have adequate permission...
 886                          */
 887 
 888                         if ((error = tmp_taccess(tp, VWRITE, cred)) != 0) {
 889                                 rw_exit(&tp->tn_rwlock);
 890                                 return (error);
 891                         }
 892 


 893                         tm = VTOTM(dvp);
 894                         xdp = tmp_kmem_zalloc(tm, sizeof (struct tmpnode),
 895                             KM_SLEEP);
 896                         if (xdp == NULL) {
 897                                 rw_exit(&tp->tn_rwlock);
 898                                 return (ENOSPC);
 899                         }
 900                         tmpnode_init(tm, xdp, &tp->tn_attr, NULL);
 901                         /*
 902                          * Fix-up fields unique to attribute directories.
 903                          */
 904                         xdp->tn_flags = ISXATTR;
 905                         xdp->tn_type = VDIR;
 906                         if (tp->tn_type == VDIR) {
 907                                 xdp->tn_mode = tp->tn_attr.va_mode;
 908                         } else {
 909                                 xdp->tn_mode = 0700;
 910                                 if (tp->tn_attr.va_mode & 0040)
 911                                         xdp->tn_mode |= 0750;
 912                                 if (tp->tn_attr.va_mode & 0004)
 913                                         xdp->tn_mode |= 0705;
 914                         }
 915                         xdp->tn_vnode->v_type = VDIR;
 916                         xdp->tn_vnode->v_flag |= V_XATTRDIR;
 917                         if ((err = tdirinit(tp, xdp)) != 0) {
 918                                 rw_exit(&tp->tn_rwlock);
 919                                 /*
 920                                  * This never got properly initialized so we can
 921                                  * just clean it up.
 922                                  */
 923                                 xdp->tn_vnode->v_flag &= V_XATTRDIR;
 924                                 tmpnode_cleanup(tp);
 925                                 return (err);
 926                         }
 927                         tp->tn_xattrdp = xdp;
 928                 } else {
 929                         VN_HOLD(tp->tn_xattrdp->tn_vnode);
 930                 }
 931                 *vpp = TNTOV(tp->tn_xattrdp);
 932                 rw_exit(&tp->tn_rwlock);
 933                 return (0);
 934         }
 935 
 936         /*
 937          * Null component name is a synonym for directory being searched.
 938          */
 939         if (*nm == '\0') {
 940                 VN_HOLD(dvp);
 941                 *vpp = dvp;
 942                 return (0);
 943         }
 944         ASSERT(tp);
 945 
 946         error = tdirlookup(tp, nm, &ntp, cred);


1488 tmp_readdir(
1489         struct vnode *vp,
1490         struct uio *uiop,
1491         struct cred *cred,
1492         int *eofp,
1493         caller_context_t *ct,
1494         int flags)
1495 {
1496         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
1497         struct tdirent *tdp;
1498         int error = 0;
1499         size_t namelen;
1500         struct dirent64 *dp;
1501         ulong_t offset;
1502         ulong_t total_bytes_wanted;
1503         long outcount = 0;
1504         long bufsize;
1505         int reclen;
1506         caddr_t outbuf;
1507 
1508         /* If the filesystem was umounted by force, return immediately. */
1509         if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
1510                 return (EIO);
1511 
1512         if (uiop->uio_loffset >= MAXOFF_T) {
1513                 if (eofp)
1514                         *eofp = 1;
1515                 return (0);
1516         }
1517         /*
1518          * assuming system call has already called tmp_rwlock
1519          */
1520         ASSERT(RW_READ_HELD(&tp->tn_rwlock));
1521 
1522         if (uiop->uio_iovcnt != 1)
1523                 return (EINVAL);
1524 
1525         if (vp->v_type != VDIR)
1526                 return (ENOTDIR);
1527 
1528         /*
1529          * There's a window here where someone could have removed
1530          * all the entries in the directory after we put a hold on the
1531          * vnode but before we grabbed the rwlock.  Just return.


1625         if (error == 0) {
1626                 /*
1627                  * The entry already exists
1628                  */
1629                 tmpnode_rele(self);
1630                 return (EEXIST);        /* was 0 */
1631         }
1632 
1633         if (error != ENOENT) {
1634                 if (self != NULL)
1635                         tmpnode_rele(self);
1636                 return (error);
1637         }
1638 
1639         rw_enter(&parent->tn_rwlock, RW_WRITER);
1640         error = tdirenter(tm, parent, lnm, DE_CREATE, (struct tmpnode *)NULL,
1641             (struct tmpnode *)NULL, tva, &self, cred, ct);
1642         rw_exit(&parent->tn_rwlock);
1643 
1644         if (error) {
1645                 if (self != NULL)
1646                         tmpnode_rele(self);
1647                 return (error);
1648         }
1649         len = strlen(tnm) + 1;
1650         cp = tmp_kmem_zalloc(tm, len, KM_NOSLEEP | KM_NORMALPRI);
1651         if (cp == NULL) {
1652                 tmpnode_rele(self);
1653                 return (ENOSPC);
1654         }
1655         (void) strcpy(cp, tnm);
1656 
1657         self->tn_symlink = cp;
1658         self->tn_size = len - 1;
1659         tmpnode_rele(self);
1660         return (error);
1661 }
1662 
1663 /* ARGSUSED2 */
1664 static int
1665 tmp_readlink(
1666         struct vnode *vp,
1667         struct uio *uiop,
1668         struct cred *cred,
1669         caller_context_t *ct)
1670 {


1695 }
1696 
1697 /* ARGSUSED */
1698 static void
1699 tmp_inactive(struct vnode *vp, struct cred *cred, caller_context_t *ct)
1700 {
1701         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
1702         struct tmount *tm = (struct tmount *)VFSTOTM(vp->v_vfsp);
1703 
1704         rw_enter(&tp->tn_rwlock, RW_WRITER);
1705 top:
1706         mutex_enter(&tp->tn_tlock);
1707         mutex_enter(&vp->v_lock);
1708         ASSERT(vp->v_count >= 1);
1709 
1710         /*
1711          * If we don't have the last hold or the link count is non-zero,
1712          * there's little to do -- just drop our hold.
1713          */
1714         if (vp->v_count > 1 || tp->tn_nlink != 0) {
1715                 if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) {
1716                         /*
1717                          * Since the file system was forcibly unmounted, we can
1718                          * have a case (v_count == 1, tn_nlink != 0) where this
1719                          * file was open so we didn't add an extra hold on the
1720                          * file in tmp_unmount. We are counting on the
1721                          * interaction of the hold made in tmp_unmount and
1722                          * rele-ed in tmp_vfsfree so we need to be sure we
1723                          * don't decrement in this case.
1724                          */
1725                         if (vp->v_count > 1)
1726                                 vp->v_count--;
1727                 } else {
1728                         vp->v_count--;
1729                 }
1730                 mutex_exit(&vp->v_lock);
1731                 mutex_exit(&tp->tn_tlock);
1732                 rw_exit(&tp->tn_rwlock);
1733                 /* If the filesystem was umounted by force, rele the vfs ref */
1734                 if (tm->tm_vfsp->vfs_flag & VFS_UNMOUNTED)
1735                         VFS_RELE(tm->tm_vfsp);
1736                 return;
1737         }
1738 
1739         /*
1740          * We have the last hold *and* the link count is zero, so this
1741          * tmpnode is dead from the filesystem's viewpoint.  However,
1742          * if the tmpnode has any pages associated with it (i.e. if it's
1743          * a normal file with non-zero size), the tmpnode can still be
1744          * discovered by pageout or fsflush via the page vnode pointers.
1745          * In this case we must drop all our locks, truncate the tmpnode,
1746          * and try the whole dance again.
1747          */
1748         if (tp->tn_size != 0) {
1749                 if (tp->tn_type == VREG) {
1750                         mutex_exit(&vp->v_lock);
1751                         mutex_exit(&tp->tn_tlock);
1752                         rw_enter(&tp->tn_contents, RW_WRITER);
1753                         (void) tmpnode_trunc(tm, tp, 0);
1754                         rw_exit(&tp->tn_contents);
1755                         ASSERT(tp->tn_size == 0);
1756                         ASSERT(tp->tn_nblocks == 0);
1757                         goto top;
1758                 }
1759                 if (tp->tn_type == VLNK)
1760                         tmp_kmem_free(tm, tp->tn_symlink, tp->tn_size + 1);
1761         }
1762 
1763         /*
1764          * Remove normal file/dir's xattr dir and xattrs.
1765          */
1766         if (tp->tn_xattrdp) {
1767                 struct tmpnode *xtp = tp->tn_xattrdp;
1768 
1769                 ASSERT(xtp->tn_flags & ISXATTR);
1770                 tmpnode_hold(xtp);
1771                 rw_enter(&xtp->tn_rwlock, RW_WRITER);
1772                 tdirtrunc(xtp);
1773                 DECR_COUNT(&xtp->tn_nlink, &xtp->tn_tlock);
1774                 tp->tn_xattrdp = NULL;
1775                 rw_exit(&xtp->tn_rwlock);
1776                 tmpnode_rele(xtp);
1777         }
1778 
1779         mutex_exit(&vp->v_lock);
1780         mutex_exit(&tp->tn_tlock);
1781         /* Here's our chance to send invalid event while we're between locks */
1782         vn_invalid(TNTOV(tp));
1783         mutex_enter(&tm->tm_contents);
1784         if (tp->tn_forw == NULL)
1785                 tm->tm_rootnode->tn_back = tp->tn_back;
1786         else
1787                 tp->tn_forw->tn_back = tp->tn_back;
1788         tp->tn_back->tn_forw = tp->tn_forw;
1789         mutex_exit(&tm->tm_contents);
1790         rw_exit(&tp->tn_rwlock);
1791         rw_destroy(&tp->tn_rwlock);
1792         mutex_destroy(&tp->tn_tlock);
1793         vn_free(TNTOV(tp));
1794         tmp_kmem_free(tm, tp, sizeof (struct tmpnode));
1795 
1796         /* If the filesystem was umounted by force, rele the vfs ref */
1797         if (tm->tm_vfsp->vfs_flag & VFS_UNMOUNTED)
1798                 VFS_RELE(tm->tm_vfsp);
1799 }
1800 
1801 /* ARGSUSED2 */
1802 static int
1803 tmp_fid(struct vnode *vp, struct fid *fidp, caller_context_t *ct)
1804 {
1805         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
1806         struct tfid *tfid;
1807 
1808         if (fidp->fid_len < (sizeof (struct tfid) - sizeof (ushort_t))) {
1809                 fidp->fid_len = sizeof (struct tfid) - sizeof (ushort_t);
1810                 return (ENOSPC);
1811         }
1812 
1813         tfid = (struct tfid *)fidp;
1814         bzero(tfid, sizeof (struct tfid));
1815         tfid->tfid_len = (int)sizeof (struct tfid) - sizeof (ushort_t);
1816 
1817         tfid->tfid_ino = tp->tn_nodeid;
1818         tfid->tfid_gen = tp->tn_gen;


1900 /*ARGSUSED*/
1901 static int
1902 tmp_getapage(
1903         struct vnode *vp,
1904         u_offset_t off,
1905         size_t len,
1906         uint_t *protp,
1907         page_t *pl[],
1908         size_t plsz,
1909         struct seg *seg,
1910         caddr_t addr,
1911         enum seg_rw rw,
1912         struct cred *cr)
1913 {
1914         struct page *pp;
1915         int flags;
1916         int err = 0;
1917         struct vnode *pvp;
1918         u_offset_t poff;
1919 
1920         /* If the filesystem was umounted by force, return immediately. */
1921         if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
1922                 return (EIO);
1923 
1924         if (protp != NULL)
1925                 *protp = PROT_ALL;
1926 again:
1927         if (pp = page_lookup(vp, off, rw == S_CREATE ? SE_EXCL : SE_SHARED)) {
1928                 if (pl) {
1929                         pl[0] = pp;
1930                         pl[1] = NULL;
1931                 } else {
1932                         page_unlock(pp);
1933                 }
1934         } else {
1935                 pp = page_create_va(vp, off, PAGESIZE,
1936                     PG_WAIT | PG_EXCL, seg, addr);
1937                 /*
1938                  * Someone raced in and created the page after we did the
1939                  * lookup but before we did the create, so go back and
1940                  * try to look it up again.
1941                  */
1942                 if (pp == NULL)
1943                         goto again;


2125         page_t *pp,
2126         u_offset_t *offp,
2127         size_t *lenp,
2128         int flags,
2129         struct cred *cr)
2130 {
2131         int err;
2132         ulong_t klstart, kllen;
2133         page_t *pplist, *npplist;
2134         extern int klustsize;
2135         long tmp_klustsize;
2136         struct tmpnode *tp;
2137         size_t pp_off, pp_len;
2138         u_offset_t io_off;
2139         size_t io_len;
2140         struct vnode *pvp;
2141         u_offset_t pstart;
2142         u_offset_t offset;
2143         u_offset_t tmpoff;
2144 
2145         /* If the filesystem was umounted by force, return immediately. */
2146         if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED)
2147                 return (EIO);
2148 
2149         ASSERT(PAGE_LOCKED(pp));
2150 
2151         /* Kluster in tmp_klustsize chunks */
2152         tp = VTOTN(vp);
2153         tmp_klustsize = klustsize;
2154         offset = pp->p_offset;
2155         klstart = (offset / tmp_klustsize) * tmp_klustsize;
2156         kllen = MIN(tmp_klustsize, tp->tn_size - klstart);
2157 
2158         /* Get a kluster of pages */
2159         pplist =
2160             pvn_write_kluster(vp, pp, &tmpoff, &pp_len, klstart, kllen, flags);
2161 
2162         pp_off = (size_t)tmpoff;
2163 
2164         /*
2165          * Get a cluster of physical offsets for the pages; the amount we
2166          * get may be some subrange of what we ask for (io_off, io_len).
2167          */
2168         io_off = pp_off;




   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 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2016, Joyent, Inc.
  29  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  30  * Copyright 2016 RackTop Systems.
  31  */
  32 
  33 #include <sys/types.h>
  34 #include <sys/param.h>
  35 #include <sys/t_lock.h>
  36 #include <sys/systm.h>
  37 #include <sys/sysmacros.h>
  38 #include <sys/user.h>
  39 #include <sys/time.h>
  40 #include <sys/vfs.h>
  41 #include <sys/vfs_opreg.h>
  42 #include <sys/vnode.h>
  43 #include <sys/file.h>
  44 #include <sys/fcntl.h>
  45 #include <sys/flock.h>
  46 #include <sys/kmem.h>
  47 #include <sys/uio.h>
  48 #include <sys/errno.h>


 568          * If we've already done a partial read, terminate
 569          * the read but return no error.
 570          */
 571         if (oresid != uio->uio_resid)
 572                 error = 0;
 573 
 574         TRACE_2(TR_FAC_TMPFS, TR_TMPFS_RWTMP_END,
 575             "tmp_rdtmp_end:vp %x error %d", vp, error);
 576         return (error);
 577 }
 578 
 579 /* ARGSUSED2 */
 580 static int
 581 tmp_read(struct vnode *vp, struct uio *uiop, int ioflag, cred_t *cred,
 582     struct caller_context *ct)
 583 {
 584         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
 585         struct tmount *tm = (struct tmount *)VTOTM(vp);
 586         int error;
 587 




 588         /*
 589          * We don't currently support reading non-regular files
 590          */
 591         if (vp->v_type == VDIR)
 592                 return (EISDIR);
 593         if (vp->v_type != VREG)
 594                 return (EINVAL);
 595         /*
 596          * tmp_rwlock should have already been called from layers above
 597          */
 598         ASSERT(RW_READ_HELD(&tp->tn_rwlock));
 599 
 600         rw_enter(&tp->tn_contents, RW_READER);
 601 
 602         error = rdtmp(tm, tp, uiop, ct);
 603 
 604         rw_exit(&tp->tn_contents);
 605 
 606         return (error);
 607 }
 608 
 609 static int
 610 tmp_write(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cred,
 611     struct caller_context *ct)
 612 {
 613         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
 614         struct tmount *tm = (struct tmount *)VTOTM(vp);
 615         int error;
 616 




 617         /*
 618          * We don't currently support writing to non-regular files
 619          */
 620         if (vp->v_type != VREG)
 621                 return (EINVAL);        /* XXX EISDIR? */
 622 
 623         /*
 624          * tmp_rwlock should have already been called from layers above
 625          */
 626         ASSERT(RW_WRITE_HELD(&tp->tn_rwlock));
 627 
 628         rw_enter(&tp->tn_contents, RW_WRITER);
 629 
 630         if (ioflag & FAPPEND) {
 631                 /*
 632                  * In append mode start at end of file.
 633                  */
 634                 uiop->uio_loffset = tp->tn_size;
 635         }
 636 


 822 }
 823 
 824 /* ARGSUSED3 */
 825 static int
 826 tmp_lookup(
 827         struct vnode *dvp,
 828         char *nm,
 829         struct vnode **vpp,
 830         struct pathname *pnp,
 831         int flags,
 832         struct vnode *rdir,
 833         struct cred *cred,
 834         caller_context_t *ct,
 835         int *direntflags,
 836         pathname_t *realpnp)
 837 {
 838         struct tmpnode *tp = (struct tmpnode *)VTOTN(dvp);
 839         struct tmpnode *ntp = NULL;
 840         int error;
 841 



 842 
 843         /* allow cd into @ dir */
 844         if (flags & LOOKUP_XATTR) {
 845                 struct tmpnode *xdp;
 846                 struct tmount *tm;
 847 
 848                 /*
 849                  * don't allow attributes if not mounted XATTR support
 850                  */
 851                 if (!(dvp->v_vfsp->vfs_flag & VFS_XATTR))
 852                         return (EINVAL);
 853 
 854                 if (tp->tn_flags & ISXATTR)
 855                         /* No attributes on attributes */
 856                         return (EINVAL);
 857 
 858                 rw_enter(&tp->tn_rwlock, RW_WRITER);
 859                 if (tp->tn_xattrdp == NULL) {


 860                         if (!(flags & CREATE_XATTR_DIR)) {
 861                                 rw_exit(&tp->tn_rwlock);
 862                                 return (ENOENT);
 863                         }
 864 
 865                         /*
 866                          * No attribute directory exists for this
 867                          * node - create the attr dir as a side effect
 868                          * of this lookup.
 869                          */
 870 
 871                         /*
 872                          * Make sure we have adequate permission...
 873                          */
 874 
 875                         if ((error = tmp_taccess(tp, VWRITE, cred)) != 0) {
 876                                 rw_exit(&tp->tn_rwlock);
 877                                 return (error);
 878                         }
 879 
 880                         xdp = tmp_memalloc(sizeof (struct tmpnode),
 881                             TMP_MUSTHAVE);
 882                         tm = VTOTM(dvp);






 883                         tmpnode_init(tm, xdp, &tp->tn_attr, NULL);
 884                         /*
 885                          * Fix-up fields unique to attribute directories.
 886                          */
 887                         xdp->tn_flags = ISXATTR;
 888                         xdp->tn_type = VDIR;
 889                         if (tp->tn_type == VDIR) {
 890                                 xdp->tn_mode = tp->tn_attr.va_mode;
 891                         } else {
 892                                 xdp->tn_mode = 0700;
 893                                 if (tp->tn_attr.va_mode & 0040)
 894                                         xdp->tn_mode |= 0750;
 895                                 if (tp->tn_attr.va_mode & 0004)
 896                                         xdp->tn_mode |= 0705;
 897                         }
 898                         xdp->tn_vnode->v_type = VDIR;
 899                         xdp->tn_vnode->v_flag |= V_XATTRDIR;
 900                         tdirinit(tp, xdp);









 901                         tp->tn_xattrdp = xdp;
 902                 } else {
 903                         VN_HOLD(tp->tn_xattrdp->tn_vnode);
 904                 }
 905                 *vpp = TNTOV(tp->tn_xattrdp);
 906                 rw_exit(&tp->tn_rwlock);
 907                 return (0);
 908         }
 909 
 910         /*
 911          * Null component name is a synonym for directory being searched.
 912          */
 913         if (*nm == '\0') {
 914                 VN_HOLD(dvp);
 915                 *vpp = dvp;
 916                 return (0);
 917         }
 918         ASSERT(tp);
 919 
 920         error = tdirlookup(tp, nm, &ntp, cred);


1462 tmp_readdir(
1463         struct vnode *vp,
1464         struct uio *uiop,
1465         struct cred *cred,
1466         int *eofp,
1467         caller_context_t *ct,
1468         int flags)
1469 {
1470         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
1471         struct tdirent *tdp;
1472         int error = 0;
1473         size_t namelen;
1474         struct dirent64 *dp;
1475         ulong_t offset;
1476         ulong_t total_bytes_wanted;
1477         long outcount = 0;
1478         long bufsize;
1479         int reclen;
1480         caddr_t outbuf;
1481 




1482         if (uiop->uio_loffset >= MAXOFF_T) {
1483                 if (eofp)
1484                         *eofp = 1;
1485                 return (0);
1486         }
1487         /*
1488          * assuming system call has already called tmp_rwlock
1489          */
1490         ASSERT(RW_READ_HELD(&tp->tn_rwlock));
1491 
1492         if (uiop->uio_iovcnt != 1)
1493                 return (EINVAL);
1494 
1495         if (vp->v_type != VDIR)
1496                 return (ENOTDIR);
1497 
1498         /*
1499          * There's a window here where someone could have removed
1500          * all the entries in the directory after we put a hold on the
1501          * vnode but before we grabbed the rwlock.  Just return.


1595         if (error == 0) {
1596                 /*
1597                  * The entry already exists
1598                  */
1599                 tmpnode_rele(self);
1600                 return (EEXIST);        /* was 0 */
1601         }
1602 
1603         if (error != ENOENT) {
1604                 if (self != NULL)
1605                         tmpnode_rele(self);
1606                 return (error);
1607         }
1608 
1609         rw_enter(&parent->tn_rwlock, RW_WRITER);
1610         error = tdirenter(tm, parent, lnm, DE_CREATE, (struct tmpnode *)NULL,
1611             (struct tmpnode *)NULL, tva, &self, cred, ct);
1612         rw_exit(&parent->tn_rwlock);
1613 
1614         if (error) {
1615                 if (self)
1616                         tmpnode_rele(self);
1617                 return (error);
1618         }
1619         len = strlen(tnm) + 1;
1620         cp = tmp_memalloc(len, 0);
1621         if (cp == NULL) {
1622                 tmpnode_rele(self);
1623                 return (ENOSPC);
1624         }
1625         (void) strcpy(cp, tnm);
1626 
1627         self->tn_symlink = cp;
1628         self->tn_size = len - 1;
1629         tmpnode_rele(self);
1630         return (error);
1631 }
1632 
1633 /* ARGSUSED2 */
1634 static int
1635 tmp_readlink(
1636         struct vnode *vp,
1637         struct uio *uiop,
1638         struct cred *cred,
1639         caller_context_t *ct)
1640 {


1665 }
1666 
1667 /* ARGSUSED */
1668 static void
1669 tmp_inactive(struct vnode *vp, struct cred *cred, caller_context_t *ct)
1670 {
1671         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
1672         struct tmount *tm = (struct tmount *)VFSTOTM(vp->v_vfsp);
1673 
1674         rw_enter(&tp->tn_rwlock, RW_WRITER);
1675 top:
1676         mutex_enter(&tp->tn_tlock);
1677         mutex_enter(&vp->v_lock);
1678         ASSERT(vp->v_count >= 1);
1679 
1680         /*
1681          * If we don't have the last hold or the link count is non-zero,
1682          * there's little to do -- just drop our hold.
1683          */
1684         if (vp->v_count > 1 || tp->tn_nlink != 0) {











1685                 vp->v_count--;



1686                 mutex_exit(&vp->v_lock);
1687                 mutex_exit(&tp->tn_tlock);
1688                 rw_exit(&tp->tn_rwlock);



1689                 return;
1690         }
1691 
1692         /*
1693          * We have the last hold *and* the link count is zero, so this
1694          * tmpnode is dead from the filesystem's viewpoint.  However,
1695          * if the tmpnode has any pages associated with it (i.e. if it's
1696          * a normal file with non-zero size), the tmpnode can still be
1697          * discovered by pageout or fsflush via the page vnode pointers.
1698          * In this case we must drop all our locks, truncate the tmpnode,
1699          * and try the whole dance again.
1700          */
1701         if (tp->tn_size != 0) {
1702                 if (tp->tn_type == VREG) {
1703                         mutex_exit(&vp->v_lock);
1704                         mutex_exit(&tp->tn_tlock);
1705                         rw_enter(&tp->tn_contents, RW_WRITER);
1706                         (void) tmpnode_trunc(tm, tp, 0);
1707                         rw_exit(&tp->tn_contents);
1708                         ASSERT(tp->tn_size == 0);
1709                         ASSERT(tp->tn_nblocks == 0);
1710                         goto top;
1711                 }
1712                 if (tp->tn_type == VLNK)
1713                         tmp_memfree(tp->tn_symlink, tp->tn_size + 1);
1714         }
1715 
1716         /*
1717          * Remove normal file/dir's xattr dir and xattrs.
1718          */
1719         if (tp->tn_xattrdp) {
1720                 struct tmpnode *xtp = tp->tn_xattrdp;
1721 
1722                 ASSERT(xtp->tn_flags & ISXATTR);
1723                 tmpnode_hold(xtp);
1724                 rw_enter(&xtp->tn_rwlock, RW_WRITER);
1725                 tdirtrunc(xtp);
1726                 DECR_COUNT(&xtp->tn_nlink, &xtp->tn_tlock);
1727                 tp->tn_xattrdp = NULL;
1728                 rw_exit(&xtp->tn_rwlock);
1729                 tmpnode_rele(xtp);
1730         }
1731 
1732         mutex_exit(&vp->v_lock);
1733         mutex_exit(&tp->tn_tlock);
1734         /* Here's our chance to send invalid event while we're between locks */
1735         vn_invalid(TNTOV(tp));
1736         mutex_enter(&tm->tm_contents);
1737         if (tp->tn_forw == NULL)
1738                 tm->tm_rootnode->tn_back = tp->tn_back;
1739         else
1740                 tp->tn_forw->tn_back = tp->tn_back;
1741         tp->tn_back->tn_forw = tp->tn_forw;
1742         mutex_exit(&tm->tm_contents);
1743         rw_exit(&tp->tn_rwlock);
1744         rw_destroy(&tp->tn_rwlock);
1745         mutex_destroy(&tp->tn_tlock);
1746         vn_free(TNTOV(tp));
1747         tmp_memfree(tp, sizeof (struct tmpnode));




1748 }
1749 
1750 /* ARGSUSED2 */
1751 static int
1752 tmp_fid(struct vnode *vp, struct fid *fidp, caller_context_t *ct)
1753 {
1754         struct tmpnode *tp = (struct tmpnode *)VTOTN(vp);
1755         struct tfid *tfid;
1756 
1757         if (fidp->fid_len < (sizeof (struct tfid) - sizeof (ushort_t))) {
1758                 fidp->fid_len = sizeof (struct tfid) - sizeof (ushort_t);
1759                 return (ENOSPC);
1760         }
1761 
1762         tfid = (struct tfid *)fidp;
1763         bzero(tfid, sizeof (struct tfid));
1764         tfid->tfid_len = (int)sizeof (struct tfid) - sizeof (ushort_t);
1765 
1766         tfid->tfid_ino = tp->tn_nodeid;
1767         tfid->tfid_gen = tp->tn_gen;


1849 /*ARGSUSED*/
1850 static int
1851 tmp_getapage(
1852         struct vnode *vp,
1853         u_offset_t off,
1854         size_t len,
1855         uint_t *protp,
1856         page_t *pl[],
1857         size_t plsz,
1858         struct seg *seg,
1859         caddr_t addr,
1860         enum seg_rw rw,
1861         struct cred *cr)
1862 {
1863         struct page *pp;
1864         int flags;
1865         int err = 0;
1866         struct vnode *pvp;
1867         u_offset_t poff;
1868 




1869         if (protp != NULL)
1870                 *protp = PROT_ALL;
1871 again:
1872         if (pp = page_lookup(vp, off, rw == S_CREATE ? SE_EXCL : SE_SHARED)) {
1873                 if (pl) {
1874                         pl[0] = pp;
1875                         pl[1] = NULL;
1876                 } else {
1877                         page_unlock(pp);
1878                 }
1879         } else {
1880                 pp = page_create_va(vp, off, PAGESIZE,
1881                     PG_WAIT | PG_EXCL, seg, addr);
1882                 /*
1883                  * Someone raced in and created the page after we did the
1884                  * lookup but before we did the create, so go back and
1885                  * try to look it up again.
1886                  */
1887                 if (pp == NULL)
1888                         goto again;


2070         page_t *pp,
2071         u_offset_t *offp,
2072         size_t *lenp,
2073         int flags,
2074         struct cred *cr)
2075 {
2076         int err;
2077         ulong_t klstart, kllen;
2078         page_t *pplist, *npplist;
2079         extern int klustsize;
2080         long tmp_klustsize;
2081         struct tmpnode *tp;
2082         size_t pp_off, pp_len;
2083         u_offset_t io_off;
2084         size_t io_len;
2085         struct vnode *pvp;
2086         u_offset_t pstart;
2087         u_offset_t offset;
2088         u_offset_t tmpoff;
2089 




2090         ASSERT(PAGE_LOCKED(pp));
2091 
2092         /* Kluster in tmp_klustsize chunks */
2093         tp = VTOTN(vp);
2094         tmp_klustsize = klustsize;
2095         offset = pp->p_offset;
2096         klstart = (offset / tmp_klustsize) * tmp_klustsize;
2097         kllen = MIN(tmp_klustsize, tp->tn_size - klstart);
2098 
2099         /* Get a kluster of pages */
2100         pplist =
2101             pvn_write_kluster(vp, pp, &tmpoff, &pp_len, klstart, kllen, flags);
2102 
2103         pp_off = (size_t)tmpoff;
2104 
2105         /*
2106          * Get a cluster of physical offsets for the pages; the amount we
2107          * get may be some subrange of what we ask for (io_off, io_len).
2108          */
2109         io_off = pp_off;