Print this page
*** NO COMMENTS ***


2582  */
2583 
2584 /*
2585  * Public filehandle evaluation of a multi-component lookup, following
2586  * symbolic links, if necessary. This may result in a vnode in another
2587  * filesystem, which is OK as long as the other filesystem is exported.
2588  *
2589  * Note that the exi will be set either to NULL or a new reference to the
2590  * exportinfo struct that corresponds to the vnode of the multi-component path.
2591  * It is the callers responsibility to release this reference.
2592  */
2593 int
2594 rfs_publicfh_mclookup(char *p, vnode_t *dvp, cred_t *cr, vnode_t **vpp,
2595     struct exportinfo **exi, struct sec_ol *sec)
2596 {
2597         int pathflag;
2598         vnode_t *mc_dvp = NULL;
2599         vnode_t *realvp;
2600         int error;
2601 
2602         *exi = NULL;
2603 
2604         /*
2605          * check if the given path is a url or native path. Since p is
2606          * modified by MCLpath(), it may be empty after returning from
2607          * there, and should be checked.
2608          */
2609         if ((pathflag = MCLpath(&p)) == -1)
2610                 return (EIO);
2611 
2612         /*
2613          * If pathflag is SECURITY_QUERY, turn the SEC_QUERY bit
2614          * on in sec->sec_flags. This bit will later serve as an
2615          * indication in makefh_ol() or makefh3_ol() to overload the
2616          * filehandle to contain the sec modes used by the server for
2617          * the path.
2618          */
2619         if (pathflag == SECURITY_QUERY) {
2620                 if ((sec->sec_index = (uint_t)(*p)) > 0) {
2621                         sec->sec_flags |= SEC_QUERY;
2622                         p++;
2623                         if ((pathflag = MCLpath(&p)) == -1)


2783                 error = rfs_pathname((*exi)->exi_export.ex_index, NULL, vpp,
2784                     mc_dvp, cr, NATIVEPATH);
2785 
2786                 if (error == ENOENT) {
2787                         *vpp = tvp;
2788                         mc_dvp = tmc_dvp;
2789                         error = 0;
2790                 } else {        /* ok or error other than ENOENT */
2791                         if (tmc_dvp)
2792                                 VN_RELE(tmc_dvp);
2793                         if (error)
2794                                 goto publicfh_done;
2795 
2796                         /*
2797                          * Found a valid vp for index "filename". Sanity check
2798                          * for odd case where a directory is provided as index
2799                          * option argument and leads us to another filesystem
2800                          */
2801 
2802                         /* Release the reference on the old exi value */
2803                         ASSERT(*exi != NULL);
2804                         exi_rele(*exi);

2805 
2806                         if (error = nfs_check_vpexi(mc_dvp, *vpp, kcred, exi)) {
2807                                 VN_RELE(*vpp);
2808                                 goto publicfh_done;
2809                         }
2810                 }
2811         }
2812 
2813 publicfh_done:
2814         if (mc_dvp)
2815                 VN_RELE(mc_dvp);
2816 



2817         return (error);
2818 }
2819 
2820 /*
2821  * Evaluate a multi-component path
2822  */
2823 int
2824 rfs_pathname(
2825         char *path,                     /* pathname to evaluate */
2826         vnode_t **dirvpp,               /* ret for ptr to parent dir vnode */
2827         vnode_t **compvpp,              /* ret for ptr to component vnode */
2828         vnode_t *startdvp,              /* starting vnode */
2829         cred_t *cr,                     /* user's credential */
2830         int pathflag)                   /* flag to identify path, e.g. URL */
2831 {
2832         char namebuf[TYPICALMAXPATHLEN];
2833         struct pathname pn;
2834         int error;
2835 
2836         /*


2942                 *q = *p;
2943                 if (*p++ == '%') {
2944                         if (*p) {
2945                                 *q = fromhex(*p) * 16;
2946                                 p++;
2947                                 if (*p) {
2948                                         *q += fromhex(*p);
2949                                         p++;
2950                                 }
2951                         }
2952                 }
2953                 q++;
2954         }
2955         *q = '\0';
2956 }
2957 
2958 
2959 /*
2960  * Get the export information for the lookup vnode, and verify its
2961  * useable.


2962  */
2963 int
2964 nfs_check_vpexi(vnode_t *mc_dvp, vnode_t *vp, cred_t *cr,
2965     struct exportinfo **exi)
2966 {
2967         int walk;
2968         int error = 0;

2969 
2970         *exi = nfs_vptoexi(mc_dvp, vp, cr, &walk, NULL, FALSE);
2971         if (*exi == NULL)
2972                 error = EACCES;
2973         else {
2974                 /*
2975                  * If nosub is set for this export then
2976                  * a lookup relative to the public fh
2977                  * must not terminate below the
2978                  * exported directory.
2979                  */
2980                 if ((*exi)->exi_export.ex_flags & EX_NOSUB && walk > 0)
2981                         error = EACCES;

2982         }
2983 


2984         return (error);
2985 }
2986 
2987 /*
2988  * Do the main work of handling HA-NFSv4 Resource Group failover on
2989  * Sun Cluster.
2990  * We need to detect whether any RG admin paths have been added or removed,
2991  * and adjust resources accordingly.
2992  * Currently we're using a very inefficient algorithm, ~ 2 * O(n**2). In
2993  * order to scale, the list and array of paths need to be held in more
2994  * suitable data structures.
2995  */
2996 static void
2997 hanfsv4_failover(void)
2998 {
2999         int i, start_grace, numadded_paths = 0;
3000         char **added_paths = NULL;
3001         rfs4_dss_path_t *dss_path;
3002 
3003         /*




2582  */
2583 
2584 /*
2585  * Public filehandle evaluation of a multi-component lookup, following
2586  * symbolic links, if necessary. This may result in a vnode in another
2587  * filesystem, which is OK as long as the other filesystem is exported.
2588  *
2589  * Note that the exi will be set either to NULL or a new reference to the
2590  * exportinfo struct that corresponds to the vnode of the multi-component path.
2591  * It is the callers responsibility to release this reference.
2592  */
2593 int
2594 rfs_publicfh_mclookup(char *p, vnode_t *dvp, cred_t *cr, vnode_t **vpp,
2595     struct exportinfo **exi, struct sec_ol *sec)
2596 {
2597         int pathflag;
2598         vnode_t *mc_dvp = NULL;
2599         vnode_t *realvp;
2600         int error;
2601 


2602         /*
2603          * check if the given path is a url or native path. Since p is
2604          * modified by MCLpath(), it may be empty after returning from
2605          * there, and should be checked.
2606          */
2607         if ((pathflag = MCLpath(&p)) == -1)
2608                 return (EIO);
2609 
2610         /*
2611          * If pathflag is SECURITY_QUERY, turn the SEC_QUERY bit
2612          * on in sec->sec_flags. This bit will later serve as an
2613          * indication in makefh_ol() or makefh3_ol() to overload the
2614          * filehandle to contain the sec modes used by the server for
2615          * the path.
2616          */
2617         if (pathflag == SECURITY_QUERY) {
2618                 if ((sec->sec_index = (uint_t)(*p)) > 0) {
2619                         sec->sec_flags |= SEC_QUERY;
2620                         p++;
2621                         if ((pathflag = MCLpath(&p)) == -1)


2781                 error = rfs_pathname((*exi)->exi_export.ex_index, NULL, vpp,
2782                     mc_dvp, cr, NATIVEPATH);
2783 
2784                 if (error == ENOENT) {
2785                         *vpp = tvp;
2786                         mc_dvp = tmc_dvp;
2787                         error = 0;
2788                 } else {        /* ok or error other than ENOENT */
2789                         if (tmc_dvp)
2790                                 VN_RELE(tmc_dvp);
2791                         if (error)
2792                                 goto publicfh_done;
2793 
2794                         /*
2795                          * Found a valid vp for index "filename". Sanity check
2796                          * for odd case where a directory is provided as index
2797                          * option argument and leads us to another filesystem
2798                          */
2799 
2800                         /* Release the reference on the old exi value */

2801                         exi_rele(*exi);
2802                         *exi = NULL;
2803 
2804                         if (error = nfs_check_vpexi(mc_dvp, *vpp, kcred, exi)) {
2805                                 VN_RELE(*vpp);
2806                                 goto publicfh_done;
2807                         }
2808                 }
2809         }
2810 
2811 publicfh_done:
2812         if (mc_dvp)
2813                 VN_RELE(mc_dvp);
2814 
2815         if (error && *exi != NULL)
2816                 exi_rele(*exi);
2817 
2818         return (error);
2819 }
2820 
2821 /*
2822  * Evaluate a multi-component path
2823  */
2824 int
2825 rfs_pathname(
2826         char *path,                     /* pathname to evaluate */
2827         vnode_t **dirvpp,               /* ret for ptr to parent dir vnode */
2828         vnode_t **compvpp,              /* ret for ptr to component vnode */
2829         vnode_t *startdvp,              /* starting vnode */
2830         cred_t *cr,                     /* user's credential */
2831         int pathflag)                   /* flag to identify path, e.g. URL */
2832 {
2833         char namebuf[TYPICALMAXPATHLEN];
2834         struct pathname pn;
2835         int error;
2836 
2837         /*


2943                 *q = *p;
2944                 if (*p++ == '%') {
2945                         if (*p) {
2946                                 *q = fromhex(*p) * 16;
2947                                 p++;
2948                                 if (*p) {
2949                                         *q += fromhex(*p);
2950                                         p++;
2951                                 }
2952                         }
2953                 }
2954                 q++;
2955         }
2956         *q = '\0';
2957 }
2958 
2959 
2960 /*
2961  * Get the export information for the lookup vnode, and verify its
2962  * useable.
2963  *
2964  * Set @exip only in success
2965  */
2966 int
2967 nfs_check_vpexi(vnode_t *mc_dvp, vnode_t *vp, cred_t *cr,
2968     struct exportinfo **exip)
2969 {
2970         int walk;
2971         int error = 0;
2972         struct exportinfo *exi;
2973 
2974         exi = nfs_vptoexi(mc_dvp, vp, cr, &walk, NULL, FALSE);
2975         if (exi == NULL)
2976                 error = EACCES;
2977         else {
2978                 /*
2979                  * If nosub is set for this export then
2980                  * a lookup relative to the public fh
2981                  * must not terminate below the
2982                  * exported directory.
2983                  */
2984                 if (exi->exi_export.ex_flags & EX_NOSUB && walk > 0) {
2985                         error = EACCES;
2986                         exi_rele(exi);
2987                 }
2988         }
2989         if (error == 0)
2990                 *exip = exi;
2991         return (error);
2992 }
2993 
2994 /*
2995  * Do the main work of handling HA-NFSv4 Resource Group failover on
2996  * Sun Cluster.
2997  * We need to detect whether any RG admin paths have been added or removed,
2998  * and adjust resources accordingly.
2999  * Currently we're using a very inefficient algorithm, ~ 2 * O(n**2). In
3000  * order to scale, the list and array of paths need to be held in more
3001  * suitable data structures.
3002  */
3003 static void
3004 hanfsv4_failover(void)
3005 {
3006         int i, start_grace, numadded_paths = 0;
3007         char **added_paths = NULL;
3008         rfs4_dss_path_t *dss_path;
3009 
3010         /*