Print this page


Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/vnode.c
          +++ new/usr/src/uts/common/fs/vnode.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  /*
  23   23   * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright 2016, Joyent, Inc.
       24 + * Copyright (c) 2014, Joyent, Inc. All rights reserved.
  25   25   */
  26   26  
  27   27  /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T     */
  28   28  /*        All Rights Reserved   */
  29   29  
  30   30  /*
  31   31   * University Copyright- Copyright (c) 1982, 1986, 1988
  32   32   * The Regents of the University of California
  33   33   * All Rights Reserved
  34   34   *
↓ open down ↓ 24 lines elided ↑ open up ↑
  59   59  #include <sys/systm.h>
  60   60  #include <sys/kmem.h>
  61   61  #include <sys/debug.h>
  62   62  #include <c2/audit.h>
  63   63  #include <sys/acl.h>
  64   64  #include <sys/nbmlock.h>
  65   65  #include <sys/fcntl.h>
  66   66  #include <fs/fs_subr.h>
  67   67  #include <sys/taskq.h>
  68   68  #include <fs/fs_reparse.h>
  69      -#include <sys/time.h>
  70      -#include <sys/sdt.h>
  71   69  
  72   70  /* Determine if this vnode is a file that is read-only */
  73   71  #define ISROFILE(vp)    \
  74   72          ((vp)->v_type != VCHR && (vp)->v_type != VBLK && \
  75   73              (vp)->v_type != VFIFO && vn_is_readonly(vp))
  76   74  
  77   75  /* Tunable via /etc/system; used only by admin/install */
  78   76  int nfs_global_client_only;
  79   77  
  80   78  /*
↓ open down ↓ 16 lines elided ↑ open up ↑
  97   95  /*
  98   96   * Root of AVL tree for the kstats associated with vopstats.  Lock protects
  99   97   * updates to vsktat_tree.
 100   98   */
 101   99  avl_tree_t      vskstat_tree;
 102  100  kmutex_t        vskstat_tree_lock;
 103  101  
 104  102  /* Global variable which enables/disables the vopstats collection */
 105  103  int vopstats_enabled = 1;
 106  104  
 107      -/* Global used for empty/invalid v_path */
 108      -char *vn_vpath_empty = "";
 109      -
 110  105  /*
 111  106   * forward declarations for internal vnode specific data (vsd)
 112  107   */
 113  108  static void *vsd_realloc(void *, size_t, size_t);
 114  109  
 115  110  /*
 116  111   * forward declarations for reparse point functions
 117  112   */
 118  113  static int fs_reparse_mark(char *target, vattr_t *vap, xvattr_t *xvattr);
 119  114  
↓ open down ↓ 81 lines elided ↑ open up ↑
 201  196   */
 202  197  #define VOPXID_MAP_CR(vp, cr)   {                                       \
 203  198          vfs_t *vfsp = (vp)->v_vfsp;                                     \
 204  199          if (vfsp != NULL && (vfsp->vfs_flag & VFS_XID) == 0)            \
 205  200                  cr = crgetmapped(cr);                                   \
 206  201          }
 207  202  
 208  203  #define VOP_LATENCY_10MS        10000000
 209  204  #define VOP_LATENCY_100MS       100000000
 210  205  #define VOP_LATENCY_1S          1000000000
 211      -#define VOP_LATENCY_10S         10000000000
 212  206  
 213  207  /*
 214  208   * Convert stat(2) formats to vnode types and vice versa.  (Knows about
 215  209   * numerical order of S_IFMT and vnode types.)
 216  210   */
 217  211  enum vtype iftovt_tab[] = {
 218  212          VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
 219  213          VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VNON
 220  214  };
 221  215  
↓ open down ↓ 1424 lines elided ↑ open up ↑
1646 1640  }
1647 1641  
1648 1642  int
1649 1643  vn_rename(char *from, char *to, enum uio_seg seg)
1650 1644  {
1651 1645          return (vn_renameat(NULL, from, NULL, to, seg));
1652 1646  }
1653 1647  
1654 1648  int
1655 1649  vn_renameat(vnode_t *fdvp, char *fname, vnode_t *tdvp,
1656      -    char *tname, enum uio_seg seg)
     1650 +                char *tname, enum uio_seg seg)
