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 /*
|