118         }
 119 
 120         startvp = vp;
 121 next:
 122         retry_with_kcred = B_FALSE;
 123 
 124         /*
 125          * Make sure we have a directory.
 126          */
 127         if (vp->v_type != VDIR) {
 128                 error = ENOTDIR;
 129                 goto bad;
 130         }
 131 
 132         if (rpnp && VN_CMP(vp, rootvp))
 133                 (void) pn_set(rpnp, "/");
 134 
 135         /*
 136          * Process the next component of the pathname.
 137          */
 138         if (error = pn_getcomponent(pnp, component)) {
 139                 goto bad;
 140         }
 141 
 142         /*
 143          * Handle "..": two special cases.
 144          * 1. If we're at the root directory (e.g. after chroot or
 145          *    zone_enter) then change ".." to "." so we can't get
 146          *    out of this subtree.
 147          * 2. If this vnode is the root of a mounted file system,
 148          *    then replace it with the vnode that was mounted on
 149          *    so that we take the ".." in the other file system.
 150          */
 151         if (component[0] == '.' && component[1] == '.' && component[2] == 0) {
 152 checkforroot:
 153                 if (VN_CMP(vp, rootvp)) {
 154                         component[1] = '\0';
 155                 } else if (vp->v_flag & VROOT) {
 156                         vfs_t *vfsp;
 157                         cvp = vp;
 158 
 
 290                         cvp = tvp;
 291                         goto bad;
 292                 }
 293                 cvp = tvp;
 294         }
 295 
 296         /*
 297          * If we hit a symbolic link and there is more path to be
 298          * translated or this operation does not wish to apply
 299          * to a link, then place the contents of the link at the
 300          * front of the remaining pathname.
 301          */
 302         if (cvp->v_type == VLNK && ((flags & FOLLOW) || pn_pathleft(pnp))) {
 303                 struct pathname linkpath;
 304 
 305                 if (++nlink > MAXSYMLINKS) {
 306                         error = ELOOP;
 307                         goto bad;
 308                 }
 309                 pn_alloc(&linkpath);
 310                 if (error = pn_getsymlink(cvp, &linkpath, cr)) {
 311                         pn_free(&linkpath);
 312                         goto bad;
 313                 }
 314 
 315                 if (pn_pathleft(&linkpath) == 0)
 316                         (void) pn_set(&linkpath, ".");
 317                 error = pn_insert(pnp, &linkpath, strlen(component));
 318                 pn_free(&linkpath);
 319                 if (error)
 320                         goto bad;
 321                 VN_RELE(cvp);
 322                 cvp = NULL;
 323                 if (pnp->pn_pathlen == 0) {
 324                         error = ENOENT;
 325                         goto bad;
 326                 }
 327                 if (pnp->pn_path[0] == '/') {
 328                         do {
 329                                 pnp->pn_path++;
 330                                 pnp->pn_pathlen--;
 
 | 
 
 
 118         }
 119 
 120         startvp = vp;
 121 next:
 122         retry_with_kcred = B_FALSE;
 123 
 124         /*
 125          * Make sure we have a directory.
 126          */
 127         if (vp->v_type != VDIR) {
 128                 error = ENOTDIR;
 129                 goto bad;
 130         }
 131 
 132         if (rpnp && VN_CMP(vp, rootvp))
 133                 (void) pn_set(rpnp, "/");
 134 
 135         /*
 136          * Process the next component of the pathname.
 137          */
 138         if ((error = pn_getcomponent(pnp, component)) != 0) {
 139                 goto bad;
 140         }
 141 
 142         /*
 143          * Handle "..": two special cases.
 144          * 1. If we're at the root directory (e.g. after chroot or
 145          *    zone_enter) then change ".." to "." so we can't get
 146          *    out of this subtree.
 147          * 2. If this vnode is the root of a mounted file system,
 148          *    then replace it with the vnode that was mounted on
 149          *    so that we take the ".." in the other file system.
 150          */
 151         if (component[0] == '.' && component[1] == '.' && component[2] == 0) {
 152 checkforroot:
 153                 if (VN_CMP(vp, rootvp)) {
 154                         component[1] = '\0';
 155                 } else if (vp->v_flag & VROOT) {
 156                         vfs_t *vfsp;
 157                         cvp = vp;
 158 
 
 290                         cvp = tvp;
 291                         goto bad;
 292                 }
 293                 cvp = tvp;
 294         }
 295 
 296         /*
 297          * If we hit a symbolic link and there is more path to be
 298          * translated or this operation does not wish to apply
 299          * to a link, then place the contents of the link at the
 300          * front of the remaining pathname.
 301          */
 302         if (cvp->v_type == VLNK && ((flags & FOLLOW) || pn_pathleft(pnp))) {
 303                 struct pathname linkpath;
 304 
 305                 if (++nlink > MAXSYMLINKS) {
 306                         error = ELOOP;
 307                         goto bad;
 308                 }
 309                 pn_alloc(&linkpath);
 310                 if ((error = pn_getsymlink(cvp, &linkpath, cr)) != 0) {
 311                         pn_free(&linkpath);
 312                         goto bad;
 313                 }
 314 
 315                 if (pn_pathleft(&linkpath) == 0)
 316                         (void) pn_set(&linkpath, ".");
 317                 error = pn_insert(pnp, &linkpath, strlen(component));
 318                 pn_free(&linkpath);
 319                 if (error)
 320                         goto bad;
 321                 VN_RELE(cvp);
 322                 cvp = NULL;
 323                 if (pnp->pn_pathlen == 0) {
 324                         error = ENOENT;
 325                         goto bad;
 326                 }
 327                 if (pnp->pn_path[0] == '/') {
 328                         do {
 329                                 pnp->pn_path++;
 330                                 pnp->pn_pathlen--;
 
 |