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 "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 }