Print this page
Caution with use after exi_rele()
Be far more judicious in the use of curzone-using macros.
(Merge and extra asserts by danmcd.)


2930 
2931                 if (error == ENOENT) {
2932                         *vpp = tvp;
2933                         mc_dvp = tmc_dvp;
2934                         error = 0;
2935                 } else {        /* ok or error other than ENOENT */
2936                         if (tmc_dvp)
2937                                 VN_RELE(tmc_dvp);
2938                         if (error)
2939                                 goto publicfh_done;
2940 
2941                         /*
2942                          * Found a valid vp for index "filename". Sanity check
2943                          * for odd case where a directory is provided as index
2944                          * option argument and leads us to another filesystem
2945                          */
2946 
2947                         /* Release the reference on the old exi value */
2948                         ASSERT(*exi != NULL);
2949                         exi_rele(*exi);

2950 
2951                         if (error = nfs_check_vpexi(mc_dvp, *vpp, kcred, exi)) {
2952                                 VN_RELE(*vpp);
2953                                 goto publicfh_done;
2954                         }

2955                 }
2956         }
2957 
2958 publicfh_done:
2959         if (mc_dvp)
2960                 VN_RELE(mc_dvp);
2961 
2962         return (error);
2963 }
2964 
2965 /*
2966  * Evaluate a multi-component path
2967  */
2968 int
2969 rfs_pathname(
2970         char *path,                     /* pathname to evaluate */
2971         vnode_t **dirvpp,               /* ret for ptr to parent dir vnode */
2972         vnode_t **compvpp,              /* ret for ptr to component vnode */
2973         vnode_t *startdvp,              /* starting vnode */
2974         cred_t *cr,                     /* user's credential */
2975         int pathflag)                   /* flag to identify path, e.g. URL */
2976 {
2977         char namebuf[TYPICALMAXPATHLEN];
2978         struct pathname pn;
2979         int error;
2980 


2981         /*
2982          * If pathname starts with '/', then set startdvp to root.
2983          */
2984         if (*path == '/') {
2985                 while (*path == '/')
2986                         path++;
2987 
2988                 startdvp = ZONE_ROOTVP();
2989         }
2990 
2991         error = pn_get_buf(path, UIO_SYSSPACE, &pn, namebuf, sizeof (namebuf));
2992         if (error == 0) {
2993                 /*
2994                  * Call the URL parser for URL paths to modify the original
2995                  * string to handle any '%' encoded characters that exist.
2996                  * Done here to avoid an extra bcopy in the lookup.
2997                  * We need to be careful about pathlen's. We know that
2998                  * rfs_pathname() is called with a non-empty path. However,
2999                  * it could be emptied due to the path simply being all /'s,
3000                  * which is valid to proceed with the lookup, or due to the




2930 
2931                 if (error == ENOENT) {
2932                         *vpp = tvp;
2933                         mc_dvp = tmc_dvp;
2934                         error = 0;
2935                 } else {        /* ok or error other than ENOENT */
2936                         if (tmc_dvp)
2937                                 VN_RELE(tmc_dvp);
2938                         if (error)
2939                                 goto publicfh_done;
2940 
2941                         /*
2942                          * Found a valid vp for index "filename". Sanity check
2943                          * for odd case where a directory is provided as index
2944                          * option argument and leads us to another filesystem
2945                          */
2946 
2947                         /* Release the reference on the old exi value */
2948                         ASSERT(*exi != NULL);
2949                         exi_rele(*exi);
2950                         *exi = NULL;
2951 
2952                         if (error = nfs_check_vpexi(mc_dvp, *vpp, kcred, exi)) {
2953                                 VN_RELE(*vpp);
2954                                 goto publicfh_done;
2955                         }
2956                         /* Have a new *exi */
2957                 }
2958         }
2959 
2960 publicfh_done:
2961         if (mc_dvp)
2962                 VN_RELE(mc_dvp);
2963 
2964         return (error);
2965 }
2966 
2967 /*
2968  * Evaluate a multi-component path
2969  */
2970 int
2971 rfs_pathname(
2972         char *path,                     /* pathname to evaluate */
2973         vnode_t **dirvpp,               /* ret for ptr to parent dir vnode */
2974         vnode_t **compvpp,              /* ret for ptr to component vnode */
2975         vnode_t *startdvp,              /* starting vnode */
2976         cred_t *cr,                     /* user's credential */
2977         int pathflag)                   /* flag to identify path, e.g. URL */
2978 {
2979         char namebuf[TYPICALMAXPATHLEN];
2980         struct pathname pn;
2981         int error;
2982 
2983         ASSERT3U(crgetzoneid(cr), ==, curzone->zone_id);
2984 
2985         /*
2986          * If pathname starts with '/', then set startdvp to root.
2987          */
2988         if (*path == '/') {
2989                 while (*path == '/')
2990                         path++;
2991 
2992                 startdvp = ZONE_ROOTVP();
2993         }
2994 
2995         error = pn_get_buf(path, UIO_SYSSPACE, &pn, namebuf, sizeof (namebuf));
2996         if (error == 0) {
2997                 /*
2998                  * Call the URL parser for URL paths to modify the original
2999                  * string to handle any '%' encoded characters that exist.
3000                  * Done here to avoid an extra bcopy in the lookup.
3001                  * We need to be careful about pathlen's. We know that
3002                  * rfs_pathname() is called with a non-empty path. However,
3003                  * it could be emptied due to the path simply being all /'s,
3004                  * which is valid to proceed with the lookup, or due to the