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 00026 /* static filesystem info. 00027 * The access is thread-safe because 00028 * it is read-only, except during initialization. 00029 */ 00030 fsal_staticfsinfo_t global_fs_info; 00031 00032 /* you can define here your supported attributes 00033 * if your filesystem is "homogenous". 00034 */ 00035 #define YOUR_SUPPORTED_ATTRIBUTES ( \ 00036 FSAL_ATTR_SUPPATTR | FSAL_ATTR_TYPE | FSAL_ATTR_SIZE | \ 00037 FSAL_ATTR_FSID | FSAL_ATTR_ACL | FSAL_ATTR_FILEID | \ 00038 FSAL_ATTR_MODE | FSAL_ATTR_NUMLINKS | FSAL_ATTR_OWNER | \ 00039 FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_CREATION | \ 00040 FSAL_ATTR_CTIME | FSAL_ATTR_MTIME | FSAL_ATTR_SPACEUSED | \ 00041 FSAL_ATTR_MOUNTFILEID | FSAL_ATTR_CHGTIME ) 00042 00043 /* filesystem info for your filesystem */ 00044 static fsal_staticfsinfo_t default_hpss_info = { 00045 0xFFFFFFFFFFFFFFFFLL, /* max file size (64bits) */ 00046 1024, /* max links for an object of your filesystem */ 00047 FSAL_MAX_NAME_LEN, /* max filename */ 00048 FSAL_MAX_PATH_LEN, /* min filename */ 00049 TRUE, /* no_trunc */ 00050 TRUE, /* chown restricted */ 00051 FALSE, /* case insensitivity */ 00052 TRUE, /* case preserving */ 00053 FSAL_EXPTYPE_PERSISTENT, /* FH expire type */ 00054 TRUE, /* hard link support */ 00055 TRUE, /* sym link support */ 00056 FALSE, /* lock support */ 00057 FALSE, /* lock owners */ 00058 FALSE, /* async blocking locks */ 00059 TRUE, /* named attributes */ 00060 TRUE, /* handles are unique and persistent */ 00061 {10, 0}, /* Duration of lease at FS in seconds */ 00062 FSAL_ACLSUPPORT_ALLOW, /* ACL support */ 00063 TRUE, /* can change times */ 00064 TRUE, /* homogenous */ 00065 YOUR_SUPPORTED_ATTRIBUTES, /* supported attributes */ 00066 (1024 * 1024), /* maxread size */ 00067 (1024 * 1024), /* maxwrite size */ 00068 0, /* default umask */ 00069 0, /* don't allow cross fileset export path */ 00070 0400, /* default access rights for xattrs: root=RW, owner=R */ 00071 0, /* default access check support in FSAL */ 00072 0, /* default share reservation support in FSAL */ 00073 0 /* default share reservation support with open owners in FSAL */ 00074 }; 00075 00076 /* variables for limiting the calls to the filesystem */ 00077 static int limit_calls = FALSE; 00078 semaphore_t sem_fs_calls; 00079 00080 /* threads keys for stats */ 00081 static pthread_key_t key_stats; 00082 static pthread_once_t once_key = PTHREAD_ONCE_INIT; 00083 00084 /* init keys */ 00085 static void init_keys(void) 00086 { 00087 if(pthread_key_create(&key_stats, NULL) == -1) 00088 LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_KEY_CREATE, errno); 00089 00090 return; 00091 } /* init_keys */ 00092 00104 void fsal_increment_nbcall(int function_index, fsal_status_t status) 00105 { 00106 00107 fsal_statistics_t *bythread_stat = NULL; 00108 00109 /* verify index */ 00110 00111 if(function_index >= FSAL_NB_FUNC) 00112 return; 00113 00114 /* first, we init the keys if this is the first time */ 00115 00116 if(pthread_once(&once_key, init_keys) != 0) 00117 { 00118 LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno); 00119 return; 00120 } 00121 00122 /* we get the specific value */ 00123 00124 bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats); 00125 00126 /* we allocate stats if this is the first time */ 00127 00128 if(bythread_stat == NULL) 00129 { 00130 int i; 00131 00132 bythread_stat = gsh_malloc(sizeof(fsal_statistics_t)); 00133 00134 if(bythread_stat == NULL) 00135 { 00136 LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM); 00137 } 00138 00139 /* inits the struct */ 00140 00141 for(i = 0; i < FSAL_NB_FUNC; i++) 00142 { 00143 bythread_stat->func_stats.nb_call[i] = 0; 00144 bythread_stat->func_stats.nb_success[i] = 0; 00145 bythread_stat->func_stats.nb_err_retryable[i] = 0; 00146 bythread_stat->func_stats.nb_err_unrecover[i] = 0; 00147 } 00148 00149 /* set the specific value */ 00150 pthread_setspecific(key_stats, (void *)bythread_stat); 00151 00152 } 00153 00154 /* we increment the values */ 00155 00156 if(bythread_stat) 00157 { 00158 bythread_stat->func_stats.nb_call[function_index]++; 00159 00160 if(!FSAL_IS_ERROR(status)) 00161 bythread_stat->func_stats.nb_success[function_index]++; 00162 else if(fsal_is_retryable(status)) 00163 bythread_stat->func_stats.nb_err_retryable[function_index]++; 00164 else 00165 bythread_stat->func_stats.nb_err_unrecover[function_index]++; 00166 } 00167 00168 return; 00169 } 00170 00181 void fsal_internal_getstats(fsal_statistics_t * output_stats) 00182 { 00183 00184 fsal_statistics_t *bythread_stat = NULL; 00185 00186 /* first, we init the keys if this is the first time */ 00187 if(pthread_once(&once_key, init_keys) != 0) 00188 { 00189 LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno); 00190 return; 00191 } 00192 00193 /* we get the specific value */ 00194 bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats); 00195 00196 /* we allocate stats if this is the first time */ 00197 if(bythread_stat == NULL) 00198 { 00199 int i; 00200 00201 if((bythread_stat = 00202 gsh_malloc(sizeof(fsal_statistics_t))) == NULL) 00203 LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM); 00204 00205 /* inits the struct */ 00206 for(i = 0; i < FSAL_NB_FUNC; i++) 00207 { 00208 bythread_stat->func_stats.nb_call[i] = 0; 00209 bythread_stat->func_stats.nb_success[i] = 0; 00210 bythread_stat->func_stats.nb_err_retryable[i] = 0; 00211 bythread_stat->func_stats.nb_err_unrecover[i] = 0; 00212 } 00213 00214 /* set the specific value */ 00215 pthread_setspecific(key_stats, (void *)bythread_stat); 00216 00217 } 00218 00219 if(output_stats) 00220 (*output_stats) = (*bythread_stat); 00221 00222 return; 00223 00224 } 00225 00229 void TakeTokenFSCall() 00230 { 00231 /* no limits */ 00232 if(limit_calls == FALSE) 00233 return; 00234 00235 /* there is a limit */ 00236 semaphore_P(&sem_fs_calls); 00237 00238 } 00239 00240 void ReleaseTokenFSCall() 00241 { 00242 /* no limits */ 00243 if(limit_calls == FALSE) 00244 return; 00245 00246 /* there is a limit */ 00247 semaphore_V(&sem_fs_calls); 00248 00249 } 00250 00251 #define SET_INTEGER_PARAM( cfg, p_init_info, _field ) \ 00252 switch( (p_init_info)->behaviors._field ){ \ 00253 case FSAL_INIT_FORCE_VALUE : \ 00254 /* force the value in any case */ \ 00255 cfg._field = (p_init_info)->values._field; \ 00256 break; \ 00257 case FSAL_INIT_MAX_LIMIT : \ 00258 /* check the higher limit */ \ 00259 if ( cfg._field > (p_init_info)->values._field ) \ 00260 cfg._field = (p_init_info)->values._field ; \ 00261 break; \ 00262 case FSAL_INIT_MIN_LIMIT : \ 00263 /* check the lower limit */ \ 00264 if ( cfg._field < (p_init_info)->values._field ) \ 00265 cfg._field = (p_init_info)->values._field ; \ 00266 break; \ 00267 /* In the other cases, we keep the default value. */ \ 00268 } 00269 00270 #define SET_BITMAP_PARAM( cfg, p_init_info, _field ) \ 00271 switch( (p_init_info)->behaviors._field ){ \ 00272 case FSAL_INIT_FORCE_VALUE : \ 00273 /* force the value in any case */ \ 00274 cfg._field = (p_init_info)->values._field; \ 00275 break; \ 00276 case FSAL_INIT_MAX_LIMIT : \ 00277 /* proceed a bit AND */ \ 00278 cfg._field &= (p_init_info)->values._field ; \ 00279 break; \ 00280 case FSAL_INIT_MIN_LIMIT : \ 00281 /* proceed a bit OR */ \ 00282 cfg._field |= (p_init_info)->values._field ; \ 00283 break; \ 00284 /* In the other cases, we keep the default value. */ \ 00285 } 00286 00287 #define SET_BOOLEAN_PARAM( cfg, p_init_info, _field ) \ 00288 switch( (p_init_info)->behaviors._field ){ \ 00289 case FSAL_INIT_FORCE_VALUE : \ 00290 /* force the value in any case */ \ 00291 cfg._field = (p_init_info)->values._field; \ 00292 break; \ 00293 case FSAL_INIT_MAX_LIMIT : \ 00294 /* proceed a boolean AND */ \ 00295 cfg._field = cfg._field && (p_init_info)->values._field ; \ 00296 break; \ 00297 case FSAL_INIT_MIN_LIMIT : \ 00298 /* proceed a boolean OR */ \ 00299 cfg._field = cfg._field && (p_init_info)->values._field ; \ 00300 break; \ 00301 /* In the other cases, we keep the default value. */ \ 00302 } 00303 00304 /* 00305 * This function initializes shared variables of the fsal. 00306 */ 00307 fsal_status_t fsal_internal_init_global(fsal_init_info_t * fsal_info, 00308 fs_common_initinfo_t * fs_common_info) 00309 { 00310 00311 /* sanity check */ 00312 if(!fsal_info || !fs_common_info) 00313 ReturnCode(ERR_FSAL_FAULT, 0); 00314 00315 /* inits FS call semaphore */ 00316 if(fsal_info->max_fs_calls > 0) 00317 { 00318 int rc; 00319 00320 limit_calls = TRUE; 00321 00322 rc = semaphore_init(&sem_fs_calls, fsal_info->max_fs_calls); 00323 00324 if(rc != 0) 00325 ReturnCode(ERR_FSAL_SERVERFAULT, rc); 00326 00327 LogDebug(COMPONENT_FSAL, 00328 "FSAL INIT: Max simultaneous calls to filesystem is limited to %u.", 00329 fsal_info->max_fs_calls); 00330 00331 } 00332 else 00333 { 00334 LogDebug(COMPONENT_FSAL 00335 "FSAL INIT: Max simultaneous calls to filesystem is unlimited."); 00336 } 00337 00338 /* setting default values. */ 00339 global_fs_info = default_hpss_info; 00340 00341 /* Analyzing fs_common_info struct */ 00342 00343 if((fs_common_info->behaviors.maxfilesize != FSAL_INIT_FS_DEFAULT) || 00344 (fs_common_info->behaviors.maxlink != FSAL_INIT_FS_DEFAULT) || 00345 (fs_common_info->behaviors.maxnamelen != FSAL_INIT_FS_DEFAULT) || 00346 (fs_common_info->behaviors.maxpathlen != FSAL_INIT_FS_DEFAULT) || 00347 (fs_common_info->behaviors.no_trunc != FSAL_INIT_FS_DEFAULT) || 00348 (fs_common_info->behaviors.case_insensitive != FSAL_INIT_FS_DEFAULT) || 00349 (fs_common_info->behaviors.case_preserving != FSAL_INIT_FS_DEFAULT) || 00350 (fs_common_info->behaviors.named_attr != FSAL_INIT_FS_DEFAULT) || 00351 (fs_common_info->behaviors.lease_time != FSAL_INIT_FS_DEFAULT) || 00352 (fs_common_info->behaviors.supported_attrs != FSAL_INIT_FS_DEFAULT) || 00353 (fs_common_info->behaviors.homogenous != FSAL_INIT_FS_DEFAULT)) 00354 ReturnCode(ERR_FSAL_NOTSUPP, 0); 00355 00356 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, symlink_support); 00357 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, link_support); 00358 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support); 00359 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_owner); 00360 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_async_block); 00361 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, cansettime); 00362 00363 SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxread); 00364 SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxwrite); 00365 00366 SET_BITMAP_PARAM(global_fs_info, fs_common_info, umask); 00367 00368 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, auth_exportpath_xdev); 00369 00370 SET_BITMAP_PARAM(global_fs_info, fs_common_info, xattr_access_rights); 00371 00372 display_fsinfo(&global_fs_info); 00373 00374 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00375 } 00376 00390 fsal_boolean_t fsal_do_log(fsal_status_t status) 00391 { 00392 00393 switch (status.major) 00394 { 00395 00396 /* here are the code, we want to trace */ 00397 case ERR_FSAL_DELAY: 00398 case ERR_FSAL_PERM: 00399 case ERR_FSAL_IO: 00400 case ERR_FSAL_NXIO: 00401 case ERR_FSAL_NOT_OPENED: 00402 case ERR_FSAL_NOMEM: 00403 case ERR_FSAL_FAULT: 00404 case ERR_FSAL_XDEV: 00405 case ERR_FSAL_INVAL: 00406 case ERR_FSAL_FBIG: 00407 case ERR_FSAL_NOSPC: 00408 case ERR_FSAL_MLINK: 00409 case ERR_FSAL_NAMETOOLONG: 00410 case ERR_FSAL_SEC: 00411 case ERR_FSAL_SERVERFAULT: 00412 return TRUE; 00413 00414 default: 00415 return FALSE; 00416 } 00417 00418 }