nfs-ganesha 1.4
|
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 }