nfs-ganesha 1.4

9p_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 "sal_functions.h"
00048 
00049 //TODO FSF: check if can optimize by using same reference as key and value
00050 
00051 hash_table_t *ht_9p_owner;
00052 
00053 int display_9p_owner(state_owner_t *pkey, char *str)
00054 {
00055   char *strtmp = str;
00056 
00057   if(pkey == NULL)
00058     return sprintf(str, "<NULL>");
00059 
00060   strtmp += sprintf(strtmp, "STATE_LOCK_OWNER_9P %p", pkey);
00061   strtmp += sprint_sockaddr( (sockaddr_t *)&(pkey->so_owner.so_9p_owner.client_addr),
00062                              strtmp, 
00063                              sizeof( pkey->so_owner.so_9p_owner.client_addr ) ) ;
00064 
00065   strtmp += sprintf(strtmp, " proc_id=%u", pkey->so_owner.so_9p_owner.proc_id);
00066  
00067   strtmp += sprintf(strtmp, " refcount=%d", pkey->so_refcount);
00068 
00069   return strtmp - str;
00070 }
00071 
00072 int display_9p_owner_key(hash_buffer_t * pbuff, char *str)
00073 {
00074   return display_9p_owner((state_owner_t *)pbuff->pdata, str);
00075 }
00076 
00077 int display_9p_owner_val(hash_buffer_t * pbuff, char *str)
00078 {
00079   return display_9p_owner((state_owner_t *)pbuff->pdata, str);
00080 }
00081 
00082 int compare_9p_owner(state_owner_t *powner1,
00083                      state_owner_t *powner2)
00084 {
00085   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
00086     {
00087       char str1[HASHTABLE_DISPLAY_STRLEN];
00088       char str2[HASHTABLE_DISPLAY_STRLEN];
00089 
00090       display_9p_owner(powner1, str1);
00091       display_9p_owner(powner2, str2);
00092       LogFullDebug(COMPONENT_STATE,
00093                    "{%s} vs {%s}", str1, str2);
00094     }
00095 
00096   if(powner1 == NULL || powner2 == NULL)
00097     return 1;
00098 
00099   if(powner1 == powner2)
00100     return 0;
00101 
00102   if(powner1->so_owner.so_9p_owner.proc_id !=
00103      powner2->so_owner.so_9p_owner.proc_id)
00104     return 1;
00105 #if 0
00106   if( memcmp( (char *)&powner1->so_owner.so_9p_owner.client_addr, 
00107               (char *)&powner2->so_owner.so_9p_owner.client_addr,
00108               sizeof( struct sockaddr_storage ) ) )
00109     return 1;
00110 #endif 
00111 
00112   if(powner1->so_owner_len !=
00113      powner2->so_owner_len)
00114     return 1;
00115 
00116   return memcmp(powner1->so_owner_val,
00117                 powner2->so_owner_val,
00118                 powner1->so_owner_len);
00119 }
00120 
00121 int compare_9p_owner_key(hash_buffer_t * buff1, hash_buffer_t * buff2)
00122 {
00123   return compare_9p_owner((state_owner_t *)buff1->pdata,
00124                           (state_owner_t *)buff2->pdata);
00125 
00126 }                               /* compare_9p_owner */
00127 
00128 uint32_t _9p_owner_value_hash_func(hash_parameter_t * p_hparam,
00129                                    hash_buffer_t * buffclef)
00130 {
00131   unsigned int sum = 0;
00132   unsigned int i;
00133   unsigned long res;
00134   state_owner_t *pkey = (state_owner_t *)buffclef->pdata;
00135 
00136   struct sockaddr_in * paddr = (struct sockaddr_in *)&pkey->so_owner.so_9p_owner.client_addr ;
00137 
00138   /* Compute the sum of all the characters */
00139   for(i = 0; i < pkey->so_owner_len; i++)
00140     sum += (unsigned char)pkey->so_owner_val[i];
00141 
00142   res = (unsigned long) (pkey->so_owner.so_9p_owner.proc_id)  +
00143         (unsigned long) paddr->sin_addr.s_addr +
00144         (unsigned long) sum +
00145         (unsigned long) pkey->so_owner_len;
00146 
00147   if(isDebug(COMPONENT_HASHTABLE))
00148     LogFullDebug(COMPONENT_STATE,
00149                  "value = %lu", res % p_hparam->index_size);
00150 
00151   return (unsigned long)(res % p_hparam->index_size);
00152 
00153 }                               
00154 
00155 uint64_t _9p_owner_rbt_hash_func(hash_parameter_t * p_hparam,
00156                                  hash_buffer_t * buffclef)
00157 {
00158   unsigned int sum = 0;
00159   unsigned int i;
00160   unsigned long res;
00161   state_owner_t *pkey = (state_owner_t *)buffclef->pdata;
00162 
00163   struct sockaddr_in * paddr = (struct sockaddr_in *)&pkey->so_owner.so_9p_owner.client_addr ;
00164 
00165   /* Compute the sum of all the characters */
00166   for(i = 0; i < pkey->so_owner_len; i++)
00167     sum += (unsigned char)pkey->so_owner_val[i];
00168 
00169   res = (unsigned long) (pkey->so_owner.so_9p_owner.proc_id)  +
00170         (unsigned long) paddr->sin_addr.s_addr +
00171         (unsigned long) sum +
00172         (unsigned long) pkey->so_owner_len;
00173 
00174   if(isDebug(COMPONENT_HASHTABLE))
00175     LogFullDebug(COMPONENT_STATE, "rbt = %lu", res);
00176 
00177   return res;
00178 }                               /* state_id_rbt_hash_func */
00179 
00191 int Init_9p_hash(void)
00192 {
00193   if((ht_9p_owner = HashTable_Init(&nfs_param._9p_owner_hash_param)) == NULL)
00194     {
00195       LogCrit(COMPONENT_STATE,
00196               "Cannot init 9P Owner cache");
00197       return -1;
00198     }
00199 
00200   return 0;
00201 }                               /* Init_9p_hash */
00202 
00212 int _9p_owner_Set(state_owner_t * pkey,
00213                   state_owner_t * powner)
00214 {
00215   hash_buffer_t buffkey;
00216   hash_buffer_t buffval;
00217 
00218   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
00219     {
00220       char str[HASHTABLE_DISPLAY_STRLEN];
00221 
00222       buffkey.pdata = (caddr_t) pkey;
00223       buffkey.len = sizeof(*pkey);
00224 
00225       display_9p_owner_key(&buffkey, str);
00226       LogFullDebug(COMPONENT_STATE,
00227                    "KEY {%s}", str);
00228     }
00229 
00230   buffkey.pdata = (caddr_t) pkey;
00231   buffkey.len = sizeof(*pkey);
00232 
00233   buffval.pdata = (caddr_t) powner;
00234   buffval.len = sizeof(*powner);
00235 
00236   if(HashTable_Test_And_Set
00237      (ht_9p_owner, &buffkey, &buffval,
00238       HASHTABLE_SET_HOW_SET_NO_OVERWRITE) != HASHTABLE_SUCCESS)
00239     return 0;
00240 
00241   return 1;
00242 }                               /* _9p_owner_Set */
00243 
00244 void remove_9p_owner( state_owner_t        * powner,
00245                       const char           * str)
00246 {
00247   hash_buffer_t buffkey, old_key, old_value;
00248 
00249   buffkey.pdata = (caddr_t) powner;
00250   buffkey.len = sizeof(*powner);
00251 
00252   switch(HashTable_DelRef(ht_9p_owner, &buffkey, &old_key, &old_value, Hash_dec_state_owner_ref))
00253     {
00254       case HASHTABLE_SUCCESS:
00255         LogFullDebug(COMPONENT_STATE,
00256                      "Free %s size %llx",
00257                      str, (unsigned long long) old_value.len);
00258         if(isFullDebug(COMPONENT_MEMLEAKS))
00259           {
00260             memset(old_key.pdata, 0, old_key.len);
00261             memset(old_value.pdata, 0, old_value.len);
00262           }
00263         gsh_free(old_key.pdata);
00264         gsh_free(old_value.pdata);
00265         break;
00266 
00267       case HASHTABLE_NOT_DELETED:
00268         /* ref count didn't end up at 0, don't free. */
00269         LogDebug(COMPONENT_STATE,
00270                  "HashTable_DelRef didn't reduce refcount to 0 for %s",
00271                   str);
00272         break;
00273 
00274       default:
00275         /* some problem occurred */
00276         LogDebug(COMPONENT_STATE,
00277                  "HashTable_DelRef failed for %s",
00278                   str);
00279         break;
00280     }
00281 }
00282 
00295 static int _9p_owner_Get_Pointer(state_owner_t  * pkey,
00296                                  state_owner_t ** powner)
00297 {
00298   hash_buffer_t buffkey;
00299   hash_buffer_t buffval;
00300 
00301   *powner = NULL; // in case we dont find it, return NULL
00302   buffkey.pdata = (caddr_t) pkey;
00303   buffkey.len = sizeof(*pkey);
00304 
00305   if(isFullDebug(COMPONENT_STATE) && isDebug(COMPONENT_HASHTABLE))
00306     {
00307       char str[HASHTABLE_DISPLAY_STRLEN];
00308 
00309       display_9p_owner_key(&buffkey, str);
00310       LogFullDebug(COMPONENT_STATE,
00311                    "KEY {%s}", str);
00312     }
00313 
00314   if(HashTable_GetRef(ht_9p_owner,
00315                       &buffkey,
00316                       &buffval,
00317                       Hash_inc_state_owner_ref) != HASHTABLE_SUCCESS)
00318     {
00319       LogFullDebug(COMPONENT_STATE,
00320                    "NOTFOUND");
00321       return 0;
00322     }
00323 
00324   *powner = (state_owner_t *) buffval.pdata;
00325 
00326   LogFullDebug(COMPONENT_STATE,
00327                "FOUND");
00328 
00329   return 1;
00330 }                               /* _9p_owner_Get_Pointer */
00331 
00341 void _9p_owner_PrintAll(void)
00342 {
00343   HashTable_Log(COMPONENT_STATE, ht_9p_owner);
00344 }                               /* _9p_owner_PrintAll */
00345 
00346 state_owner_t *get_9p_owner( struct sockaddr_storage * pclient_addr,
00347                              uint32_t    proc_id)
00348 {
00349   state_owner_t * pkey, *powner;
00350 
00351   pkey = (state_owner_t *)gsh_malloc(sizeof(*pkey));
00352   if(pkey == NULL)
00353     return NULL;
00354 
00355   memset(pkey, 0, sizeof(*pkey));
00356   pkey->so_type                             = STATE_LOCK_OWNER_9P;
00357   pkey->so_refcount                         = 1;
00358   pkey->so_owner.so_9p_owner.proc_id        = proc_id;
00359   memcpy( (char *)&pkey->so_owner.so_9p_owner.client_addr, (char *)pclient_addr, sizeof( struct sockaddr_storage ) ) ; 
00360   pkey->so_owner_len                        = 0 ;
00361   memset( pkey->so_owner_val, 0, NFS4_OPAQUE_LIMIT) ;
00362   if(isFullDebug(COMPONENT_STATE))
00363     {
00364       char str[HASHTABLE_DISPLAY_STRLEN];
00365 
00366       display_9p_owner(pkey, str);
00367 
00368       LogFullDebug(COMPONENT_STATE,
00369                    "Find 9P Owner KEY {%s}", str);
00370     }
00371 
00372   /* If we found it, return it, if we don't care, return NULL */
00373   if(_9p_owner_Get_Pointer(pkey, &powner) == 1 )
00374     {
00375       /* Discard the key we created and return the found 9P Owner */
00376       gsh_free(pkey);
00377 
00378       if(isFullDebug(COMPONENT_STATE))
00379         {
00380           char str[HASHTABLE_DISPLAY_STRLEN];
00381 
00382           display_9p_owner(powner, str);
00383           LogFullDebug(COMPONENT_STATE,
00384                        "Found {%s}",
00385                        str);
00386         }
00387 
00388       return powner;
00389     }
00390     
00391   powner = (state_owner_t *)gsh_malloc(sizeof(*pkey));
00392   if(powner == NULL)
00393     {
00394       gsh_free(pkey);
00395       return NULL;
00396     }
00397 
00398   /* Copy everything over */
00399   *powner = *pkey;
00400   init_glist(&powner->so_lock_list);
00401 
00402   if(pthread_mutex_init(&powner->so_mutex, NULL) == -1)
00403     {
00404       /* Mutex initialization failed, free the key and created owner */
00405       gsh_free(pkey);
00406       gsh_free(powner);
00407       return NULL;
00408     }
00409 
00410   if(isFullDebug(COMPONENT_STATE))
00411     {
00412       char str[HASHTABLE_DISPLAY_STRLEN];
00413 
00414       display_9p_owner(powner, str);
00415       LogFullDebug(COMPONENT_STATE,
00416                    "New {%s}", str);
00417     }
00418 
00419   /* Ref count the client as being used by this owner */
00420   if(_9p_owner_Set(pkey, powner) == 1)
00421     {
00422       if(isFullDebug(COMPONENT_STATE))
00423         {
00424           char str[HASHTABLE_DISPLAY_STRLEN];
00425 
00426           display_9p_owner(powner, str);
00427           LogFullDebug(COMPONENT_STATE,
00428                        "Set 9P Owner {%s}",
00429                        str);
00430         }
00431 
00432       return powner;
00433     }
00434 
00435   gsh_free(pkey);
00436   gsh_free(powner);
00437   return NULL;
00438 }