nfs-ganesha 1.4

nlm_owner.c

Go to the documentation of this file.
00001 
00032 #ifdef HAVE_CONFIG_H
00033 #include "config.h"
00034 #endif
00035 
00036 #ifdef _SOLARIS
00037 #include "solaris_port.h"
00038 #endif
00039 
00040 #include <string.h>
00041 #include <ctype.h>
00042 #include <pthread.h>
00043 #include "log.h"
00044 #include "HashData.h"
00045 #include "HashTable.h"
00046 #include "nfs_core.h"
00047 #include "nlm4.h"
00048 #include "sal_functions.h"
00049 #include "nsm.h"
00050 #include "ganesha_rpc.h"
00051 
00052 //TODO FSF: check if can optimize by using same reference as key and value
00053 
00054 hash_table_t *ht_nsm_client;
00055 hash_table_t *ht_nlm_client;
00056 hash_table_t *ht_nlm_owner;
00057 
00058 int display_nsm_client(state_nsm_client_t *pkey, char *str)
00059 {
00060   char *strtmp = str;
00061 
00062   if(pkey == NULL)
00063     return sprintf(str, "<NULL>");
00064 
00065   strtmp += sprintf(strtmp, "%p: ", pkey);
00066 
00067   if(nfs_param.core_param.nsm_use_caller_name)
00068     strtmp += sprintf(strtmp, "caller_name=");
00069   else
00070     strtmp += sprintf(strtmp, "addr=");
00071 
00072   strncpy(strtmp, pkey->ssc_nlm_caller_name, pkey->ssc_nlm_caller_name_len);
00073   strtmp += pkey->ssc_nlm_caller_name_len;
00074 
00075   strtmp += sprintf(strtmp,
00076                     " monitored=%d refcount=%d",
00077                     pkey->ssc_monitored, pkey->ssc_refcount);
00078 
00079   return strtmp - str;
00080 }
00081 
00082 int display_nsm_client_key(hash_buffer_t * pbuff, char *str)
00083 {
00084   return display_nsm_client((state_nsm_client_t *)pbuff->pdata, str);
00085 }
00086 
00087 int display_nsm_client_val(hash_buffer_t * pbuff, char *str)
00088 {
00089   return display_nsm_client((state_nsm_client_t *)pbuff->pdata, str);
00090 }
00091 
00092 int compare_nsm_client(state_nsm_client_t *pclient1,
00093                        state_nsm_client_t *pclient2)
00094 {
00095   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
00096     {
00097       char str1[HASHTABLE_DISPLAY_STRLEN];
00098       char str2[HASHTABLE_DISPLAY_STRLEN];
00099 
00100       display_nsm_client(pclient1, str1);
00101       display_nsm_client(pclient2, str2);
00102       LogFullDebug(COMPONENT_STATE,
00103                    "{%s} vs {%s}", str1, str2);
00104     }
00105 
00106   if(pclient1 == NULL || pclient2 == NULL)
00107     return 1;
00108 
00109   if(pclient1 == pclient2)
00110     return 0;
00111 
00112   if(!nfs_param.core_param.nsm_use_caller_name)
00113     {
00114       if(cmp_sockaddr(&pclient1->ssc_client_addr, &pclient2->ssc_client_addr, IGNORE_PORT) == 0)
00115         return 1;
00116       return 0;
00117     }
00118 
00119   if(pclient1->ssc_nlm_caller_name_len != pclient2->ssc_nlm_caller_name_len)
00120     return 1;
00121 
00122   return memcmp(pclient1->ssc_nlm_caller_name,
00123                 pclient2->ssc_nlm_caller_name,
00124                 pclient1->ssc_nlm_caller_name_len);
00125 }
00126 
00127 int compare_nsm_client_key(hash_buffer_t * buff1, hash_buffer_t * buff2)
00128 {
00129   return compare_nsm_client((state_nsm_client_t *)buff1->pdata,
00130                             (state_nsm_client_t *)buff2->pdata);
00131 
00132 }                               /* compare_nsm_client */
00133 
00134 uint32_t nsm_client_value_hash_func(hash_parameter_t * p_hparam,
00135                                         hash_buffer_t * buffclef)
00136 {
00137   unsigned long        res;
00138   state_nsm_client_t * pkey = (state_nsm_client_t *)buffclef->pdata;
00139 
00140   if(nfs_param.core_param.nsm_use_caller_name)
00141     {
00142       unsigned int sum = 0;
00143       unsigned int i;
00144 
00145       /* Compute the sum of all the characters */
00146       for(i = 0; i < pkey->ssc_nlm_caller_name_len; i++)
00147         sum +=(unsigned char) pkey->ssc_nlm_caller_name[i];
00148 
00149       res = (unsigned long) sum +
00150             (unsigned long) pkey->ssc_nlm_caller_name_len;
00151     }
00152   else
00153     {
00154       res = hash_sockaddr(&pkey->ssc_client_addr, IGNORE_PORT) % p_hparam->index_size;
00155     }
00156 
00157   if(isDebug(COMPONENT_HASHTABLE))
00158     LogFullDebug(COMPONENT_STATE,
00159                  "value = %lu", res % p_hparam->index_size);
00160 
00161   return (unsigned long)(res % p_hparam->index_size);
00162 }                               /* nsm_client_value_hash_func */
00163 
00164 uint64_t nsm_client_rbt_hash_func(hash_parameter_t * p_hparam,
00165                                       hash_buffer_t * buffclef)
00166 {
00167   unsigned long        res;
00168   state_nsm_client_t * pkey = (state_nsm_client_t *)buffclef->pdata;
00169 
00170   if(nfs_param.core_param.nsm_use_caller_name)
00171     {
00172       unsigned int sum = 0;
00173       unsigned int i;
00174 
00175       /* Compute the sum of all the characters */
00176       for(i = 0; i < pkey->ssc_nlm_caller_name_len; i++)
00177         sum +=(unsigned char) pkey->ssc_nlm_caller_name[i];
00178 
00179       res = (unsigned long) sum +
00180             (unsigned long) pkey->ssc_nlm_caller_name_len;
00181     }
00182   else
00183     {
00184       res = hash_sockaddr(&pkey->ssc_client_addr, IGNORE_PORT);
00185     }
00186 
00187   if(isDebug(COMPONENT_HASHTABLE))
00188     LogFullDebug(COMPONENT_STATE, "rbt = %lu", res);
00189 
00190   return res;
00191 }                               /* nsm_client_rbt_hash_func */
00192 
00193 int display_nlm_client(state_nlm_client_t *pkey, char *str)
00194 {
00195   char *strtmp = str;
00196 
00197   if(pkey == NULL)
00198     return sprintf(str, "<NULL>");
00199 
00200   strtmp += sprintf(strtmp, "%p: NSM Client {", pkey);
00201   strtmp += display_nsm_client(pkey->slc_nsm_client, strtmp);
00202   strtmp += sprintf(strtmp, "} caller_name=");
00203   strncpy(strtmp, pkey->slc_nlm_caller_name, pkey->slc_nlm_caller_name_len);
00204   strtmp += pkey->slc_nlm_caller_name_len;
00205   strtmp += sprintf(strtmp, " type=%s", xprt_type_to_str(pkey->slc_client_type));
00206   strtmp += sprintf(strtmp, " refcount=%d", pkey->slc_refcount);
00207 
00208   return strtmp - str;
00209 }
00210 
00211 int display_nlm_client_key(hash_buffer_t * pbuff, char *str)
00212 {
00213   return display_nlm_client((state_nlm_client_t *)pbuff->pdata, str);
00214 }
00215 
00216 int display_nlm_client_val(hash_buffer_t * pbuff, char *str)
00217 {
00218   return display_nlm_client((state_nlm_client_t *)pbuff->pdata, str);
00219 }
00220 
00221 int compare_nlm_client(state_nlm_client_t *pclient1,
00222                        state_nlm_client_t *pclient2)
00223 {
00224   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
00225     {
00226       char str1[HASHTABLE_DISPLAY_STRLEN];
00227       char str2[HASHTABLE_DISPLAY_STRLEN];
00228 
00229       display_nlm_client(pclient1, str1);
00230       display_nlm_client(pclient2, str2);
00231       LogFullDebug(COMPONENT_STATE,
00232                    "{%s} vs {%s}", str1, str2);
00233     }
00234 
00235   if(pclient1 == NULL || pclient2 == NULL)
00236     return 1;
00237 
00238   if(pclient1 == pclient2)
00239     return 0;
00240 
00241   if(compare_nsm_client(pclient1->slc_nsm_client, pclient2->slc_nsm_client) != 0)
00242     return 1;
00243 
00244   if(pclient1->slc_client_type != pclient2->slc_client_type)
00245     return 1;
00246 
00247   if(pclient1->slc_nlm_caller_name_len != pclient2->slc_nlm_caller_name_len)
00248     return 1;
00249 
00250   return memcmp(pclient1->slc_nlm_caller_name,
00251                 pclient2->slc_nlm_caller_name,
00252                 pclient1->slc_nlm_caller_name_len);
00253 }
00254 
00255 int compare_nlm_client_key(hash_buffer_t * buff1, hash_buffer_t * buff2)
00256 {
00257   return compare_nlm_client((state_nlm_client_t *)buff1->pdata,
00258                             (state_nlm_client_t *)buff2->pdata);
00259 
00260 }                               /* compare_nlm_client */
00261 
00262 uint32_t nlm_client_value_hash_func(hash_parameter_t * p_hparam,
00263                                         hash_buffer_t * buffclef)
00264 {
00265   unsigned int sum = 0;
00266   unsigned int i;
00267   unsigned long res;
00268   state_nlm_client_t *pkey = (state_nlm_client_t *)buffclef->pdata;
00269 
00270   /* Compute the sum of all the characters */
00271   for(i = 0; i < pkey->slc_nlm_caller_name_len; i++)
00272     sum +=(unsigned char) pkey->slc_nlm_caller_name[i];
00273 
00274   res = (unsigned long) sum +
00275         (unsigned long) pkey->slc_nlm_caller_name_len;
00276 
00277   if(isDebug(COMPONENT_HASHTABLE))
00278     LogFullDebug(COMPONENT_STATE,
00279                  "value = %lu", res % p_hparam->index_size);
00280 
00281   return (unsigned long)(res % p_hparam->index_size);
00282 }                               /* nlm_client_value_hash_func */
00283 
00284 uint64_t nlm_client_rbt_hash_func(hash_parameter_t * p_hparam,
00285                                   hash_buffer_t * buffclef)
00286 {
00287   unsigned int sum = 0;
00288   unsigned int i;
00289   unsigned long res;
00290   state_nlm_client_t *pkey = (state_nlm_client_t *)buffclef->pdata;
00291 
00292   /* Compute the sum of all the characters */
00293   for(i = 0; i < pkey->slc_nlm_caller_name_len; i++)
00294     sum +=(unsigned char) pkey->slc_nlm_caller_name[i];
00295 
00296   res = (unsigned long) sum +
00297         (unsigned long) pkey->slc_nlm_caller_name_len;
00298 
00299   if(isDebug(COMPONENT_HASHTABLE))
00300     LogFullDebug(COMPONENT_STATE, "rbt = %lu", res);
00301 
00302   return res;
00303 }                               /* nlm_client_rbt_hash_func */
00304  
00305 int display_nlm_owner(state_owner_t *pkey, char *str)
00306 {
00307   char *strtmp = str;
00308 
00309   if(pkey == NULL)
00310     return sprintf(str, "<NULL>");
00311 
00312   strtmp += sprintf(strtmp, "STATE_LOCK_OWNER_NLM %p: NLM Client {", pkey);
00313 
00314   strtmp += display_nlm_client(pkey->so_owner.so_nlm_owner.so_client, strtmp);
00315 
00316   strtmp += sprintf(strtmp, "} oh=");
00317 
00318   strtmp += DisplayOpaqueValue(pkey->so_owner_val, pkey->so_owner_len, strtmp);
00319 
00320   strtmp += sprintf(strtmp, " svid=%d", pkey->so_owner.so_nlm_owner.so_nlm_svid);
00321   strtmp += sprintf(strtmp, " refcount=%d", pkey->so_refcount);
00322 
00323   return strtmp - str;
00324 }
00325 
00326 int display_nlm_owner_key(hash_buffer_t * pbuff, char *str)
00327 {
00328   return display_nlm_owner((state_owner_t *)pbuff->pdata, str);
00329 }
00330 
00331 int display_nlm_owner_val(hash_buffer_t * pbuff, char *str)
00332 {
00333   return display_nlm_owner((state_owner_t *)pbuff->pdata, str);
00334 }
00335 
00336 int compare_nlm_owner(state_owner_t *powner1,
00337                       state_owner_t *powner2)
00338 {
00339   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
00340     {
00341       char str1[HASHTABLE_DISPLAY_STRLEN];
00342       char str2[HASHTABLE_DISPLAY_STRLEN];
00343 
00344       display_nlm_owner(powner1, str1);
00345       display_nlm_owner(powner2, str2);
00346       LogFullDebug(COMPONENT_STATE,
00347                    "{%s} vs {%s}", str1, str2);
00348     }
00349 
00350   if(powner1 == NULL || powner2 == NULL)
00351     return 1;
00352 
00353   if(powner1 == powner2)
00354     return 0;
00355 
00356   if(compare_nlm_client(powner1->so_owner.so_nlm_owner.so_client,
00357                         powner2->so_owner.so_nlm_owner.so_client) != 0)
00358     return 1;
00359 
00360   if(powner1->so_owner.so_nlm_owner.so_nlm_svid !=
00361      powner2->so_owner.so_nlm_owner.so_nlm_svid)
00362     return 1;
00363 
00364   if(powner1->so_owner_len !=
00365      powner2->so_owner_len)
00366     return 1;
00367 
00368   return memcmp(powner1->so_owner_val,
00369                 powner2->so_owner_val,
00370                 powner1->so_owner_len);
00371 }
00372 
00373 int compare_nlm_owner_key(hash_buffer_t * buff1, hash_buffer_t * buff2)
00374 {
00375   return compare_nlm_owner((state_owner_t *)buff1->pdata,
00376                            (state_owner_t *)buff2->pdata);
00377 
00378 }                               /* compare_nlm_owner */
00379 
00380 uint32_t nlm_owner_value_hash_func(hash_parameter_t * p_hparam,
00381                                    hash_buffer_t * buffclef)
00382 {
00383   unsigned int sum = 0;
00384   unsigned int i;
00385   unsigned long res;
00386   state_owner_t *pkey = (state_owner_t *)buffclef->pdata;
00387 
00388   /* Compute the sum of all the characters */
00389   for(i = 0; i < pkey->so_owner_len; i++)
00390     sum += (unsigned char)pkey->so_owner_val[i];
00391 
00392   res = (unsigned long) (pkey->so_owner.so_nlm_owner.so_nlm_svid) +
00393         (unsigned long) sum +
00394         (unsigned long) pkey->so_owner_len;
00395 
00396   if(isDebug(COMPONENT_HASHTABLE))
00397     LogFullDebug(COMPONENT_STATE,
00398                  "value = %lu", res % p_hparam->index_size);
00399 
00400   return (unsigned long)(res % p_hparam->index_size);
00401 
00402 }                               /* nlm_so_nlm_ohue_hash_func */
00403 
00404 uint64_t nlm_owner_rbt_hash_func(hash_parameter_t * p_hparam,
00405                                  hash_buffer_t * buffclef)
00406 {
00407   unsigned int sum = 0;
00408   unsigned int i;
00409   unsigned long res;
00410   state_owner_t *pkey = (state_owner_t *)buffclef->pdata;
00411 
00412   /* Compute the sum of all the characters */
00413   for(i = 0; i < pkey->so_owner_len; i++)
00414     sum += (unsigned char)pkey->so_owner_val[i];
00415 
00416   res = (unsigned long) (pkey->so_owner.so_nlm_owner.so_nlm_svid) +
00417         (unsigned long) sum +
00418         (unsigned long) pkey->so_owner_len;
00419 
00420   if(isDebug(COMPONENT_HASHTABLE))
00421     LogFullDebug(COMPONENT_STATE, "rbt = %lu", res);
00422 
00423   return res;
00424 }                               /* state_id_rbt_hash_func */
00425 
00437 int Init_nlm_hash(void)
00438 {
00439 
00440   if((ht_nsm_client =
00441       HashTable_Init(&nfs_param.nsm_client_hash_param)) == NULL)
00442     {
00443       LogCrit(COMPONENT_STATE,
00444               "Cannot init NSM Client cache");
00445       return -1;
00446     }
00447 
00448   if((ht_nlm_client
00449       = HashTable_Init(&nfs_param.nlm_client_hash_param)) == NULL)
00450     {
00451       LogCrit(COMPONENT_STATE,
00452               "Cannot init NLM Client cache");
00453       return -1;
00454     }
00455 
00456   if((ht_nlm_owner = HashTable_Init(&nfs_param.nlm_owner_hash_param)) == NULL)
00457     {
00458       LogCrit(COMPONENT_STATE,
00459               "Cannot init NLM Owner cache");
00460       return -1;
00461     }
00462 
00463   return 0;
00464 }                               /* Init_nlm_hash */
00465 
00475 int nsm_client_Set(state_nsm_client_t * pkey,
00476                    state_nsm_client_t * pclient)
00477 {
00478   hash_buffer_t buffkey;
00479   hash_buffer_t buffval;
00480 
00481   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
00482     {
00483       char str[HASHTABLE_DISPLAY_STRLEN];
00484 
00485       buffkey.pdata = (caddr_t) pkey;
00486       buffkey.len = sizeof(*pkey);
00487 
00488       display_nsm_client_key(&buffkey, str);
00489       LogFullDebug(COMPONENT_STATE,
00490                    "KEY {%s}", str);
00491     }
00492 
00493   buffkey.pdata = (caddr_t) pkey;
00494   buffkey.len = sizeof(*pkey);
00495 
00496   buffval.pdata = (caddr_t) pclient;
00497   buffval.len = sizeof(*pclient);
00498 
00499   if(HashTable_Test_And_Set
00500      (ht_nsm_client, &buffkey, &buffval,
00501       HASHTABLE_SET_HOW_SET_NO_OVERWRITE) != HASHTABLE_SUCCESS)
00502     return 0;
00503 
00504   return 1;
00505 }                               /* nsm_client_Set */
00506 
00507 static int Hash_dec_nsm_client_ref(hash_buffer_t *buffval)
00508 {
00509   int rc;
00510   state_nsm_client_t *pclient = (state_nsm_client_t *)(buffval->pdata);
00511 
00512   P(pclient->ssc_mutex);
00513 
00514   pclient->ssc_refcount--;
00515 
00516   if(isFullDebug(COMPONENT_STATE))
00517     {
00518       char str[HASHTABLE_DISPLAY_STRLEN];
00519 
00520       display_nsm_client(pclient, str);
00521       LogFullDebug(COMPONENT_STATE,
00522                    "Decrement refcount NSM Client {%s}",
00523                    str);
00524     }
00525 
00526   rc = pclient->ssc_refcount;
00527 
00528   V(pclient->ssc_mutex);  
00529 
00530   return rc;
00531 }
00532 
00533 static void Hash_inc_nsm_client_ref(hash_buffer_t *buffval)
00534 {
00535   state_nsm_client_t *pclient = (state_nsm_client_t *)(buffval->pdata);
00536 
00537   P(pclient->ssc_mutex);
00538   pclient->ssc_refcount++;
00539 
00540   if(isFullDebug(COMPONENT_STATE))
00541     {
00542       char str[HASHTABLE_DISPLAY_STRLEN];
00543 
00544       display_nsm_client(pclient, str);
00545       LogFullDebug(COMPONENT_STATE,
00546                    "Increment refcount NSM Client {%s}",
00547                    str);
00548     }
00549 
00550   V(pclient->ssc_mutex);  
00551 }
00552 
00553 void inc_nsm_client_ref_locked(state_nsm_client_t *pclient)
00554 {
00555   pclient->ssc_refcount++;
00556 
00557   if(isFullDebug(COMPONENT_STATE))
00558     {
00559       char str[HASHTABLE_DISPLAY_STRLEN];
00560 
00561       display_nsm_client(pclient, str);
00562       LogFullDebug(COMPONENT_STATE,
00563                    "Increment refcount NSM Client {%s}",
00564                    str);
00565     }
00566 
00567   V(pclient->ssc_mutex);
00568 }
00569 
00570 void inc_nsm_client_ref(state_nsm_client_t *pclient)
00571 {
00572   P(pclient->ssc_mutex);
00573 
00574   inc_nsm_client_ref_locked(pclient);
00575 }
00576 
00577 void free_nsm_client(state_nsm_client_t *pclient)
00578 {
00579   if(pclient->ssc_nlm_caller_name != NULL)
00580     gsh_free(pclient->ssc_nlm_caller_name);
00581   if(isFullDebug(COMPONENT_MEMLEAKS))
00582     memset(pclient, 0, sizeof(*pclient));
00583   gsh_free(pclient);
00584 }
00585 
00586 void dec_nsm_client_ref_locked(state_nsm_client_t *pclient)
00587 {
00588   bool_t remove = FALSE;
00589   char   str[HASHTABLE_DISPLAY_STRLEN];
00590 
00591   if(isFullDebug(COMPONENT_STATE))
00592     display_nsm_client(pclient, str);
00593 
00594   if(pclient->ssc_refcount > 1)
00595     {
00596       pclient->ssc_refcount--;
00597 
00598       LogFullDebug(COMPONENT_STATE,
00599                    "Decrement refcount NSM Client {%s}",
00600                    str);
00601     }
00602   else
00603     remove = TRUE;
00604 
00605   V(pclient->ssc_mutex);
00606 
00607   if(remove)
00608     {
00609       hash_buffer_t buffkey, old_key, old_value;
00610 
00611       buffkey.pdata = (caddr_t) pclient;
00612       buffkey.len = sizeof(*pclient);
00613 
00614       switch(HashTable_DelRef(ht_nsm_client, &buffkey, &old_key, &old_value, Hash_dec_nsm_client_ref))
00615         {
00616           case HASHTABLE_SUCCESS:
00617             LogFullDebug(COMPONENT_STATE,
00618                          "Free NSM Client {%s} size %llx",
00619                          str, (unsigned long long) old_value.len);
00620             nsm_unmonitor((state_nsm_client_t *) old_value.pdata);
00621             free_nsm_client((state_nsm_client_t *) old_key.pdata);
00622             free_nsm_client((state_nsm_client_t *) old_value.pdata);
00623             break;
00624 
00625           case HASHTABLE_NOT_DELETED:
00626             /* ref count didn't end up at 0, don't free. */
00627             LogDebug(COMPONENT_STATE,
00628                      "HashTable_DelRef didn't reduce refcount to 0 for NSM Client {%s}",
00629                      str);
00630             break;
00631 
00632           default:
00633             /* some problem occurred */
00634             LogDebug(COMPONENT_STATE,
00635                      "HashTable_DelRef failed for NSM Client {%s}",
00636                      str);
00637             break;
00638         }
00639     }
00640 }
00641 
00642 void dec_nsm_client_ref(state_nsm_client_t *pclient)
00643 {
00644   P(pclient->ssc_mutex);
00645 
00646   dec_nsm_client_ref_locked(pclient);
00647 }
00648 
00661 int nsm_client_Get_Pointer(state_nsm_client_t * pkey,
00662                            state_nsm_client_t * *pclient)
00663 {
00664   hash_buffer_t buffkey;
00665   hash_buffer_t buffval;
00666 
00667   buffkey.pdata = (caddr_t) pkey;
00668   buffkey.len = sizeof(*pkey);
00669 
00670   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
00671     {
00672       char str[HASHTABLE_DISPLAY_STRLEN];
00673 
00674       display_nsm_client_key(&buffkey, str);
00675       LogFullDebug(COMPONENT_STATE,
00676                    "KEY {%s}", str);
00677     }
00678 
00679   if(HashTable_GetRef(ht_nsm_client, &buffkey, &buffval,
00680                       Hash_inc_nsm_client_ref) != HASHTABLE_SUCCESS)
00681     {
00682       LogFullDebug(COMPONENT_STATE,
00683                    "NOTFOUND");
00684       *pclient = NULL;
00685       return 0;
00686     }
00687 
00688   *pclient = (state_nsm_client_t *) buffval.pdata;
00689 
00690   LogFullDebug(COMPONENT_STATE,
00691                "FOUND");
00692 
00693   return 1;
00694 }                               /* nsm_client_Get_Pointer */
00695 
00705 void nsm_client_PrintAll(void)
00706 {
00707   HashTable_Log(COMPONENT_STATE, ht_nsm_client);
00708 }                               /* nsm_client_PrintAll */
00709 
00710 state_nsm_client_t *get_nsm_client(care_t       care,
00711                                    SVCXPRT    * xprt,
00712                                    const char * caller_name)
00713 {
00714   state_nsm_client_t *pkey, *pclient;
00715 
00716   if(caller_name == NULL)
00717     return NULL;
00718 
00719   pkey = gsh_malloc(sizeof(*pkey));
00720   if(pkey == NULL)
00721     return NULL;
00722 
00723   memset(pkey, 0, sizeof(*pkey));
00724   pkey->ssc_refcount            = 1;
00725 
00726   if(nfs_param.core_param.nsm_use_caller_name)
00727     {
00728       pkey->ssc_nlm_caller_name_len = strlen(caller_name);
00729 
00730       if(pkey->ssc_nlm_caller_name_len > LM_MAXSTRLEN)
00731         {
00732           /* Discard the key we created */
00733           free_nsm_client(pkey);
00734           return NULL;
00735         }
00736 
00737       pkey->ssc_nlm_caller_name
00738            = gsh_malloc(pkey->ssc_nlm_caller_name_len + 1);
00739       if(pkey->ssc_nlm_caller_name == NULL)
00740         {
00741           /* Discard the key we created */
00742           free_nsm_client(pkey);
00743           return NULL;
00744         }
00745 
00746       memcpy(pkey->ssc_nlm_caller_name,
00747              caller_name,
00748              pkey->ssc_nlm_caller_name_len);
00749       pkey->ssc_nlm_caller_name[pkey->ssc_nlm_caller_name_len] = '\0';
00750     }
00751   else if(xprt == NULL)
00752     {
00753       int rc = ipstring_to_sockaddr(caller_name, &pkey->ssc_client_addr);
00754       if(rc != 0)
00755         {
00756           LogEvent(COMPONENT_STATE,
00757                   "Error converting caller_name %s to an ipaddress %s",
00758                   caller_name, gai_strerror(rc));
00759 
00760           /* Discard the key we created */
00761           free_nsm_client(pkey);
00762 
00763           return NULL;
00764         }
00765 
00766       pkey->ssc_nlm_caller_name_len = strlen(caller_name);
00767 
00768       if(pkey->ssc_nlm_caller_name_len > LM_MAXSTRLEN)
00769         {
00770           /* Discard the key we created */
00771           free_nsm_client(pkey);
00772           return NULL;
00773         }
00774 
00775       pkey->ssc_nlm_caller_name
00776            = gsh_malloc(pkey->ssc_nlm_caller_name_len + 1);
00777       if(pkey->ssc_nlm_caller_name == NULL)
00778         {
00779           /* Discard the key we created */
00780           free_nsm_client(pkey);
00781           return NULL;
00782         }
00783 
00784       memcpy(pkey->ssc_nlm_caller_name,
00785              caller_name,
00786              pkey->ssc_nlm_caller_name_len);
00787       pkey->ssc_nlm_caller_name[pkey->ssc_nlm_caller_name_len] = '\0';
00788     }
00789   else
00790     {
00791       pkey->ssc_nlm_caller_name_len = SOCK_NAME_MAX;
00792       pkey->ssc_nlm_caller_name
00793            = gsh_malloc(SOCK_NAME_MAX);
00794       if(pkey->ssc_nlm_caller_name == NULL)
00795         {
00796           /* Discard the key we created */
00797           free_nsm_client(pkey);
00798           return NULL;
00799         }
00800 
00801       if(copy_xprt_addr(&pkey->ssc_client_addr, xprt) == 0)
00802         {
00803           /* Discard the key we created */
00804           free_nsm_client(pkey);
00805           return NULL;
00806         }
00807 
00808       if(sprint_sockip(&pkey->ssc_client_addr, pkey->ssc_nlm_caller_name, SOCK_NAME_MAX) == 0)
00809         {
00810           /* Discard the key we created */
00811           free_nsm_client(pkey);
00812           return NULL;
00813         }
00814       pkey->ssc_nlm_caller_name_len = strlen(pkey->ssc_nlm_caller_name);
00815     }
00816 
00817   
00818   if(isFullDebug(COMPONENT_STATE))
00819     {
00820       char str[HASHTABLE_DISPLAY_STRLEN];
00821 
00822       display_nsm_client(pkey, str);
00823       LogFullDebug(COMPONENT_STATE,
00824                    "Find NSM Client pkey {%s}", str);
00825     }
00826 
00827   /* If we found it, return it, if we don't care, return NULL */
00828   if(nsm_client_Get_Pointer(pkey, &pclient) == 1 || care == CARE_NOT)
00829     {
00830       /* Discard the key we created and return the found NSM Client */
00831       free_nsm_client(pkey);
00832 
00833       if(isFullDebug(COMPONENT_STATE))
00834         {
00835           char str[HASHTABLE_DISPLAY_STRLEN];
00836 
00837           display_nsm_client(pclient, str);
00838           LogFullDebug(COMPONENT_STATE,
00839                        "Found NSM Client {%s}",
00840                        str);
00841         }
00842 
00843       if(care == CARE_MONITOR)
00844         if(!nsm_monitor(pclient))
00845           {
00846             dec_nsm_client_ref(pclient);
00847             return NULL;
00848           }
00849 
00850       return pclient;
00851     }
00852 
00853   pclient = gsh_malloc(sizeof(*pkey));
00854   if(pclient == NULL)
00855     {
00856       free_nsm_client(pkey);
00857       return NULL;
00858     }
00859 
00860   /* Copy everything over */
00861   *pclient = *pkey;
00862 
00863   pclient->ssc_nlm_caller_name = gsh_malloc(pkey->ssc_nlm_caller_name_len + 1);
00864   if(pclient->ssc_nlm_caller_name == NULL)
00865     {
00866       /* Discard the key and created client */
00867       free_nsm_client(pkey);
00868       free_nsm_client(pclient);
00869       return NULL;
00870     }
00871 
00872   memcpy(pclient->ssc_nlm_caller_name,
00873          pkey->ssc_nlm_caller_name,
00874          pclient->ssc_nlm_caller_name_len);
00875   pclient->ssc_nlm_caller_name[pclient->ssc_nlm_caller_name_len] = '\0';
00876 
00877   init_glist(&pclient->ssc_lock_list);
00878   init_glist(&pclient->ssc_share_list);
00879 
00880   if(isFullDebug(COMPONENT_STATE))
00881     {
00882       char str[HASHTABLE_DISPLAY_STRLEN];
00883 
00884       display_nsm_client(pclient, str);
00885       LogFullDebug(COMPONENT_STATE,
00886                    "New NSM Client {%s}", str);
00887     }
00888 
00889   if(pthread_mutex_init(&pclient->ssc_mutex, NULL) == -1)
00890     {
00891       /* Mutex initialization failed, free the key and created client */
00892       free_nsm_client(pkey);
00893       free_nsm_client(pclient);
00894       return NULL;
00895     }
00896 
00897   if(nsm_client_Set(pkey, pclient) == 1)
00898     {
00899       if(isFullDebug(COMPONENT_STATE))
00900         {
00901           char str[HASHTABLE_DISPLAY_STRLEN];
00902 
00903           display_nsm_client(pclient, str);
00904           LogFullDebug(COMPONENT_STATE,
00905                        "Set NSM Client {%s}",
00906                        str);
00907         }
00908 
00909       if(care != CARE_MONITOR || nsm_monitor(pclient))
00910         return pclient;
00911 
00912       dec_nsm_client_ref(pclient);
00913       return NULL;
00914     }
00915 
00916   free_nsm_client(pkey);
00917   free_nsm_client(pclient);
00918   return NULL;
00919 }
00920 
00930 int nlm_client_Set(state_nlm_client_t * pkey,
00931                    state_nlm_client_t * pclient)
00932 {
00933   hash_buffer_t buffkey;
00934   hash_buffer_t buffval;
00935 
00936   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
00937     {
00938       char str[HASHTABLE_DISPLAY_STRLEN];
00939 
00940       buffkey.pdata = (caddr_t) pkey;
00941       buffkey.len = sizeof(*pkey);
00942 
00943       display_nlm_client_key(&buffkey, str);
00944       LogFullDebug(COMPONENT_STATE,
00945                    "KEY {%s}", str);
00946     }
00947 
00948   buffkey.pdata = (caddr_t) pkey;
00949   buffkey.len = sizeof(*pkey);
00950 
00951   buffval.pdata = (caddr_t) pclient;
00952   buffval.len = sizeof(*pclient);
00953 
00954   if(HashTable_Test_And_Set
00955      (ht_nlm_client, &buffkey, &buffval,
00956       HASHTABLE_SET_HOW_SET_NO_OVERWRITE) != HASHTABLE_SUCCESS)
00957     return 0;
00958 
00959   return 1;
00960 }                               /* nlm_client_Set */
00961 
00962 static int Hash_dec_nlm_client_ref(hash_buffer_t *buffval)
00963 {
00964   int rc;
00965   state_nlm_client_t *pclient = (state_nlm_client_t *)(buffval->pdata);
00966 
00967   P(pclient->slc_mutex);
00968 
00969   pclient->slc_refcount--;
00970 
00971   if(isFullDebug(COMPONENT_STATE))
00972     {
00973       char str[HASHTABLE_DISPLAY_STRLEN];
00974 
00975       display_nlm_client(pclient, str);
00976       LogFullDebug(COMPONENT_STATE,
00977                    "Decrement refcount NLM Client {%s}",
00978                    str);
00979     }
00980 
00981   rc = pclient->slc_refcount;
00982 
00983   V(pclient->slc_mutex);  
00984 
00985   return rc;
00986 }
00987 
00988 static void Hash_inc_nlm_client_ref(hash_buffer_t *buffval)
00989 {
00990   state_nlm_client_t *pclient = (state_nlm_client_t *)(buffval->pdata);
00991 
00992   P(pclient->slc_mutex);
00993   pclient->slc_refcount++;
00994 
00995   if(isFullDebug(COMPONENT_STATE))
00996     {
00997       char str[HASHTABLE_DISPLAY_STRLEN];
00998 
00999       display_nlm_client(pclient, str);
01000       LogFullDebug(COMPONENT_STATE,
01001                    "Increment refcount NLM Client {%s}",
01002                    str);
01003     }
01004 
01005   V(pclient->slc_mutex);  
01006 }
01007 
01008 void inc_nlm_client_ref_locked(state_nlm_client_t *pclient)
01009 {
01010   pclient->slc_refcount++;
01011 
01012   if(isFullDebug(COMPONENT_STATE))
01013     {
01014       char str[HASHTABLE_DISPLAY_STRLEN];
01015 
01016       display_nlm_client(pclient, str);
01017       LogFullDebug(COMPONENT_STATE,
01018                    "Increment refcount NLM Client {%s}",
01019                    str);
01020     }
01021 
01022   V(pclient->slc_mutex);
01023 }
01024 
01025 void inc_nlm_client_ref(state_nlm_client_t *pclient)
01026 {
01027   P(pclient->slc_mutex);
01028 
01029   inc_nlm_client_ref_locked(pclient);
01030 }
01031 
01032 void dec_nlm_client_ref_locked(state_nlm_client_t *pclient)
01033 {
01034   bool_t remove = FALSE;
01035   char   str[HASHTABLE_DISPLAY_STRLEN];
01036 
01037   if(isFullDebug(COMPONENT_STATE))
01038     display_nlm_client(pclient, str);
01039 
01040   if(pclient->slc_refcount > 1)
01041     {
01042       pclient->slc_refcount--;
01043 
01044       LogFullDebug(COMPONENT_STATE,
01045                    "Decrement refcount NLM Client {%s}",
01046                    str);
01047     }
01048   else
01049     remove = TRUE;
01050 
01051   V(pclient->slc_mutex);
01052 
01053   if(remove)
01054     {
01055       hash_buffer_t buffkey, old_key, old_value;
01056 
01057       buffkey.pdata = (caddr_t) pclient;
01058       buffkey.len = sizeof(*pclient);
01059 
01060       switch(HashTable_DelRef(ht_nlm_client, &buffkey, &old_key, &old_value, Hash_dec_nlm_client_ref))
01061         {
01062           case HASHTABLE_SUCCESS:
01063             LogFullDebug(COMPONENT_STATE,
01064                          "Free NLM Client {%s} size %llx",
01065                          str, (unsigned long long) old_value.len);
01066             if(pclient->slc_callback_clnt != NULL)
01067               Clnt_destroy(pclient->slc_callback_clnt);
01068             dec_nsm_client_ref(pclient->slc_nsm_client);
01069             if(isFullDebug(COMPONENT_MEMLEAKS))
01070               {
01071                 memset(old_key.pdata, 0, old_key.len);
01072                 memset(old_value.pdata, 0, old_value.len);
01073               }
01074             gsh_free(old_key.pdata);
01075             gsh_free(old_value.pdata);
01076             break;
01077 
01078           case HASHTABLE_NOT_DELETED:
01079             /* ref count didn't end up at 0, don't free. */
01080             LogDebug(COMPONENT_STATE,
01081                      "HashTable_DelRef didn't reduce refcount to 0 for NLM Client {%s}",
01082                      str);
01083             break;
01084 
01085           default:
01086             /* some problem occurred */
01087             LogDebug(COMPONENT_STATE,
01088                      "HashTable_DelRef failed for NLM Client {%s}",
01089                      str);
01090             break;
01091         }
01092     }
01093 }
01094 
01095 void dec_nlm_client_ref(state_nlm_client_t *pclient)
01096 {
01097   P(pclient->slc_mutex);
01098 
01099   dec_nlm_client_ref_locked(pclient);
01100 }
01101 
01114 int nlm_client_Get_Pointer(state_nlm_client_t * pkey,
01115                            state_nlm_client_t * *pclient)
01116 {
01117   hash_buffer_t buffkey;
01118   hash_buffer_t buffval;
01119 
01120   buffkey.pdata = (caddr_t) pkey;
01121   buffkey.len = sizeof(*pkey);
01122 
01123   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
01124     {
01125       char str[HASHTABLE_DISPLAY_STRLEN];
01126 
01127       display_nlm_client_key(&buffkey, str);
01128       LogFullDebug(COMPONENT_STATE,
01129                    "KEY {%s}", str);
01130     }
01131 
01132   if(HashTable_GetRef(ht_nlm_client, &buffkey, &buffval,
01133                       Hash_inc_nlm_client_ref) != HASHTABLE_SUCCESS)
01134     {
01135       LogFullDebug(COMPONENT_STATE,
01136                    "NOTFOUND");
01137       *pclient = NULL;
01138       return 0;
01139     }
01140 
01141   *pclient = (state_nlm_client_t *) buffval.pdata;
01142 
01143   LogFullDebug(COMPONENT_STATE,
01144                "FOUND");
01145 
01146   return 1;
01147 }                               /* nlm_client_Get_Pointer */
01148 
01158 void nlm_client_PrintAll(void)
01159 {
01160   HashTable_Log(COMPONENT_STATE, ht_nlm_client);
01161 }                               /* nlm_client_PrintAll */
01162 
01163 
01164 state_nlm_client_t *get_nlm_client(care_t               care,
01165                                    SVCXPRT            * xprt,
01166                                    state_nsm_client_t * pnsm_client,
01167                                    const char         * caller_name)
01168 {
01169   state_nlm_client_t *pkey, *pclient;
01170 
01171   if(caller_name == NULL)
01172     return NULL;
01173 
01174   pkey = gsh_malloc(sizeof(*pkey));
01175   if(pkey == NULL)
01176     return NULL;
01177 
01178   memset(pkey, 0, sizeof(*pkey));
01179   pkey->slc_refcount            = 1;
01180   pkey->slc_nsm_client          = pnsm_client;
01181   pkey->slc_nlm_caller_name_len = strlen(caller_name);
01182   pkey->slc_client_type         = svc_get_xprt_type(xprt);
01183 
01184   if(pkey->slc_nlm_caller_name_len > LM_MAXSTRLEN)
01185     {
01186       /* Discard the key we created */
01187       gsh_free(pkey);
01188       return NULL;
01189     }
01190 
01191   memcpy(pkey->slc_nlm_caller_name,
01192          caller_name,
01193          pkey->slc_nlm_caller_name_len);
01194   pkey->slc_nlm_caller_name[pkey->slc_nlm_caller_name_len] = '\0';
01195   
01196   if(isFullDebug(COMPONENT_STATE))
01197     {
01198       char str[HASHTABLE_DISPLAY_STRLEN];
01199 
01200       display_nlm_client(pkey, str);
01201       LogFullDebug(COMPONENT_STATE,
01202                    "Find NLM Client pkey {%s}", str);
01203     }
01204 
01205   /* If we found it, return it, if we don't care, return NULL */
01206   if(nlm_client_Get_Pointer(pkey, &pclient) == 1 || care == CARE_NOT)
01207     {
01208       /* Discard the key we created and return the found NLM Client */
01209       gsh_free(pkey);
01210 
01211       if(isFullDebug(COMPONENT_STATE))
01212         {
01213           char str[HASHTABLE_DISPLAY_STRLEN];
01214 
01215           display_nlm_client(pclient, str);
01216           LogFullDebug(COMPONENT_STATE,
01217                        "Found NLM Client {%s}",
01218                        str);
01219         }
01220 
01221       if(care == CARE_MONITOR)
01222         if(!nsm_monitor(pnsm_client))
01223           {
01224             dec_nlm_client_ref(pclient);
01225             return NULL;
01226           }
01227 
01228       return pclient;
01229     }
01230 
01231   pclient = gsh_malloc(sizeof(*pkey));
01232   if(pclient == NULL)
01233     {
01234       gsh_free(pkey);
01235       return NULL;
01236     }
01237 
01238   /* Copy everything over */
01239   *pclient = *pkey;
01240 
01241   if(isFullDebug(COMPONENT_STATE))
01242     {
01243       char str[HASHTABLE_DISPLAY_STRLEN];
01244 
01245       display_nlm_client(pclient, str);
01246       LogFullDebug(COMPONENT_STATE,
01247                    "New NLM Client {%s}", str);
01248     }
01249 
01250   if(pthread_mutex_init(&pclient->slc_mutex, NULL) == -1)
01251     {
01252       /* Mutex initialization failed, free the key and created owner */
01253       gsh_free(pkey);
01254       gsh_free(pclient);
01255       return NULL;
01256     }
01257 
01258   /* Ref count the NSM Client as being used by this NLM Client */
01259   inc_nsm_client_ref(pnsm_client);
01260 
01261   if(nlm_client_Set(pkey, pclient) == 1)
01262     {
01263       if(isFullDebug(COMPONENT_STATE))
01264         {
01265           char str[HASHTABLE_DISPLAY_STRLEN];
01266 
01267           display_nlm_client(pclient, str);
01268           LogFullDebug(COMPONENT_STATE,
01269                        "Set NLM Client {%s}",
01270                        str);
01271         }
01272 
01273       if(care != CARE_MONITOR || nsm_monitor(pnsm_client))
01274         return pclient;
01275 
01276       dec_nlm_client_ref(pclient);
01277       return NULL;
01278     }
01279 
01280   dec_nsm_client_ref(pnsm_client);
01281   gsh_free(pkey);
01282   gsh_free(pclient);
01283   return NULL;
01284 }
01285 
01295 int nlm_owner_Set(state_owner_t * pkey,
01296                   state_owner_t * powner)
01297 {
01298   hash_buffer_t buffkey;
01299   hash_buffer_t buffval;
01300 
01301   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
01302     {
01303       char str[HASHTABLE_DISPLAY_STRLEN];
01304 
01305       buffkey.pdata = (caddr_t) pkey;
01306       buffkey.len = sizeof(*pkey);
01307 
01308       display_nlm_owner_key(&buffkey, str);
01309       LogFullDebug(COMPONENT_STATE,
01310                    "KEY {%s}", str);
01311     }
01312 
01313   buffkey.pdata = (caddr_t) pkey;
01314   buffkey.len = sizeof(*pkey);
01315 
01316   buffval.pdata = (caddr_t) powner;
01317   buffval.len = sizeof(*powner);
01318 
01319   if(HashTable_Test_And_Set
01320      (ht_nlm_owner, &buffkey, &buffval,
01321       HASHTABLE_SET_HOW_SET_NO_OVERWRITE) != HASHTABLE_SUCCESS)
01322     return 0;
01323 
01324   return 1;
01325 }                               /* nlm_owner_Set */
01326 
01327 void remove_nlm_owner(state_owner_t        * powner,
01328                       const char           * str)
01329 {
01330   hash_buffer_t buffkey, old_key, old_value;
01331 
01332   buffkey.pdata = (caddr_t) powner;
01333   buffkey.len = sizeof(*powner);
01334 
01335   switch(HashTable_DelRef(ht_nlm_owner, &buffkey, &old_key, &old_value, Hash_dec_state_owner_ref))
01336     {
01337       case HASHTABLE_SUCCESS:
01338         LogFullDebug(COMPONENT_STATE,
01339                      "Free %s size %llx",
01340                      str, (unsigned long long) old_value.len);
01341         dec_nlm_client_ref(powner->so_owner.so_nlm_owner.so_client);
01342         if(isFullDebug(COMPONENT_MEMLEAKS))
01343           {
01344             memset(old_key.pdata, 0, old_key.len);
01345             memset(old_value.pdata, 0, old_value.len);
01346           }
01347         gsh_free(old_key.pdata);
01348         gsh_free(old_value.pdata);
01349         break;
01350 
01351       case HASHTABLE_NOT_DELETED:
01352         /* ref count didn't end up at 0, don't free. */
01353         LogDebug(COMPONENT_STATE,
01354                  "HashTable_DelRef didn't reduce refcount to 0 for %s",
01355                   str);
01356         break;
01357 
01358       default:
01359         /* some problem occurred */
01360         LogDebug(COMPONENT_STATE,
01361                  "HashTable_DelRef failed for %s",
01362                   str);
01363         break;
01364     }
01365 }
01366 
01379 static int nlm_owner_Get_Pointer(state_owner_t  * pkey,
01380                           state_owner_t ** powner)
01381 {
01382   hash_buffer_t buffkey;
01383   hash_buffer_t buffval;
01384 
01385   *powner = NULL; // in case we dont find it, return NULL
01386   buffkey.pdata = (caddr_t) pkey;
01387   buffkey.len = sizeof(*pkey);
01388 
01389   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
01390     {
01391       char str[HASHTABLE_DISPLAY_STRLEN];
01392 
01393       display_nlm_owner_key(&buffkey, str);
01394       LogFullDebug(COMPONENT_STATE,
01395                    "KEY {%s}", str);
01396     }
01397 
01398   if(HashTable_GetRef(ht_nlm_owner,
01399                       &buffkey,
01400                       &buffval,
01401                       Hash_inc_state_owner_ref) != HASHTABLE_SUCCESS)
01402     {
01403       LogFullDebug(COMPONENT_STATE,
01404                    "NOTFOUND");
01405       return 0;
01406     }
01407 
01408   *powner = (state_owner_t *) buffval.pdata;
01409 
01410   LogFullDebug(COMPONENT_STATE,
01411                "FOUND");
01412 
01413   return 1;
01414 }                               /* nlm_owner_Get_Pointer */
01415 
01425 void nlm_owner_PrintAll(void)
01426 {
01427   HashTable_Log(COMPONENT_STATE, ht_nlm_owner);
01428 }                               /* nlm_owner_PrintAll */
01429 
01430 state_owner_t *get_nlm_owner(care_t               care,
01431                              state_nlm_client_t * pclient, 
01432                              netobj             * oh,
01433                              uint32_t             svid)
01434 {
01435   state_owner_t * pkey, *powner;
01436 
01437   if(pclient == NULL || oh == NULL || oh->n_len > MAX_NETOBJ_SZ)
01438     return NULL;
01439 
01440   pkey = gsh_malloc(sizeof(*pkey));
01441   if(pkey == NULL)
01442     return NULL;
01443 
01444   memset(pkey, 0, sizeof(*pkey));
01445   pkey->so_type                             = STATE_LOCK_OWNER_NLM;
01446   pkey->so_refcount                         = 1;
01447   pkey->so_owner.so_nlm_owner.so_client     = pclient;
01448   pkey->so_owner.so_nlm_owner.so_nlm_svid   = svid;
01449   pkey->so_owner_len                        = oh->n_len;
01450   memcpy(pkey->so_owner_val, oh->n_bytes, oh->n_len);
01451 
01452   if(isFullDebug(COMPONENT_STATE))
01453     {
01454       char str[HASHTABLE_DISPLAY_STRLEN];
01455 
01456       display_nlm_owner(pkey, str);
01457 
01458       LogFullDebug(COMPONENT_STATE,
01459                    "Find NLM Owner KEY {%s}", str);
01460     }
01461 
01462   /* If we found it, return it, if we don't care, return NULL */
01463   if(nlm_owner_Get_Pointer(pkey, &powner) == 1 || care == CARE_NOT)
01464     {
01465       /* Discard the key we created and return the found NLM Owner */
01466       gsh_free(pkey);
01467 
01468       if(isFullDebug(COMPONENT_STATE))
01469         {
01470           char str[HASHTABLE_DISPLAY_STRLEN];
01471 
01472           display_nlm_owner(powner, str);
01473           LogFullDebug(COMPONENT_STATE,
01474                        "Found {%s}",
01475                        str);
01476         }
01477 
01478       return powner;
01479     }
01480 
01481   powner = gsh_malloc(sizeof(*pkey));
01482   if(powner == NULL)
01483     {
01484       gsh_free(pkey);
01485       return NULL;
01486     }
01487 
01488   /* Copy everything over */
01489   *powner = *pkey;
01490   init_glist(&powner->so_lock_list);
01491   init_glist(&powner->so_owner.so_nlm_owner.so_nlm_shares);
01492 
01493   if(pthread_mutex_init(&powner->so_mutex, NULL) == -1)
01494     {
01495       /* Mutex initialization failed, free the key and created owner */
01496       gsh_free(pkey);
01497       gsh_free(powner);
01498       return NULL;
01499     }
01500 
01501   if(isFullDebug(COMPONENT_STATE))
01502     {
01503       char str[HASHTABLE_DISPLAY_STRLEN];
01504 
01505       display_nlm_owner(powner, str);
01506       LogFullDebug(COMPONENT_STATE,
01507                    "New {%s}", str);
01508     }
01509 
01510   /* Ref count the client as being used by this owner */
01511   inc_nlm_client_ref(pclient);
01512   if(nlm_owner_Set(pkey, powner) == 1)
01513     {
01514       if(isFullDebug(COMPONENT_STATE))
01515         {
01516           char str[HASHTABLE_DISPLAY_STRLEN];
01517 
01518           display_nlm_owner(powner, str);
01519           LogFullDebug(COMPONENT_STATE,
01520                        "Set NLM Owner {%s}",
01521                        str);
01522         }
01523 
01524       return powner;
01525     }
01526 
01527   dec_nlm_client_ref(pclient);
01528   gsh_free(pkey);
01529   gsh_free(powner);
01530   return NULL;
01531 }