nfs-ganesha 1.4

fsal_internal.c

Go to the documentation of this file.
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 }