Print this page
XXXXX convert NLM's single-count semaphore to a mutex


 846 
 847         /*
 848          * Create an RPC handle that'll be used for communication with local
 849          * statd using the status monitor protocol.
 850          */
 851         error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, SM_PROG, SM_VERS,
 852             0, NLM_RPC_RETRIES, zone_kcred(), &nsm->ns_handle);
 853         if (error != 0)
 854                 goto error;
 855 
 856         /*
 857          * Create an RPC handle that'll be used for communication with the
 858          * local statd using the address registration protocol.
 859          */
 860         error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, NSM_ADDR_PROGRAM,
 861             NSM_ADDR_V1, 0, NLM_RPC_RETRIES, zone_kcred(),
 862             &nsm->ns_addr_handle);
 863         if (error != 0)
 864                 goto error;
 865 
 866         sema_init(&nsm->ns_sem, 1, NULL, SEMA_DEFAULT, NULL);
 867         return (0);
 868 
 869 error:
 870         kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
 871         if (nsm->ns_handle) {
 872                 ASSERT(nsm->ns_handle->cl_auth != NULL);
 873                 auth_destroy(nsm->ns_handle->cl_auth);
 874                 CLNT_DESTROY(nsm->ns_handle);
 875         }
 876 
 877         return (error);
 878 }
 879 
 880 static void
 881 nlm_nsm_fini(struct nlm_nsm *nsm)
 882 {
 883         kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
 884         if (nsm->ns_addr_handle->cl_auth != NULL)
 885                 auth_destroy(nsm->ns_addr_handle->cl_auth);
 886         CLNT_DESTROY(nsm->ns_addr_handle);
 887         nsm->ns_addr_handle = NULL;
 888         if (nsm->ns_handle->cl_auth != NULL)
 889                 auth_destroy(nsm->ns_handle->cl_auth);
 890         CLNT_DESTROY(nsm->ns_handle);
 891         nsm->ns_handle = NULL;
 892         sema_destroy(&nsm->ns_sem);
 893 }
 894 
 895 static enum clnt_stat
 896 nlm_nsm_simu_crash(struct nlm_nsm *nsm)
 897 {
 898         enum clnt_stat stat;
 899 
 900         sema_p(&nsm->ns_sem);
 901         nlm_nsm_clnt_init(nsm->ns_handle, nsm);
 902         stat = sm_simu_crash_1(NULL, NULL, nsm->ns_handle);
 903         sema_v(&nsm->ns_sem);
 904 
 905         return (stat);
 906 }
 907 
 908 static enum clnt_stat
 909 nlm_nsm_stat(struct nlm_nsm *nsm, int32_t *out_stat)
 910 {
 911         struct sm_name args;
 912         struct sm_stat_res res;
 913         enum clnt_stat stat;
 914 
 915         args.mon_name = uts_nodename();
 916         bzero(&res, sizeof (res));
 917 
 918         sema_p(&nsm->ns_sem);
 919         nlm_nsm_clnt_init(nsm->ns_handle, nsm);
 920         stat = sm_stat_1(&args, &res, nsm->ns_handle);
 921         sema_v(&nsm->ns_sem);
 922 
 923         if (stat == RPC_SUCCESS)
 924                 *out_stat = res.state;
 925 
 926         return (stat);
 927 }
 928 
 929 static enum clnt_stat
 930 nlm_nsm_mon(struct nlm_nsm *nsm, char *hostname, uint16_t priv)
 931 {
 932         struct mon args;
 933         struct sm_stat_res res;
 934         enum clnt_stat stat;
 935 
 936         bzero(&args, sizeof (args));
 937         bzero(&res, sizeof (res));
 938 
 939         args.mon_id.mon_name = hostname;
 940         args.mon_id.my_id.my_name = uts_nodename();
 941         args.mon_id.my_id.my_prog = NLM_PROG;
 942         args.mon_id.my_id.my_vers = NLM_SM;
 943         args.mon_id.my_id.my_proc = NLM_SM_NOTIFY1;
 944         bcopy(&priv, args.priv, sizeof (priv));
 945 
 946         sema_p(&nsm->ns_sem);
 947         nlm_nsm_clnt_init(nsm->ns_handle, nsm);
 948         stat = sm_mon_1(&args, &res, nsm->ns_handle);
 949         sema_v(&nsm->ns_sem);
 950 
 951         return (stat);
 952 }
 953 
 954 static enum clnt_stat
 955 nlm_nsm_unmon(struct nlm_nsm *nsm, char *hostname)
 956 {
 957         struct mon_id args;
 958         struct sm_stat res;
 959         enum clnt_stat stat;
 960 
 961         bzero(&args, sizeof (args));
 962         bzero(&res, sizeof (res));
 963 
 964         args.mon_name = hostname;
 965         args.my_id.my_name = uts_nodename();
 966         args.my_id.my_prog = NLM_PROG;
 967         args.my_id.my_vers = NLM_SM;
 968         args.my_id.my_proc = NLM_SM_NOTIFY1;
 969 
 970         sema_p(&nsm->ns_sem);
 971         nlm_nsm_clnt_init(nsm->ns_handle, nsm);
 972         stat = sm_unmon_1(&args, &res, nsm->ns_handle);
 973         sema_v(&nsm->ns_sem);
 974 
 975         return (stat);
 976 }
 977 
 978 static enum clnt_stat
 979 nlm_nsmaddr_reg(struct nlm_nsm *nsm, char *name, int family, netobj *address)
 980 {
 981         struct reg1args args = { 0 };
 982         struct reg1res res = { 0 };
 983         enum clnt_stat stat;
 984 
 985         args.family = family;
 986         args.name = name;
 987         args.address = *address;
 988 
 989         sema_p(&nsm->ns_sem);
 990         nlm_nsm_clnt_init(nsm->ns_addr_handle, nsm);
 991         stat = nsmaddrproc1_reg_1(&args, &res, nsm->ns_addr_handle);
 992         sema_v(&nsm->ns_sem);
 993 
 994         return (stat);
 995 }
 996 
 997 /*
 998  * Get NLM vhold object corresponding to vnode "vp".
 999  * If no such object was found, create a new one.
1000  *
1001  * The purpose of this function is to associate vhold
1002  * object with given vnode, so that:
1003  * 1) vnode is hold (VN_HOLD) while vhold object is alive.
1004  * 2) host has a track of all vnodes it touched by lock
1005  *    or share operations. These vnodes are accessible
1006  *    via collection of vhold objects.
1007  */
1008 struct nlm_vhold *
1009 nlm_vhold_get(struct nlm_host *hostp, vnode_t *vp)
1010 {
1011         struct nlm_vhold *nvp, *new_nvp = NULL;
1012 




 846 
 847         /*
 848          * Create an RPC handle that'll be used for communication with local
 849          * statd using the status monitor protocol.
 850          */
 851         error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, SM_PROG, SM_VERS,
 852             0, NLM_RPC_RETRIES, zone_kcred(), &nsm->ns_handle);
 853         if (error != 0)
 854                 goto error;
 855 
 856         /*
 857          * Create an RPC handle that'll be used for communication with the
 858          * local statd using the address registration protocol.
 859          */
 860         error = clnt_tli_kcreate(&nsm->ns_knc, &nsm->ns_addr, NSM_ADDR_PROGRAM,
 861             NSM_ADDR_V1, 0, NLM_RPC_RETRIES, zone_kcred(),
 862             &nsm->ns_addr_handle);
 863         if (error != 0)
 864                 goto error;
 865 
 866         mutex_init(&nsm->ns_lock, NULL, MUTEX_DEFAULT, NULL);
 867         return (0);
 868 
 869 error:
 870         kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
 871         if (nsm->ns_handle) {
 872                 ASSERT(nsm->ns_handle->cl_auth != NULL);
 873                 auth_destroy(nsm->ns_handle->cl_auth);
 874                 CLNT_DESTROY(nsm->ns_handle);
 875         }
 876 
 877         return (error);
 878 }
 879 
 880 static void
 881 nlm_nsm_fini(struct nlm_nsm *nsm)
 882 {
 883         kmem_free(nsm->ns_addr.buf, nsm->ns_addr.maxlen);
 884         if (nsm->ns_addr_handle->cl_auth != NULL)
 885                 auth_destroy(nsm->ns_addr_handle->cl_auth);
 886         CLNT_DESTROY(nsm->ns_addr_handle);
 887         nsm->ns_addr_handle = NULL;
 888         if (nsm->ns_handle->cl_auth != NULL)
 889                 auth_destroy(nsm->ns_handle->cl_auth);
 890         CLNT_DESTROY(nsm->ns_handle);
 891         nsm->ns_handle = NULL;
 892         mutex_destroy(&nsm->ns_lock);
 893 }
 894 
 895 static enum clnt_stat
 896 nlm_nsm_simu_crash(struct nlm_nsm *nsm)
 897 {
 898         enum clnt_stat stat;
 899 
 900         mutex_enter(&nsm->ns_lock);
 901         nlm_nsm_clnt_init(nsm->ns_handle, nsm);
 902         stat = sm_simu_crash_1(NULL, NULL, nsm->ns_handle);
 903         mutex_exit(&nsm->ns_lock);
 904 
 905         return (stat);
 906 }
 907 
 908 static enum clnt_stat
 909 nlm_nsm_stat(struct nlm_nsm *nsm, int32_t *out_stat)
 910 {
 911         struct sm_name args;
 912         struct sm_stat_res res;
 913         enum clnt_stat stat;
 914 
 915         args.mon_name = uts_nodename();
 916         bzero(&res, sizeof (res));
 917 
 918         mutex_enter(&nsm->ns_lock);
 919         nlm_nsm_clnt_init(nsm->ns_handle, nsm);
 920         stat = sm_stat_1(&args, &res, nsm->ns_handle);
 921         mutex_exit(&nsm->ns_lock);
 922 
 923         if (stat == RPC_SUCCESS)
 924                 *out_stat = res.state;
 925 
 926         return (stat);
 927 }
 928 
 929 static enum clnt_stat
 930 nlm_nsm_mon(struct nlm_nsm *nsm, char *hostname, uint16_t priv)
 931 {
 932         struct mon args;
 933         struct sm_stat_res res;
 934         enum clnt_stat stat;
 935 
 936         bzero(&args, sizeof (args));
 937         bzero(&res, sizeof (res));
 938 
 939         args.mon_id.mon_name = hostname;
 940         args.mon_id.my_id.my_name = uts_nodename();
 941         args.mon_id.my_id.my_prog = NLM_PROG;
 942         args.mon_id.my_id.my_vers = NLM_SM;
 943         args.mon_id.my_id.my_proc = NLM_SM_NOTIFY1;
 944         bcopy(&priv, args.priv, sizeof (priv));
 945 
 946         mutex_enter(&nsm->ns_lock);
 947         nlm_nsm_clnt_init(nsm->ns_handle, nsm);
 948         stat = sm_mon_1(&args, &res, nsm->ns_handle);
 949         mutex_exit(&nsm->ns_lock);
 950 
 951         return (stat);
 952 }
 953 
 954 static enum clnt_stat
 955 nlm_nsm_unmon(struct nlm_nsm *nsm, char *hostname)
 956 {
 957         struct mon_id args;
 958         struct sm_stat res;
 959         enum clnt_stat stat;
 960 
 961         bzero(&args, sizeof (args));
 962         bzero(&res, sizeof (res));
 963 
 964         args.mon_name = hostname;
 965         args.my_id.my_name = uts_nodename();
 966         args.my_id.my_prog = NLM_PROG;
 967         args.my_id.my_vers = NLM_SM;
 968         args.my_id.my_proc = NLM_SM_NOTIFY1;
 969 
 970         mutex_enter(&nsm->ns_lock);
 971         nlm_nsm_clnt_init(nsm->ns_handle, nsm);
 972         stat = sm_unmon_1(&args, &res, nsm->ns_handle);
 973         mutex_exit(&nsm->ns_lock);
 974 
 975         return (stat);
 976 }
 977 
 978 static enum clnt_stat
 979 nlm_nsmaddr_reg(struct nlm_nsm *nsm, char *name, int family, netobj *address)
 980 {
 981         struct reg1args args = { 0 };
 982         struct reg1res res = { 0 };
 983         enum clnt_stat stat;
 984 
 985         args.family = family;
 986         args.name = name;
 987         args.address = *address;
 988 
 989         mutex_enter(&nsm->ns_lock);
 990         nlm_nsm_clnt_init(nsm->ns_addr_handle, nsm);
 991         stat = nsmaddrproc1_reg_1(&args, &res, nsm->ns_addr_handle);
 992         mutex_exit(&nsm->ns_lock);
 993 
 994         return (stat);
 995 }
 996 
 997 /*
 998  * Get NLM vhold object corresponding to vnode "vp".
 999  * If no such object was found, create a new one.
1000  *
1001  * The purpose of this function is to associate vhold
1002  * object with given vnode, so that:
1003  * 1) vnode is hold (VN_HOLD) while vhold object is alive.
1004  * 2) host has a track of all vnodes it touched by lock
1005  *    or share operations. These vnodes are accessible
1006  *    via collection of vhold objects.
1007  */
1008 struct nlm_vhold *
1009 nlm_vhold_get(struct nlm_host *hostp, vnode_t *vp)
1010 {
1011         struct nlm_vhold *nvp, *new_nvp = NULL;
1012