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