nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 */ 00004 00015 #define FSAL_INTERNAL_C 00016 #ifdef HAVE_CONFIG_H 00017 #include "config.h" 00018 #endif 00019 00020 #include "fsal.h" 00021 #include "fsal_internal.h" 00022 #include "SemN.h" 00023 00024 #include <pthread.h> 00025 #include "abstract_mem.h" 00026 00027 /* credential lifetime (1h) */ 00028 fsal_uint_t CredentialLifetime = 3600; 00029 00030 /* Behavior for inconsistent direntries */ 00031 fsal_uint_t ReturnInconsistentDirent = FALSE; 00032 00033 /* static filesystem info. 00034 * The access is thread-safe because 00035 * it is read-only, except during initialization. 00036 */ 00037 fsal_staticfsinfo_t global_fs_info; 00038 00039 /* filesystem info for HPSS */ 00040 static fsal_staticfsinfo_t default_hpss_info = { 00041 0xFFFFFFFFFFFFFFFFLL, /* max file size (64bits) */ 00042 NS_MAX_HARD_LINK_VALUE, /* max links */ 00043 FSAL_MAX_NAME_LEN, /* max filename */ 00044 FSAL_MAX_PATH_LEN, /* min filename */ 00045 TRUE, /* no_trunc */ 00046 TRUE, /* chown restricted */ 00047 FALSE, /* case insensitivity */ 00048 TRUE, /* case preserving */ 00049 FSAL_EXPTYPE_PERSISTENT, /* FH expire type */ 00050 TRUE, /* hard link support */ 00051 TRUE, /* symlink support */ 00052 FALSE, /* lock management */ 00053 FALSE, /* lock owners */ 00054 FALSE, /* async blocking locks */ 00055 TRUE, /* named attributes are supported */ 00056 TRUE, /* handles are unique and persistent */ 00057 {10, 0}, /* Duration of lease at FS in seconds */ 00058 FSAL_ACLSUPPORT_ALLOW, /* ACL support */ 00059 TRUE, /* can change times */ 00060 TRUE, /* homogenous */ 00061 HPSS_SUPPORTED_ATTRIBUTES, /* supported attributes */ 00062 (1024 * 1024), /* maxread size */ 00063 (1024 * 1024), /* maxwrite size */ 00064 0, /* default umask */ 00065 0, /* don't allow cross fileset export path */ 00066 0400, /* default access rights for xattrs: root=RW, owner=R */ 00067 0, /* default access check support in FSAL */ 00068 0, /* default share reservation support in FSAL */ 00069 0 /* default share reservation support with open owners in FSAL */ 00070 }; 00071 00072 /* 00073 * Log Descriptor 00074 */ 00075 /* variables for limiting the calls to the filesystem */ 00076 static int limit_calls = FALSE; 00077 semaphore_t sem_fs_calls; 00078 00079 /* threads keys for stats */ 00080 static pthread_key_t key_stats; 00081 static pthread_once_t once_key = PTHREAD_ONCE_INIT; 00082 00083 /* init keys */ 00084 static void init_keys(void) 00085 { 00086 if(pthread_key_create(&key_stats, NULL) == -1) 00087 LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_KEY_CREATE, errno); 00088 00089 return; 00090 } /* init_keys */ 00091 00103 void fsal_increment_nbcall(int function_index, fsal_status_t status) 00104 { 00105 00106 fsal_statistics_t *bythread_stat = NULL; 00107 00108 /* verify index */ 00109 00110 if(function_index >= FSAL_NB_FUNC) 00111 return; 00112 00113 /* first, we init the keys if this is the first time */ 00114 00115 if(pthread_once(&once_key, init_keys) != 0) 00116 { 00117 LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno); 00118 return; 00119 } 00120 00121 /* we get the specific value */ 00122 00123 bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats); 00124 00125 /* we allocate stats if this is the first time */ 00126 00127 if(bythread_stat == NULL) 00128 { 00129 int i; 00130 00131 bythread_stat = gsh_malloc(sizeof(fsal_statistics_t)); 00132 00133 if(bythread_stat == NULL) 00134 { 00135 LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM); 00136 } 00137 00138 /* inits the struct */ 00139 00140 for(i = 0; i < FSAL_NB_FUNC; i++) 00141 { 00142 bythread_stat->func_stats.nb_call[i] = 0; 00143 bythread_stat->func_stats.nb_success[i] = 0; 00144 bythread_stat->func_stats.nb_err_retryable[i] = 0; 00145 bythread_stat->func_stats.nb_err_unrecover[i] = 0; 00146 } 00147 00148 /* set the specific value */ 00149 pthread_setspecific(key_stats, (void *)bythread_stat); 00150 00151 } 00152 00153 /* we increment the values */ 00154 00155 if(bythread_stat) 00156 { 00157 bythread_stat->func_stats.nb_call[function_index]++; 00158 00159 if(!FSAL_IS_ERROR(status)) 00160 bythread_stat->func_stats.nb_success[function_index]++; 00161 else if(fsal_is_retryable(status)) 00162 bythread_stat->func_stats.nb_err_retryable[function_index]++; 00163 else 00164 bythread_stat->func_stats.nb_err_unrecover[function_index]++; 00165 } 00166 00167 return; 00168 } 00169 00180 void fsal_internal_getstats(fsal_statistics_t * output_stats) 00181 { 00182 00183 fsal_statistics_t *bythread_stat = NULL; 00184 00185 /* first, we init the keys if this is the first time */ 00186 if(pthread_once(&once_key, init_keys) != 0) 00187 { 00188 LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno); 00189 return; 00190 } 00191 00192 /* we get the specific value */ 00193 bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats); 00194 00195 /* we allocate stats if this is the first time */ 00196 if(bythread_stat == NULL) 00197 { 00198 int i; 00199 00200 if((bythread_stat = 00201 gsh_mem(sizeof(fsal_statistics_t))) == NULL) 00202 LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM); 00203 00204 /* inits the struct */ 00205 for(i = 0; i < FSAL_NB_FUNC; i++) 00206 { 00207 bythread_stat->func_stats.nb_call[i] = 0; 00208 bythread_stat->func_stats.nb_success[i] = 0; 00209 bythread_stat->func_stats.nb_err_retryable[i] = 0; 00210 bythread_stat->func_stats.nb_err_unrecover[i] = 0; 00211 } 00212 00213 /* set the specific value */ 00214 pthread_setspecific(key_stats, (void *)bythread_stat); 00215 00216 } 00217 00218 if(output_stats) 00219 (*output_stats) = (*bythread_stat); 00220 00221 return; 00222 00223 } 00224 00235 void fsal_internal_SetCredentialLifetime(fsal_uint_t lifetime_in) 00236 { 00237 CredentialLifetime = lifetime_in; 00238 } 00239 00249 void fsal_internal_SetReturnInconsistentDirent(fsal_uint_t bool_in) 00250 { 00251 ReturnInconsistentDirent = bool_in; 00252 } 00253 00257 void TakeTokenFSCall() 00258 { 00259 /* no limits */ 00260 if(limit_calls == FALSE) 00261 return; 00262 00263 /* there is a limit */ 00264 semaphore_P(&sem_fs_calls); 00265 00266 } 00267 00268 void ReleaseTokenFSCall() 00269 { 00270 /* no limits */ 00271 if(limit_calls == FALSE) 00272 return; 00273 00274 /* there is a limit */ 00275 semaphore_V(&sem_fs_calls); 00276 00277 } 00278 00279 #define SET_INTEGER_PARAM( cfg, p_init_info, _field ) \ 00280 switch( (p_init_info)->behaviors._field ){ \ 00281 case FSAL_INIT_FORCE_VALUE : \ 00282 /* force the value in any case */ \ 00283 cfg._field = (p_init_info)->values._field; \ 00284 break; \ 00285 case FSAL_INIT_MAX_LIMIT : \ 00286 /* check the higher limit */ \ 00287 if ( cfg._field > (p_init_info)->values._field ) \ 00288 cfg._field = (p_init_info)->values._field ; \ 00289 break; \ 00290 case FSAL_INIT_MIN_LIMIT : \ 00291 /* check the lower limit */ \ 00292 if ( cfg._field < (p_init_info)->values._field ) \ 00293 cfg._field = (p_init_info)->values._field ; \ 00294 break; \ 00295 /* In the other cases, we keep the default value. */ \ 00296 } 00297 00298 #define SET_BITMAP_PARAM( cfg, p_init_info, _field ) \ 00299 switch( (p_init_info)->behaviors._field ){ \ 00300 case FSAL_INIT_FORCE_VALUE : \ 00301 /* force the value in any case */ \ 00302 cfg._field = (p_init_info)->values._field; \ 00303 break; \ 00304 case FSAL_INIT_MAX_LIMIT : \ 00305 /* proceed a bit AND */ \ 00306 cfg._field &= (p_init_info)->values._field ; \ 00307 break; \ 00308 case FSAL_INIT_MIN_LIMIT : \ 00309 /* proceed a bit OR */ \ 00310 cfg._field |= (p_init_info)->values._field ; \ 00311 break; \ 00312 /* In the other cases, we keep the default value. */ \ 00313 } 00314 00315 #define SET_BOOLEAN_PARAM( cfg, p_init_info, _field ) \ 00316 switch( (p_init_info)->behaviors._field ){ \ 00317 case FSAL_INIT_FORCE_VALUE : \ 00318 /* force the value in any case */ \ 00319 cfg._field = (p_init_info)->values._field; \ 00320 break; \ 00321 case FSAL_INIT_MAX_LIMIT : \ 00322 /* proceed a boolean AND */ \ 00323 cfg._field = cfg._field && (p_init_info)->values._field ; \ 00324 break; \ 00325 case FSAL_INIT_MIN_LIMIT : \ 00326 /* proceed a boolean OR */ \ 00327 cfg._field = cfg._field && (p_init_info)->values._field ; \ 00328 break; \ 00329 /* In the other cases, we keep the default value. */ \ 00330 } 00331 00332 /* 00333 * This function initializes shared variables of the fsal. 00334 */ 00335 fsal_status_t fsal_internal_init_global(fsal_init_info_t * fsal_info, 00336 fs_common_initinfo_t * fs_common_info) 00337 { 00338 00339 /* sanity check */ 00340 if(!fsal_info || !fs_common_info) 00341 ReturnCode(ERR_FSAL_FAULT, 0); 00342 00343 00344 /* inits FS call semaphore */ 00345 if(fsal_info->max_fs_calls > 0) 00346 { 00347 int rc; 00348 00349 limit_calls = TRUE; 00350 00351 rc = semaphore_init(&sem_fs_calls, fsal_info->max_fs_calls); 00352 00353 if(rc != 0) 00354 ReturnCode(ERR_FSAL_SERVERFAULT, rc); 00355 00356 LogDebug(COMPONENT_FSAL, 00357 "FSAL INIT: Max simultaneous calls to filesystem is limited to %u.", 00358 fsal_info->max_fs_calls); 00359 00360 } 00361 else 00362 { 00363 LogDebug(COMPONENT_FSAL, 00364 "FSAL INIT: Max simultaneous calls to filesystem is unlimited."); 00365 } 00366 00367 /* setting default values. */ 00368 global_fs_info = default_hpss_info; 00369 00370 /* Analyzing fs_common_info struct */ 00371 00372 if((fs_common_info->behaviors.maxfilesize != FSAL_INIT_FS_DEFAULT) || 00373 (fs_common_info->behaviors.maxlink != FSAL_INIT_FS_DEFAULT) || 00374 (fs_common_info->behaviors.maxnamelen != FSAL_INIT_FS_DEFAULT) || 00375 (fs_common_info->behaviors.maxpathlen != FSAL_INIT_FS_DEFAULT) || 00376 (fs_common_info->behaviors.no_trunc != FSAL_INIT_FS_DEFAULT) || 00377 (fs_common_info->behaviors.case_insensitive != FSAL_INIT_FS_DEFAULT) || 00378 (fs_common_info->behaviors.case_preserving != FSAL_INIT_FS_DEFAULT) || 00379 (fs_common_info->behaviors.named_attr != FSAL_INIT_FS_DEFAULT) || 00380 (fs_common_info->behaviors.lease_time != FSAL_INIT_FS_DEFAULT) || 00381 (fs_common_info->behaviors.supported_attrs != FSAL_INIT_FS_DEFAULT) || 00382 (fs_common_info->behaviors.homogenous != FSAL_INIT_FS_DEFAULT)) 00383 ReturnCode(ERR_FSAL_NOTSUPP, 0); 00384 00385 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, symlink_support); 00386 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, link_support); 00387 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support); 00388 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_owner); 00389 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_async_block); 00390 00391 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, cansettime); 00392 00393 SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxread); 00394 SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxwrite); 00395 00396 SET_BITMAP_PARAM(global_fs_info, fs_common_info, umask); 00397 00398 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, auth_exportpath_xdev); 00399 00400 SET_BITMAP_PARAM(global_fs_info, fs_common_info, xattr_access_rights); 00401 00402 LogDebug(COMPONENT_FSAL, "FileSystem info :"); 00403 LogDebug(COMPONENT_FSAL, " maxfilesize = %llX ", 00404 global_fs_info.maxfilesize); 00405 LogDebug(COMPONENT_FSAL, " maxlink = %lu ", global_fs_info.maxlink); 00406 LogDebug(COMPONENT_FSAL, " maxnamelen = %lu ", 00407 global_fs_info.maxnamelen); 00408 LogDebug(COMPONENT_FSAL, " maxpathlen = %lu ", 00409 global_fs_info.maxpathlen); 00410 LogDebug(COMPONENT_FSAL, " no_trunc = %d ", global_fs_info.no_trunc); 00411 LogDebug(COMPONENT_FSAL, " chown_restricted = %d ", 00412 global_fs_info.chown_restricted); 00413 LogDebug(COMPONENT_FSAL, " case_insensitive = %d ", 00414 global_fs_info.case_insensitive); 00415 LogDebug(COMPONENT_FSAL, " case_preserving = %d ", 00416 global_fs_info.case_preserving); 00417 LogDebug(COMPONENT_FSAL, " fh_expire_type = %hu ", 00418 global_fs_info.fh_expire_type); 00419 LogDebug(COMPONENT_FSAL, " link_support = %d ", 00420 global_fs_info.link_support); 00421 LogDebug(COMPONENT_FSAL, " symlink_support = %d ", 00422 global_fs_info.symlink_support); 00423 LogDebug(COMPONENT_FSAL, " lock_support = %d ", 00424 global_fs_info.lock_support); 00425 LogDebug(COMPONENT_FSAL, " lock_support_owner = %d ", 00426 global_fs_info.lock_support_owner); 00427 LogDebug(COMPONENT_FSAL, " lock_support_async_block = %d ", 00428 global_fs_info.lock_support_async_block); 00429 LogDebug(COMPONENT_FSAL, " named_attr = %d ", 00430 global_fs_info.named_attr); 00431 LogDebug(COMPONENT_FSAL, " unique_handles = %d ", 00432 global_fs_info.unique_handles); 00433 LogDebug(COMPONENT_FSAL, " lease_time = %u.%u ", 00434 global_fs_info.lease_time.seconds, 00435 global_fs_info.lease_time.nseconds); 00436 LogDebug(COMPONENT_FSAL, " acl_support = %hu ", 00437 global_fs_info.acl_support); 00438 LogDebug(COMPONENT_FSAL, " cansettime = %d ", 00439 global_fs_info.cansettime); 00440 LogDebug(COMPONENT_FSAL, " homogenous = %d ", 00441 global_fs_info.homogenous); 00442 LogDebug(COMPONENT_FSAL, " supported_attrs = %llX ", 00443 global_fs_info.supported_attrs); 00444 LogDebug(COMPONENT_FSAL, " maxread = %llX ", 00445 global_fs_info.maxread); 00446 LogDebug(COMPONENT_FSAL, " maxwrite = %llX ", 00447 global_fs_info.maxwrite); 00448 LogDebug(COMPONENT_FSAL, " umask = %#o ", global_fs_info.umask); 00449 LogDebug(COMPONENT_FSAL, " auth_exportpath_xdev = %d ", 00450 global_fs_info.auth_exportpath_xdev); 00451 LogDebug(COMPONENT_FSAL, " xattr_access_rights = %#o ", 00452 global_fs_info.xattr_access_rights); 00453 00454 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00455 } 00456 00470 fsal_boolean_t fsal_do_log(fsal_status_t status) 00471 { 00472 00473 switch (status.major) 00474 { 00475 00476 /* here are the code, we want to trace */ 00477 case ERR_FSAL_DELAY: 00478 case ERR_FSAL_PERM: 00479 case ERR_FSAL_IO: 00480 case ERR_FSAL_NXIO: 00481 case ERR_FSAL_NOT_OPENED: 00482 case ERR_FSAL_NOMEM: 00483 case ERR_FSAL_FAULT: 00484 case ERR_FSAL_XDEV: 00485 case ERR_FSAL_INVAL: 00486 case ERR_FSAL_FBIG: 00487 case ERR_FSAL_NOSPC: 00488 case ERR_FSAL_MLINK: 00489 case ERR_FSAL_NAMETOOLONG: 00490 case ERR_FSAL_SEC: 00491 case ERR_FSAL_SERVERFAULT: 00492 return TRUE; 00493 00494 default: 00495 return FALSE; 00496 } 00497 00498 }