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 "abstract_mem.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 libzfswrap_handle_t *p_zhd; 00034 00035 size_t i_snapshots; 00036 snapshot_t *p_snapshots; 00037 pthread_rwlock_t vfs_lock = PTHREAD_RWLOCK_INITIALIZER; 00038 00039 /* filesystem info for your filesystem */ 00040 static fsal_staticfsinfo_t default_zfs_info = { 00041 0xFFFFFFFFFFFFFFFFLL, /* max file size (64bits) */ 00042 1024, /* max links for an object of your filesystem */ 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, /* sym link support */ 00052 FALSE, /* lock support */ 00053 FALSE, /* lock owners */ 00054 FALSE, /* async blocking locks */ 00055 TRUE, /* named attributes */ 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 POSIX_SUPPORTED_ATTRIBUTES, /* supported attributes */ 00062 0, /* maxread size */ 00063 0, /* 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 /* variables for limiting the calls to the filesystem */ 00073 static int limit_calls = FALSE; 00074 semaphore_t sem_fs_calls; 00075 00076 /* threads keys for stats */ 00077 static pthread_key_t key_stats; 00078 static pthread_once_t once_key = PTHREAD_ONCE_INIT; 00079 00080 /* init keys */ 00081 static void init_keys(void) 00082 { 00083 if(pthread_key_create(&key_stats, NULL) == -1) 00084 LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_KEY_CREATE, errno); 00085 00086 return; 00087 } /* init_keys */ 00088 00100 void fsal_increment_nbcall(int function_index, fsal_status_t status) 00101 { 00102 00103 fsal_statistics_t *bythread_stat = NULL; 00104 00105 /* verify index */ 00106 00107 if(function_index >= FSAL_NB_FUNC) 00108 return; 00109 00110 /* first, we init the keys if this is the first time */ 00111 00112 if(pthread_once(&once_key, init_keys) != 0) 00113 { 00114 LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno); 00115 return; 00116 } 00117 00118 /* we get the specific value */ 00119 00120 bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats); 00121 00122 /* we allocate stats if this is the first time */ 00123 00124 if(bythread_stat == NULL) 00125 { 00126 int i; 00127 00128 bythread_stat = gsh_malloc(sizeof(fsal_statistics_t)); 00129 00130 if(bythread_stat == NULL) 00131 { 00132 LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM); 00133 } 00134 00135 /* inits the struct */ 00136 00137 for(i = 0; i < FSAL_NB_FUNC; i++) 00138 { 00139 bythread_stat->func_stats.nb_call[i] = 0; 00140 bythread_stat->func_stats.nb_success[i] = 0; 00141 bythread_stat->func_stats.nb_err_retryable[i] = 0; 00142 bythread_stat->func_stats.nb_err_unrecover[i] = 0; 00143 } 00144 00145 /* set the specific value */ 00146 pthread_setspecific(key_stats, (void *)bythread_stat); 00147 00148 } 00149 00150 /* we increment the values */ 00151 00152 if(bythread_stat) 00153 { 00154 bythread_stat->func_stats.nb_call[function_index]++; 00155 00156 if(!FSAL_IS_ERROR(status)) 00157 bythread_stat->func_stats.nb_success[function_index]++; 00158 else if(fsal_is_retryable(status)) 00159 bythread_stat->func_stats.nb_err_retryable[function_index]++; 00160 else 00161 bythread_stat->func_stats.nb_err_unrecover[function_index]++; 00162 } 00163 00164 return; 00165 } 00166 00177 void fsal_internal_getstats(fsal_statistics_t * output_stats) 00178 { 00179 00180 fsal_statistics_t *bythread_stat = NULL; 00181 00182 /* first, we init the keys if this is the first time */ 00183 if(pthread_once(&once_key, init_keys) != 0) 00184 { 00185 LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno); 00186 return; 00187 } 00188 00189 /* we get the specific value */ 00190 bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats); 00191 00192 /* we allocate stats if this is the first time */ 00193 if(bythread_stat == NULL) 00194 { 00195 int i; 00196 00197 if((bythread_stat = 00198 gsh_malloc(sizeof(fsal_statistics_t))) == NULL) 00199 LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM); 00200 00201 /* inits the struct */ 00202 for(i = 0; i < FSAL_NB_FUNC; i++) 00203 { 00204 bythread_stat->func_stats.nb_call[i] = 0; 00205 bythread_stat->func_stats.nb_success[i] = 0; 00206 bythread_stat->func_stats.nb_err_retryable[i] = 0; 00207 bythread_stat->func_stats.nb_err_unrecover[i] = 0; 00208 } 00209 00210 /* set the specific value */ 00211 pthread_setspecific(key_stats, (void *)bythread_stat); 00212 00213 } 00214 00215 if(output_stats) 00216 (*output_stats) = (*bythread_stat); 00217 00218 return; 00219 00220 } 00221 00225 void TakeTokenFSCall() 00226 { 00227 /* no limits */ 00228 if(limit_calls == FALSE) 00229 return; 00230 00231 /* there is a limit */ 00232 semaphore_P(&sem_fs_calls); 00233 00234 } 00235 00236 void ReleaseTokenFSCall() 00237 { 00238 /* no limits */ 00239 if(limit_calls == FALSE) 00240 return; 00241 00242 /* there is a limit */ 00243 semaphore_V(&sem_fs_calls); 00244 00245 } 00246 00247 /* 00248 * This function initializes shared variables of the fsal. 00249 */ 00250 fsal_status_t fsal_internal_init_global(fsal_init_info_t * fsal_info, 00251 fs_common_initinfo_t * fs_common_info, 00252 fs_specific_initinfo_t * fs_specific_info) 00253 { 00254 00255 /* sanity check */ 00256 if(!fsal_info || !fs_common_info) 00257 ReturnCode(ERR_FSAL_FAULT, 0); 00258 00259 00260 /* inits FS call semaphore */ 00261 if(fsal_info->max_fs_calls > 0) 00262 { 00263 int rc; 00264 00265 limit_calls = TRUE; 00266 00267 rc = semaphore_init(&sem_fs_calls, fsal_info->max_fs_calls); 00268 00269 if(rc != 0) 00270 ReturnCode(ERR_FSAL_SERVERFAULT, rc); 00271 00272 LogDebug(COMPONENT_FSAL, 00273 "FSAL INIT: Max simultaneous calls to filesystem is limited to %u.", 00274 fsal_info->max_fs_calls); 00275 00276 } 00277 else 00278 { 00279 LogDebug(COMPONENT_FSAL, 00280 "FSAL INIT: Max simultaneous calls to filesystem is unlimited."); 00281 } 00282 00283 /* setting default values. */ 00284 global_fs_info = default_zfs_info; 00285 00286 /* Analyzing fs_common_info struct */ 00287 00288 if((fs_common_info->behaviors.maxfilesize != FSAL_INIT_FS_DEFAULT) || 00289 (fs_common_info->behaviors.maxlink != FSAL_INIT_FS_DEFAULT) || 00290 (fs_common_info->behaviors.maxnamelen != FSAL_INIT_FS_DEFAULT) || 00291 (fs_common_info->behaviors.maxpathlen != FSAL_INIT_FS_DEFAULT) || 00292 (fs_common_info->behaviors.no_trunc != FSAL_INIT_FS_DEFAULT) || 00293 (fs_common_info->behaviors.case_insensitive != FSAL_INIT_FS_DEFAULT) || 00294 (fs_common_info->behaviors.case_preserving != FSAL_INIT_FS_DEFAULT) || 00295 (fs_common_info->behaviors.named_attr != FSAL_INIT_FS_DEFAULT) || 00296 (fs_common_info->behaviors.lease_time != FSAL_INIT_FS_DEFAULT) || 00297 (fs_common_info->behaviors.supported_attrs != FSAL_INIT_FS_DEFAULT) || 00298 (fs_common_info->behaviors.homogenous != FSAL_INIT_FS_DEFAULT)) 00299 ReturnCode(ERR_FSAL_NOTSUPP, 0); 00300 00301 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, symlink_support); 00302 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, link_support); 00303 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support); 00304 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_owner); 00305 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_async_block); 00306 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, cansettime); 00307 00308 SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxread); 00309 SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxwrite); 00310 00311 SET_BITMAP_PARAM(global_fs_info, fs_common_info, umask); 00312 00313 SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, auth_exportpath_xdev); 00314 00315 SET_BITMAP_PARAM(global_fs_info, fs_common_info, xattr_access_rights); 00316 00317 display_fsinfo(&global_fs_info); 00318 00319 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00320 }