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