1657 1651  {
1658 1652          int error;
1659 1653          struct vattr vattr;
1660 1654          struct pathname fpn;            /* from pathname */
1661 1655          struct pathname tpn;            /* to pathname */
1662 1656          dev_t fsid;
1663 1657          int in_crit_src, in_crit_targ;
1664 1658          vnode_t *fromvp, *fvp;
1665 1659          vnode_t *tovp, *targvp;
1666 1660          int estale_retry = 0;
↓ open down ↓ 620 lines elided ↑ open up ↑
2287 2281  {
2288 2282          struct vnode *vp;
2289 2283  
2290 2284          vp = buf;
2291 2285  
2292 2286          mutex_init(&vp->v_lock, NULL, MUTEX_DEFAULT, NULL);
2293 2287          mutex_init(&vp->v_vsd_lock, NULL, MUTEX_DEFAULT, NULL);
2294 2288          cv_init(&vp->v_cv, NULL, CV_DEFAULT, NULL);
2295 2289          rw_init(&vp->v_nbllock, NULL, RW_DEFAULT, NULL);
2296 2290          vp->v_femhead = NULL;   /* Must be done before vn_reinit() */
2297      -        vp->v_path = vn_vpath_empty;
2298      -        vp->v_path_stamp = 0;
     2291 +        vp->v_path = NULL;
2299 2292          vp->v_mpssdata = NULL;
2300 2293          vp->v_vsd = NULL;
2301 2294          vp->v_fopdata = NULL;
2302 2295  
2303 2296          return (0);
2304 2297  }
2305 2298  
2306 2299  /* ARGSUSED */
2307 2300  static void
2308 2301  vn_cache_destructor(void *buf, void *cdrarg)
↓ open down ↓ 26 lines elided ↑ open up ↑
2335 2328  }
2336 2329  
2337 2330  /*
2338 2331   * Used by file systems when fs-specific nodes (e.g., ufs inodes) are
2339 2332   * cached by the file system and vnodes remain associated.
2340 2333   */
2341 2334  void
2342 2335  vn_recycle(vnode_t *vp)
2343 2336  {
2344 2337          ASSERT(vp->v_pages == NULL);
2345      -        VERIFY(vp->v_path != NULL);
2346 2338  
2347 2339          /*
2348 2340           * XXX - This really belongs in vn_reinit(), but we have some issues
2349 2341           * with the counts.  Best to have it here for clean initialization.
2350 2342           */
2351 2343          vp->v_rdcnt = 0;
2352 2344          vp->v_wrcnt = 0;
2353 2345          vp->v_mmap_read = 0;
2354 2346          vp->v_mmap_write = 0;
2355 2347  
↓ open down ↓ 2 lines elided ↑ open up ↑
2358 2350           * NOTE: vp->v_femhead is initialized to NULL in the vnode
2359 2351           * constructor.
2360 2352           */
2361 2353          if (vp->v_femhead) {
2362 2354                  /* XXX - There should be a free_femhead() that does all this */
2363 2355                  ASSERT(vp->v_femhead->femh_list == NULL);
2364 2356                  mutex_destroy(&vp->v_femhead->femh_lock);
2365 2357                  kmem_free(vp->v_femhead, sizeof (*(vp->v_femhead)));
2366 2358                  vp->v_femhead = NULL;
2367 2359          }
2368      -        if (vp->v_path != vn_vpath_empty) {
     2360 +        if (vp->v_path) {
2369 2361                  kmem_free(vp->v_path, strlen(vp->v_path) + 1);
2370      -                vp->v_path = vn_vpath_empty;
     2362 +                vp->v_path = NULL;
2371 2363          }
2372      -        vp->v_path_stamp = 0;
2373 2364  
2374 2365          if (vp->v_fopdata != NULL) {
2375 2366                  free_fopdata(vp);
2376 2367          }
2377 2368          vp->v_mpssdata = NULL;
2378 2369          vsd_free(vp);
2379 2370  }
2380 2371  
2381 2372  /*
2382 2373   * Used to reset the vnode fields including those that are directly accessible
↓ open down ↓ 50 lines elided ↑ open up ↑
2433 2424          ASSERT(vp->v_shrlocks == NULL);
2434 2425          ASSERT(vp->v_filocks == NULL);
2435 2426  
2436 2427          /*
2437 2428           * Some file systems call vn_free() with v_count of zero,
2438 2429           * some with v_count of 1.  In any case, the value should
2439 2430           * never be anything else.
2440 2431           */
2441 2432          ASSERT((vp->v_count == 0) || (vp->v_count == 1));
2442 2433          ASSERT(vp->v_count_dnlc == 0);
2443      -        VERIFY(vp->v_path != NULL);
2444      -        if (vp->v_path != vn_vpath_empty) {
     2434 +        if (vp->v_path != NULL) {
2445 2435                  kmem_free(vp->v_path, strlen(vp->v_path) + 1);
2446      -                vp->v_path = vn_vpath_empty;
     2436 +                vp->v_path = NULL;
2447 2437          }
2448 2438  
2449 2439          /* If FEM was in use, make sure everything gets cleaned up */
2450 2440          if (vp->v_femhead) {
2451 2441                  /* XXX - There should be a free_femhead() that does all this */
2452 2442                  ASSERT(vp->v_femhead->femh_list == NULL);
2453 2443                  mutex_destroy(&vp->v_femhead->femh_lock);
2454 2444                  kmem_free(vp->v_femhead, sizeof (*(vp->v_femhead)));
2455 2445                  vp->v_femhead = NULL;
2456 2446          }
↓ open down ↓ 513 lines elided ↑ open up ↑
2970 2960   */
2971 2961  u_longlong_t
2972 2962  fs_new_caller_id()
2973 2963  {
2974 2964          static uint64_t next_caller_id = 0LL; /* First call returns 1 */
2975 2965  
2976 2966          return ((u_longlong_t)atomic_inc_64_nv(&next_caller_id));
2977 2967  }
2978 2968  
2979 2969  /*
2980      - * The value stored in v_path is relative to rootdir, located in the global
2981      - * zone.  Zones or chroot environments which reside deeper inside the VFS
2982      - * hierarchy will have a relative view of MAXPATHLEN since they are unaware of
2983      - * what lies below their perceived root.  In order to keep v_path usable for
2984      - * these child environments, its allocations are allowed to exceed MAXPATHLEN.
2985      - *
2986      - * An upper bound of max_vnode_path is placed upon v_path allocations to
2987      - * prevent the system from going too wild at the behest of pathological
2988      - * behavior from the operator.
     2970 + * Given a starting vnode and a path, updates the path in the target vnode in
     2971 + * a safe manner.  If the vnode already has path information embedded, then the
     2972 + * cached path is left untouched.
2989 2973   */
     2974 +
2990 2975  size_t max_vnode_path = 4 * MAXPATHLEN;
2991 2976  
2992      -
2993 2977  void
2994      -vn_clearpath(vnode_t *vp, hrtime_t compare_stamp)
     2978 +vn_setpath(vnode_t *rootvp, struct vnode *startvp, struct vnode *vp,
     2979 +    const char *path, size_t plen)
2995 2980  {
2996      -        char *buf;
     2981 +        char    *rpath;
     2982 +        vnode_t *base;
     2983 +        size_t  rpathlen, rpathalloc;
     2984 +        int     doslash = 1;
2997 2985  
2998      -        mutex_enter(&vp->v_lock);
     2986 +        if (*path == '/') {
     2987 +                base = rootvp;
     2988 +                path++;
     2989 +                plen--;
     2990 +        } else {
     2991 +                base = startvp;
     2992 +        }
     2993 +
2999 2994          /*
3000      -         * If the snapshot of v_path_stamp passed in via compare_stamp does not
3001      -         * match the present value on the vnode, it indicates that subsequent
3002      -         * changes have occurred.  The v_path value is not cleared in this case
3003      -         * since the new value may be valid.
     2995 +         * We cannot grab base->v_lock while we hold vp->v_lock because of
     2996 +         * the potential for deadlock.
3004 2997           */
3005      -        if (compare_stamp != 0 && vp->v_path_stamp != compare_stamp) {
3006      -                mutex_exit(&vp->v_lock);
     2998 +        mutex_enter(&base->v_lock);
     2999 +        if (base->v_path == NULL) {
     3000 +                mutex_exit(&base->v_lock);
3007 3001                  return;
3008 3002          }
3009      -        buf = vp->v_path;
3010      -        vp->v_path = vn_vpath_empty;
3011      -        vp->v_path_stamp = 0;
3012      -        mutex_exit(&vp->v_lock);
3013      -        if (buf != vn_vpath_empty) {
3014      -                kmem_free(buf, strlen(buf) + 1);
3015      -        }
3016      -}
3017 3003  
3018      -static void
3019      -vn_setpath_common(vnode_t *pvp, vnode_t *vp, const char *name, size_t len,
3020      -    boolean_t is_rename)
3021      -{
3022      -        char *buf, *oldbuf;
3023      -        hrtime_t pstamp;
3024      -        size_t baselen, buflen = 0;
     3004 +        rpathlen = strlen(base->v_path);
     3005 +        rpathalloc = rpathlen + plen + 1;
     3006 +        /* Avoid adding a slash if there's already one there */
     3007 +        if (base->v_path[rpathlen-1] == '/')
     3008 +                doslash = 0;
     3009 +        else
     3010 +                rpathalloc++;
3025 3011  
3026      -        /* Handle the vn_setpath_str case. */
3027      -        if (pvp == NULL) {
3028      -                if (len + 1 > max_vnode_path) {
3029      -                        DTRACE_PROBE4(vn__setpath__too__long, vnode_t *, pvp,
3030      -                            vnode_t *, vp, char *, name, size_t, len + 1);
3031      -                        return;
3032      -                }
3033      -                buf = kmem_alloc(len + 1, KM_SLEEP);
3034      -                bcopy(name, buf, len);
3035      -                buf[len] = '\0';
     3012 +        /*
     3013 +         * We don't want to call kmem_alloc(KM_SLEEP) with kernel locks held,
     3014 +         * so we must do this dance.  If, by chance, something changes the path,
     3015 +         * just give up since there is no real harm.
     3016 +         */
     3017 +        mutex_exit(&base->v_lock);
3036 3018  
3037      -                mutex_enter(&vp->v_lock);
3038      -                oldbuf = vp->v_path;
3039      -                vp->v_path = buf;
3040      -                vp->v_path_stamp = gethrtime();
3041      -                mutex_exit(&vp->v_lock);
3042      -                if (oldbuf != vn_vpath_empty) {
3043      -                        kmem_free(oldbuf, strlen(oldbuf) + 1);
3044      -                }
     3019 +        /* Paths should stay within reason */
     3020 +        if (rpathalloc > max_vnode_path)
3045 3021                  return;
3046      -        }
3047 3022  
3048      -        /* Take snapshot of parent dir */
3049      -        mutex_enter(&pvp->v_lock);
3050      -retrybuf:
3051      -        if (pvp->v_path == vn_vpath_empty) {
3052      -                /*
3053      -                 * Without v_path from the parent directory, generating a child
3054      -                 * path from the name is impossible.
3055      -                 */
3056      -                if (len > 0) {
3057      -                        pstamp = pvp->v_path_stamp;
3058      -                        mutex_exit(&pvp->v_lock);
3059      -                        vn_clearpath(vp, pstamp);
3060      -                        return;
3061      -                }
     3023 +        rpath = kmem_alloc(rpathalloc, KM_SLEEP);
3062 3024  
3063      -                /*
3064      -                 * The only feasible case here is where a NUL lookup is being
3065      -                 * performed on rootdir prior to its v_path being populated.
3066      -                 */
3067      -                ASSERT(pvp->v_path_stamp = 0);
3068      -                baselen = 0;
3069      -                pstamp = 0;
3070      -        } else {
3071      -                pstamp = pvp->v_path_stamp;
3072      -                baselen = strlen(pvp->v_path);
3073      -                /* ignore a trailing slash if present */
3074      -                if (pvp->v_path[baselen - 1] == '/') {
3075      -                        /* This should only the be case for rootdir */
3076      -                        ASSERT(baselen == 1 && pvp == rootdir);
3077      -                        baselen--;
3078      -                }
3079      -        }
3080      -        mutex_exit(&pvp->v_lock);
3081      -
3082      -        if (buflen != 0) {
3083      -                /* Free the existing (mis-sized) buffer in case of retry */
3084      -                kmem_free(buf, buflen);
3085      -        }
3086      -        /* base, '/', name and trailing NUL */
3087      -        buflen = baselen + len + 2;
3088      -        if (buflen > max_vnode_path) {
3089      -                DTRACE_PROBE4(vn__setpath_too__long, vnode_t *, pvp,
3090      -                    vnode_t *, vp, char *, name, size_t, buflen);
     3025 +        mutex_enter(&base->v_lock);
     3026 +        if (base->v_path == NULL || strlen(base->v_path) != rpathlen) {
     3027 +                mutex_exit(&base->v_lock);
     3028 +                kmem_free(rpath, rpathalloc);
3091 3029                  return;
3092 3030          }
3093      -        buf = kmem_alloc(buflen, KM_SLEEP);
     3031 +        bcopy(base->v_path, rpath, rpathlen);
     3032 +        mutex_exit(&base->v_lock);
3094 3033  
3095      -        mutex_enter(&pvp->v_lock);
3096      -        if (pvp->v_path_stamp != pstamp) {
3097      -                size_t vlen;
     3034 +        if (doslash)
     3035 +                rpath[rpathlen++] = '/';
     3036 +        bcopy(path, rpath + rpathlen, plen);
     3037 +        rpath[rpathlen + plen] = '\0';
3098 3038  
3099      -                /*
3100      -                 * Since v_path_stamp changed on the parent, it is likely that
3101      -                 * v_path has been altered as well.  If the length does not
3102      -                 * exactly match what was previously measured, the buffer
3103      -                 * allocation must be repeated for proper sizing.
3104      -                 */
3105      -                if (pvp->v_path == vn_vpath_empty) {
3106      -                        /* Give up if parent lack v_path */
3107      -                        mutex_exit(&pvp->v_lock);
3108      -                        kmem_free(buf, buflen);
3109      -                        return;
3110      -                }
3111      -                vlen = strlen(pvp->v_path);
3112      -                if (pvp->v_path[vlen - 1] == '/') {
3113      -                        vlen--;
3114      -                }
3115      -                if (vlen != baselen) {
3116      -                        goto retrybuf;
3117      -                }
3118      -        }
3119      -        bcopy(pvp->v_path, buf, baselen);
3120      -        mutex_exit(&pvp->v_lock);
3121      -
3122      -        buf[baselen] = '/';
3123      -        baselen++;
3124      -        bcopy(name, &buf[baselen], len + 1);
3125      -
3126 3039          mutex_enter(&vp->v_lock);
3127      -        if (vp->v_path_stamp == 0) {
3128      -                /* never-visited vnode can inherit stamp from parent */
3129      -                ASSERT(vp->v_path == vn_vpath_empty);
3130      -                vp->v_path_stamp = pstamp;
3131      -                vp->v_path = buf;
     3040 +        if (vp->v_path != NULL) {
3132 3041                  mutex_exit(&vp->v_lock);
3133      -        } else if (vp->v_path_stamp < pstamp || is_rename) {
3134      -                /*
3135      -                 * Install the updated path and stamp, ensuring that the v_path
3136      -                 * pointer is valid at all times for dtrace.
3137      -                 */
3138      -                oldbuf = vp->v_path;
3139      -                vp->v_path = buf;
3140      -                vp->v_path_stamp = gethrtime();
3141      -                mutex_exit(&vp->v_lock);
3142      -                kmem_free(oldbuf, strlen(oldbuf) + 1);
     3042 +                kmem_free(rpath, rpathalloc);
3143 3043          } else {
3144      -                /*
3145      -                 * If the timestamp matches or is greater, it means another
3146      -                 * thread performed the update first while locks were dropped
3147      -                 * here to make the allocation.  We defer to the newer value.
3148      -                 */
     3044 +                vp->v_path = rpath;
3149 3045                  mutex_exit(&vp->v_lock);
3150      -                kmem_free(buf, buflen);
3151 3046          }
3152      -        ASSERT(MUTEX_NOT_HELD(&vp->v_lock));
3153 3047  }
3154 3048  
     3049 +/*
     3050 + * Sets the path to the vnode to be the given string, regardless of current
     3051 + * context.  The string must be a complete path from rootdir.  This is only used
     3052 + * by fsop_root() for setting the path based on the mountpoint.
     3053 + */
3155 3054  void
3156      -vn_updatepath(vnode_t *pvp, vnode_t *vp, const char *name)
     3055 +vn_setpath_str(struct vnode *vp, const char *str, size_t len)
3157 3056  {
3158      -        size_t len;
     3057 +        char *buf = kmem_alloc(len + 1, KM_SLEEP);
3159 3058  
3160      -        /*
3161      -         * If the parent is older or empty, there's nothing further to do.
3162      -         */
3163      -        if (pvp->v_path == vn_vpath_empty ||
3164      -            pvp->v_path_stamp <= vp->v_path_stamp) {
     3059 +        mutex_enter(&vp->v_lock);
     3060 +        if (vp->v_path != NULL) {
     3061 +                mutex_exit(&vp->v_lock);
     3062 +                kmem_free(buf, len + 1);
3165 3063                  return;
3166 3064          }
3167 3065  
3168      -        /*
3169      -         * Given the lack of appropriate context, meaningful updates to v_path
3170      -         * cannot be made for during lookups for the '.' or '..' entries.
3171      -         */
3172      -        len = strlen(name);
3173      -        if (len == 0 || (len == 1 && name[0] == '.') ||
3174      -            (len == 2 && name[0] == '.' && name[1] == '.')) {
3175      -                return;
3176      -        }
     3066 +        vp->v_path = buf;
     3067 +        bcopy(str, vp->v_path, len);
     3068 +        vp->v_path[len] = '\0';
3177 3069  
3178      -        vn_setpath_common(pvp, vp, name, len, B_FALSE);
     3070 +        mutex_exit(&vp->v_lock);
3179 3071  }
3180 3072  
3181 3073  /*
3182      - * Given a starting vnode and a path, updates the path in the target vnode in
3183      - * a safe manner.  If the vnode already has path information embedded, then the
3184      - * cached path is left untouched.
3185      - */
3186      -/* ARGSUSED */
3187      -void
3188      -vn_setpath(vnode_t *rootvp, vnode_t *pvp, vnode_t *vp, const char *name,
3189      -    size_t len)
3190      -{
3191      -        vn_setpath_common(pvp, vp, name, len, B_FALSE);
3192      -}
3193      -
3194      -/*
3195      - * Sets the path to the vnode to be the given string, regardless of current
3196      - * context.  The string must be a complete path from rootdir.  This is only used
3197      - * by fsop_root() for setting the path based on the mountpoint.
3198      - */
3199      -void
3200      -vn_setpath_str(vnode_t *vp, const char *str, size_t len)
3201      -{
3202      -        vn_setpath_common(NULL, vp, str, len, B_FALSE);
3203      -}
3204      -
3205      -/*
3206 3074   * Called from within filesystem's vop_rename() to handle renames once the
3207 3075   * target vnode is available.
3208 3076   */
3209 3077  void
3210      -vn_renamepath(vnode_t *pvp, vnode_t *vp, const char *name, size_t len)
     3078 +vn_renamepath(vnode_t *dvp, vnode_t *vp, const char *nm, size_t len)
3211 3079  {
3212      -        vn_setpath_common(pvp, vp, name, len, B_TRUE);
     3080 +        char *tmp;
     3081 +
     3082 +        mutex_enter(&vp->v_lock);
     3083 +        tmp = vp->v_path;
     3084 +        vp->v_path = NULL;
     3085 +        mutex_exit(&vp->v_lock);
     3086 +        vn_setpath(rootdir, dvp, vp, nm, len);
     3087 +        if (tmp != NULL)
     3088 +                kmem_free(tmp, strlen(tmp) + 1);
3213 3089  }
3214 3090  
3215 3091  /*
3216 3092   * Similar to vn_setpath_str(), this function sets the path of the destination
3217 3093   * vnode to the be the same as the source vnode.
3218 3094   */
3219 3095  void
3220 3096  vn_copypath(struct vnode *src, struct vnode *dst)
3221 3097  {
3222 3098          char *buf;
3223      -        hrtime_t stamp;
3224      -        size_t buflen;
     3099 +        int alloc;
3225 3100  
3226 3101          mutex_enter(&src->v_lock);
3227      -        if (src->v_path == vn_vpath_empty) {
     3102 +        if (src->v_path == NULL) {
3228 3103                  mutex_exit(&src->v_lock);
3229 3104                  return;
3230 3105          }
3231      -        buflen = strlen(src->v_path) + 1;
3232      -        mutex_exit(&src->v_lock);
     3106 +        alloc = strlen(src->v_path) + 1;
3233 3107  
3234      -        buf = kmem_alloc(buflen, KM_SLEEP);
3235      -
     3108 +        /* avoid kmem_alloc() with lock held */
     3109 +        mutex_exit(&src->v_lock);
     3110 +        buf = kmem_alloc(alloc, KM_SLEEP);
3236 3111          mutex_enter(&src->v_lock);
3237      -        if (src->v_path == vn_vpath_empty ||
3238      -            strlen(src->v_path) + 1 != buflen) {
     3112 +        if (src->v_path == NULL || strlen(src->v_path) + 1 != alloc) {
3239 3113                  mutex_exit(&src->v_lock);
3240      -                kmem_free(buf, buflen);
     3114 +                kmem_free(buf, alloc);
3241 3115                  return;
3242 3116          }
3243      -        bcopy(src->v_path, buf, buflen);
3244      -        stamp = src->v_path_stamp;
     3117 +        bcopy(src->v_path, buf, alloc);
3245 3118          mutex_exit(&src->v_lock);
3246 3119  
3247 3120          mutex_enter(&dst->v_lock);
3248      -        if (dst->v_path != vn_vpath_empty) {
     3121 +        if (dst->v_path != NULL) {
3249 3122                  mutex_exit(&dst->v_lock);
3250      -                kmem_free(buf, buflen);
     3123 +                kmem_free(buf, alloc);
3251 3124                  return;
3252 3125          }
3253 3126          dst->v_path = buf;
3254      -        dst->v_path_stamp = stamp;
3255 3127          mutex_exit(&dst->v_lock);
3256 3128  }
3257 3129  
3258      -
3259 3130  /*
3260 3131   * XXX Private interface for segvn routines that handle vnode
3261 3132   * large page segments.
3262 3133   *
3263 3134   * return 1 if vp's file system VOP_PAGEIO() implementation
3264 3135   * can be safely used instead of VOP_GETPAGE() for handling
3265 3136   * pagefaults against regular non swap files. VOP_PAGEIO()
3266 3137   * interface is considered safe here if its implementation
3267 3138   * is very close to VOP_GETPAGE() implementation.
3268 3139   * e.g. It zero's out the part of the page beyond EOF. Doesn't
↓ open down ↓ 168 lines elided ↑ open up ↑
3437 3308                  mutex_exit(&zonep->zone_vfs_lock);
3438 3309  
3439 3310                  lat = gethrtime() - start;
3440 3311  
3441 3312                  if (lat >= VOP_LATENCY_10MS) {
3442 3313                          if (lat < VOP_LATENCY_100MS)
3443 3314                                  atomic_inc_64(&zvp->zv_10ms_ops.value.ui64);
3444 3315                          else if (lat < VOP_LATENCY_1S) {
3445 3316                                  atomic_inc_64(&zvp->zv_10ms_ops.value.ui64);
3446 3317                                  atomic_inc_64(&zvp->zv_100ms_ops.value.ui64);
3447      -                        } else if (lat < VOP_LATENCY_10S) {
3448      -                                atomic_inc_64(&zvp->zv_10ms_ops.value.ui64);
3449      -                                atomic_inc_64(&zvp->zv_100ms_ops.value.ui64);
3450      -                                atomic_inc_64(&zvp->zv_1s_ops.value.ui64);
3451 3318                          } else {
3452 3319                                  atomic_inc_64(&zvp->zv_10ms_ops.value.ui64);
3453 3320                                  atomic_inc_64(&zvp->zv_100ms_ops.value.ui64);
3454 3321                                  atomic_inc_64(&zvp->zv_1s_ops.value.ui64);
3455      -                                atomic_inc_64(&zvp->zv_10s_ops.value.ui64);
3456 3322                          }
3457 3323                  }
3458 3324          }
3459 3325  
3460 3326          return (err);
3461 3327  }
3462 3328  
3463 3329  int
3464 3330  fop_write(
3465 3331          vnode_t *vp,
↓ open down ↓ 39 lines elided ↑ open up ↑
3505 3371                  mutex_exit(&zonep->zone_vfs_lock);
3506 3372  
3507 3373                  lat = gethrtime() - start;
3508 3374  
3509 3375                  if (lat >= VOP_LATENCY_10MS) {
3510 3376                          if (lat < VOP_LATENCY_100MS)
3511 3377                                  atomic_inc_64(&zvp->zv_10ms_ops.value.ui64);
3512 3378                          else if (lat < VOP_LATENCY_1S) {
3513 3379                                  atomic_inc_64(&zvp->zv_10ms_ops.value.ui64);
3514 3380                                  atomic_inc_64(&zvp->zv_100ms_ops.value.ui64);
3515      -                        } else if (lat < VOP_LATENCY_10S) {
3516      -                                atomic_inc_64(&zvp->zv_10ms_ops.value.ui64);
3517      -                                atomic_inc_64(&zvp->zv_100ms_ops.value.ui64);
3518      -                                atomic_inc_64(&zvp->zv_1s_ops.value.ui64);
3519 3381                          } else {
3520 3382                                  atomic_inc_64(&zvp->zv_10ms_ops.value.ui64);
3521 3383                                  atomic_inc_64(&zvp->zv_100ms_ops.value.ui64);
3522 3384                                  atomic_inc_64(&zvp->zv_1s_ops.value.ui64);
3523      -                                atomic_inc_64(&zvp->zv_10s_ops.value.ui64);
3524 3385                          }
3525 3386                  }
3526 3387          }
3527 3388  
3528 3389          return (err);
3529 3390  }
3530 3391  
3531 3392  int
3532 3393  fop_ioctl(
3533 3394          vnode_t *vp,
↓ open down ↓ 147 lines elided ↑ open up ↑
3681 3542          VOPXID_MAP_CR(dvp, cr);
3682 3543  
3683 3544          if ((flags & LOOKUP_XATTR) && (flags & LOOKUP_HAVE_SYSATTR_DIR) == 0) {
3684 3545                  ret = xattr_dir_lookup(dvp, vpp, flags, cr);
3685 3546          } else {
3686 3547                  ret = (*(dvp)->v_op->vop_lookup)
3687 3548                      (dvp, nm, vpp, pnp, flags, rdir, cr, ct, deflags, ppnp);
3688 3549          }
3689 3550          if (ret == 0 && *vpp) {
3690 3551                  VOPSTATS_UPDATE(*vpp, lookup);
3691      -                vn_updatepath(dvp, *vpp, nm);
     3552 +                if ((*vpp)->v_path == NULL) {
     3553 +                        vn_setpath(rootdir, dvp, *vpp, nm, strlen(nm));
     3554 +                }
3692 3555          }
3693 3556  
3694 3557          return (ret);
3695 3558  }
3696 3559  
3697 3560  int
3698 3561  fop_create(
3699 3562          vnode_t *dvp,
3700 3563          char *name,
3701 3564          vattr_t *vap,
↓ open down ↓ 19 lines elided ↑ open up ↑
3721 3584              (vfs_has_feature(dvp->v_vfsp, VFSFT_CASEINSENSITIVE) == 0 &&
3722 3585              vfs_has_feature(dvp->v_vfsp, VFSFT_NOCASESENSITIVE) == 0))
3723 3586                  return (EINVAL);
3724 3587  
3725 3588          VOPXID_MAP_CR(dvp, cr);
3726 3589  
3727 3590          ret = (*(dvp)->v_op->vop_create)
3728 3591              (dvp, name, vap, excl, mode, vpp, cr, flags, ct, vsecp);
3729 3592          if (ret == 0 && *vpp) {
3730 3593                  VOPSTATS_UPDATE(*vpp, create);
3731      -                vn_updatepath(dvp, *vpp, name);
     3594 +                if ((*vpp)->v_path == NULL) {
     3595 +                        vn_setpath(rootdir, dvp, *vpp, name, strlen(name));
     3596 +                }
3732 3597          }
3733 3598  
3734 3599          return (ret);
3735 3600  }
3736 3601  
3737 3602  int
3738 3603  fop_remove(
3739 3604          vnode_t *dvp,
3740 3605          char *nm,
3741 3606          cred_t *cr,
↓ open down ↓ 99 lines elided ↑ open up ↑
3841 3706              (vfs_has_feature(dvp->v_vfsp, VFSFT_CASEINSENSITIVE) == 0 &&
3842 3707              vfs_has_feature(dvp->v_vfsp, VFSFT_NOCASESENSITIVE) == 0))
3843 3708                  return (EINVAL);
3844 3709  
3845 3710          VOPXID_MAP_CR(dvp, cr);
3846 3711  
3847 3712          ret = (*(dvp)->v_op->vop_mkdir)
3848 3713              (dvp, dirname, vap, vpp, cr, ct, flags, vsecp);
3849 3714          if (ret == 0 && *vpp) {
3850 3715                  VOPSTATS_UPDATE(*vpp, mkdir);
3851      -                vn_updatepath(dvp, *vpp, dirname);
     3716 +                if ((*vpp)->v_path == NULL) {
     3717 +                        vn_setpath(rootdir, dvp, *vpp, dirname,
     3718 +                            strlen(dirname));
     3719 +                }
3852 3720          }
3853 3721  
3854 3722          return (ret);
3855 3723  }
3856 3724  
3857 3725  int
3858 3726  fop_rmdir(
3859 3727          vnode_t *dvp,
3860 3728          char *nm,
3861 3729          vnode_t *cdir,
↓ open down ↓ 946 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX