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 #include "abstract_mem.h"
00026 
00027 /* credential lifetime (1h) */
00028 fsal_uint_t CredentialLifetime = 3600;
00029 
00030 /* Behavior for inconsistent direntries */
00031 fsal_uint_t ReturnInconsistentDirent = FALSE;
00032 
00033 /* static filesystem info.
00034  * The access is thread-safe because
00035  * it is read-only, except during initialization.
00036  */
00037 fsal_staticfsinfo_t global_fs_info;
00038 
00039 /* filesystem info for HPSS */
00040 static fsal_staticfsinfo_t default_hpss_info = {
00041   0xFFFFFFFFFFFFFFFFLL,         /* max file size (64bits) */
00042   NS_MAX_HARD_LINK_VALUE,       /* max links */
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,                         /* symlink support */
00052   FALSE,                        /* lock management */
00053   FALSE,                        /* lock owners */
00054   FALSE,                        /* async blocking locks */
00055   TRUE,                         /* named attributes are supported */
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   HPSS_SUPPORTED_ATTRIBUTES,    /* supported attributes */
00062   (1024 * 1024),                /* maxread size */
00063   (1024 * 1024),                /* 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 /*
00073  *  Log Descriptor
00074  */
00075 /* variables for limiting the calls to the filesystem */
00076 static int limit_calls = FALSE;
00077 semaphore_t sem_fs_calls;
00078 
00079 /* threads keys for stats */
00080 static pthread_key_t key_stats;
00081 static pthread_once_t once_key = PTHREAD_ONCE_INIT;
00082 
00083 /* init keys */
00084 static void init_keys(void)
00085 {
00086   if(pthread_key_create(&key_stats, NULL) == -1)
00087     LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_KEY_CREATE, errno);
00088 
00089   return;
00090 }                               /* init_keys */
00091 
00103 void fsal_increment_nbcall(int function_index, fsal_status_t status)
00104 {
00105 
00106   fsal_statistics_t *bythread_stat = NULL;
00107 
00108   /* verify index */
00109 
00110   if(function_index >= FSAL_NB_FUNC)
00111     return;
00112 
00113   /* first, we init the keys if this is the first time */
00114 
00115   if(pthread_once(&once_key, init_keys) != 0)
00116     {
00117       LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno);
00118       return;
00119     }
00120 
00121   /* we get the specific value */
00122 
00123   bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats);
00124 
00125   /* we allocate stats if this is the first time */
00126 
00127   if(bythread_stat == NULL)
00128     {
00129       int i;
00130 
00131       bythread_stat = gsh_malloc(sizeof(fsal_statistics_t));
00132 
00133       if(bythread_stat == NULL)
00134         {
00135           LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM);
00136         }
00137 
00138       /* inits the struct */
00139 
00140       for(i = 0; i < FSAL_NB_FUNC; i++)
00141         {
00142           bythread_stat->func_stats.nb_call[i] = 0;
00143           bythread_stat->func_stats.nb_success[i] = 0;
00144           bythread_stat->func_stats.nb_err_retryable[i] = 0;
00145           bythread_stat->func_stats.nb_err_unrecover[i] = 0;
00146         }
00147 
00148       /* set the specific value */
00149       pthread_setspecific(key_stats, (void *)bythread_stat);
00150 
00151     }
00152 
00153   /* we increment the values */
00154 
00155   if(bythread_stat)
00156     {
00157       bythread_stat->func_stats.nb_call[function_index]++;
00158 
00159       if(!FSAL_IS_ERROR(status))
00160         bythread_stat->func_stats.nb_success[function_index]++;
00161       else if(fsal_is_retryable(status))
00162         bythread_stat->func_stats.nb_err_retryable[function_index]++;
00163       else
00164         bythread_stat->func_stats.nb_err_unrecover[function_index]++;
00165     }
00166 
00167   return;
00168 }
00169 
00180 void fsal_internal_getstats(fsal_statistics_t * output_stats)
00181 {
00182 
00183   fsal_statistics_t *bythread_stat = NULL;
00184 
00185   /* first, we init the keys if this is the first time */
00186   if(pthread_once(&once_key, init_keys) != 0)
00187     {
00188       LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno);
00189       return;
00190     }
00191 
00192   /* we get the specific value */
00193   bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats);
00194 
00195   /* we allocate stats if this is the first time */
00196   if(bythread_stat == NULL)
00197     {
00198       int i;
00199 
00200       if((bythread_stat =
00201           gsh_mem(sizeof(fsal_statistics_t))) == NULL)
00202         LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM);
00203 
00204       /* inits the struct */
00205       for(i = 0; i < FSAL_NB_FUNC; i++)
00206         {
00207           bythread_stat->func_stats.nb_call[i] = 0;
00208           bythread_stat->func_stats.nb_success[i] = 0;
00209           bythread_stat->func_stats.nb_err_retryable[i] = 0;
00210           bythread_stat->func_stats.nb_err_unrecover[i] = 0;
00211         }
00212 
00213       /* set the specific value */
00214       pthread_setspecific(key_stats, (void *)bythread_stat);
00215 
00216     }
00217 
00218   if(output_stats)
00219     (*output_stats) = (*bythread_stat);
00220 
00221   return;
00222 
00223 }
00224 
00235 void fsal_internal_SetCredentialLifetime(fsal_uint_t lifetime_in)
00236 {
00237   CredentialLifetime = lifetime_in;
00238 }
00239 
00249 void fsal_internal_SetReturnInconsistentDirent(fsal_uint_t bool_in)
00250 {
00251   ReturnInconsistentDirent = bool_in;
00252 }
00253 
00257 void TakeTokenFSCall()
00258 {
00259   /* no limits */
00260   if(limit_calls == FALSE)
00261     return;
00262 
00263   /* there is a limit */
00264   semaphore_P(&sem_fs_calls);
00265 
00266 }
00267 
00268 void ReleaseTokenFSCall()
00269 {
00270   /* no limits */
00271   if(limit_calls == FALSE)
00272     return;
00273 
00274   /* there is a limit */
00275   semaphore_V(&sem_fs_calls);
00276 
00277 }
00278 
00279 #define SET_INTEGER_PARAM( cfg, p_init_info, _field )             \
00280     switch( (p_init_info)->behaviors._field ){                    \
00281     case FSAL_INIT_FORCE_VALUE :                                  \
00282       /* force the value in any case */                           \
00283       cfg._field = (p_init_info)->values._field;                  \
00284       break;                                                      \
00285     case FSAL_INIT_MAX_LIMIT :                                    \
00286       /* check the higher limit */                                \
00287       if ( cfg._field > (p_init_info)->values._field )            \
00288         cfg._field = (p_init_info)->values._field ;               \
00289       break;                                                      \
00290     case FSAL_INIT_MIN_LIMIT :                                    \
00291       /* check the lower limit */                                 \
00292       if ( cfg._field < (p_init_info)->values._field )            \
00293         cfg._field = (p_init_info)->values._field ;               \
00294       break;                                                      \
00295     /* In the other cases, we keep the default value. */          \
00296     }
00297 
00298 #define SET_BITMAP_PARAM( cfg, p_init_info, _field )              \
00299     switch( (p_init_info)->behaviors._field ){                    \
00300     case FSAL_INIT_FORCE_VALUE :                                  \
00301         /* force the value in any case */                         \
00302         cfg._field = (p_init_info)->values._field;                \
00303         break;                                                    \
00304     case FSAL_INIT_MAX_LIMIT :                                    \
00305       /* proceed a bit AND */                                     \
00306       cfg._field &= (p_init_info)->values._field ;                \
00307       break;                                                      \
00308     case FSAL_INIT_MIN_LIMIT :                                    \
00309       /* proceed a bit OR */                                      \
00310       cfg._field |= (p_init_info)->values._field ;                \
00311       break;                                                      \
00312     /* In the other cases, we keep the default value. */          \
00313     }
00314 
00315 #define SET_BOOLEAN_PARAM( cfg, p_init_info, _field )             \
00316     switch( (p_init_info)->behaviors._field ){                    \
00317     case FSAL_INIT_FORCE_VALUE :                                  \
00318         /* force the value in any case */                         \
00319         cfg._field = (p_init_info)->values._field;                \
00320         break;                                                    \
00321     case FSAL_INIT_MAX_LIMIT :                                    \
00322       /* proceed a boolean AND */                                 \
00323       cfg._field = cfg._field && (p_init_info)->values._field ;   \
00324       break;                                                      \
00325     case FSAL_INIT_MIN_LIMIT :                                    \
00326       /* proceed a boolean OR */                                  \
00327       cfg._field = cfg._field && (p_init_info)->values._field ;   \
00328       break;                                                      \
00329     /* In the other cases, we keep the default value. */          \
00330     }
00331 
00332 /*
00333  *  This function initializes shared variables of the fsal.
00334  */
00335 fsal_status_t fsal_internal_init_global(fsal_init_info_t * fsal_info,
00336                                         fs_common_initinfo_t * fs_common_info)
00337 {
00338 
00339   /* sanity check */
00340   if(!fsal_info || !fs_common_info)
00341     ReturnCode(ERR_FSAL_FAULT, 0);
00342 
00343 
00344   /* inits FS call semaphore */
00345   if(fsal_info->max_fs_calls > 0)
00346     {
00347       int rc;
00348 
00349       limit_calls = TRUE;
00350 
00351       rc = semaphore_init(&sem_fs_calls, fsal_info->max_fs_calls);
00352 
00353       if(rc != 0)
00354         ReturnCode(ERR_FSAL_SERVERFAULT, rc);
00355 
00356       LogDebug(COMPONENT_FSAL,
00357                         "FSAL INIT: Max simultaneous calls to filesystem is limited to %u.",
00358                         fsal_info->max_fs_calls);
00359 
00360     }
00361   else
00362     {
00363       LogDebug(COMPONENT_FSAL,
00364                         "FSAL INIT: Max simultaneous calls to filesystem is unlimited.");
00365     }
00366 
00367   /* setting default values. */
00368   global_fs_info = default_hpss_info;
00369 
00370   /* Analyzing fs_common_info struct */
00371 
00372   if((fs_common_info->behaviors.maxfilesize != FSAL_INIT_FS_DEFAULT) ||
00373      (fs_common_info->behaviors.maxlink != FSAL_INIT_FS_DEFAULT) ||
00374      (fs_common_info->behaviors.maxnamelen != FSAL_INIT_FS_DEFAULT) ||
00375      (fs_common_info->behaviors.maxpathlen != FSAL_INIT_FS_DEFAULT) ||
00376      (fs_common_info->behaviors.no_trunc != FSAL_INIT_FS_DEFAULT) ||
00377      (fs_common_info->behaviors.case_insensitive != FSAL_INIT_FS_DEFAULT) ||
00378      (fs_common_info->behaviors.case_preserving != FSAL_INIT_FS_DEFAULT) ||
00379      (fs_common_info->behaviors.named_attr != FSAL_INIT_FS_DEFAULT) ||
00380      (fs_common_info->behaviors.lease_time != FSAL_INIT_FS_DEFAULT) ||
00381      (fs_common_info->behaviors.supported_attrs != FSAL_INIT_FS_DEFAULT) ||
00382      (fs_common_info->behaviors.homogenous != FSAL_INIT_FS_DEFAULT))
00383     ReturnCode(ERR_FSAL_NOTSUPP, 0);
00384 
00385   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, symlink_support);
00386   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, link_support);
00387   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support);
00388   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_owner);
00389   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_async_block);
00390 
00391   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, cansettime);
00392 
00393   SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxread);
00394   SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxwrite);
00395 
00396   SET_BITMAP_PARAM(global_fs_info, fs_common_info, umask);
00397 
00398   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, auth_exportpath_xdev);
00399 
00400   SET_BITMAP_PARAM(global_fs_info, fs_common_info, xattr_access_rights);
00401 
00402   LogDebug(COMPONENT_FSAL, "FileSystem info :");
00403   LogDebug(COMPONENT_FSAL, "  maxfilesize  = %llX    ",
00404            global_fs_info.maxfilesize);
00405   LogDebug(COMPONENT_FSAL, "  maxlink  = %lu   ", global_fs_info.maxlink);
00406   LogDebug(COMPONENT_FSAL, "  maxnamelen  = %lu  ",
00407            global_fs_info.maxnamelen);
00408   LogDebug(COMPONENT_FSAL, "  maxpathlen  = %lu  ",
00409            global_fs_info.maxpathlen);
00410   LogDebug(COMPONENT_FSAL, "  no_trunc  = %d ", global_fs_info.no_trunc);
00411   LogDebug(COMPONENT_FSAL, "  chown_restricted  = %d ",
00412            global_fs_info.chown_restricted);
00413   LogDebug(COMPONENT_FSAL, "  case_insensitive  = %d ",
00414            global_fs_info.case_insensitive);
00415   LogDebug(COMPONENT_FSAL, "  case_preserving  = %d ",
00416            global_fs_info.case_preserving);
00417   LogDebug(COMPONENT_FSAL, "  fh_expire_type  = %hu ",
00418            global_fs_info.fh_expire_type);
00419   LogDebug(COMPONENT_FSAL, "  link_support  = %d  ",
00420            global_fs_info.link_support);
00421   LogDebug(COMPONENT_FSAL, "  symlink_support  = %d  ",
00422            global_fs_info.symlink_support);
00423   LogDebug(COMPONENT_FSAL, "  lock_support  = %d  ",
00424            global_fs_info.lock_support);
00425   LogDebug(COMPONENT_FSAL, "  lock_support_owner  = %d  ",
00426            global_fs_info.lock_support_owner);
00427   LogDebug(COMPONENT_FSAL, "  lock_support_async_block  = %d  ",
00428            global_fs_info.lock_support_async_block);
00429   LogDebug(COMPONENT_FSAL, "  named_attr  = %d  ",
00430            global_fs_info.named_attr);
00431   LogDebug(COMPONENT_FSAL, "  unique_handles  = %d  ",
00432            global_fs_info.unique_handles);
00433   LogDebug(COMPONENT_FSAL, "  lease_time  = %u.%u     ",
00434            global_fs_info.lease_time.seconds,
00435            global_fs_info.lease_time.nseconds);
00436   LogDebug(COMPONENT_FSAL, "  acl_support  = %hu  ",
00437            global_fs_info.acl_support);
00438   LogDebug(COMPONENT_FSAL, "  cansettime  = %d  ",
00439            global_fs_info.cansettime);
00440   LogDebug(COMPONENT_FSAL, "  homogenous  = %d  ",
00441            global_fs_info.homogenous);
00442   LogDebug(COMPONENT_FSAL, "  supported_attrs  = %llX  ",
00443            global_fs_info.supported_attrs);
00444   LogDebug(COMPONENT_FSAL, "  maxread  = %llX     ",
00445            global_fs_info.maxread);
00446   LogDebug(COMPONENT_FSAL, "  maxwrite  = %llX     ",
00447            global_fs_info.maxwrite);
00448   LogDebug(COMPONENT_FSAL, "  umask  = %#o ", global_fs_info.umask);
00449   LogDebug(COMPONENT_FSAL, "  auth_exportpath_xdev  = %d  ",
00450            global_fs_info.auth_exportpath_xdev);
00451   LogDebug(COMPONENT_FSAL, "  xattr_access_rights = %#o ",
00452            global_fs_info.xattr_access_rights);
00453 
00454   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00455 }
00456 
00470 fsal_boolean_t fsal_do_log(fsal_status_t status)
00471 {
00472 
00473   switch (status.major)
00474     {
00475 
00476       /* here are the code, we want to trace */
00477     case ERR_FSAL_DELAY:
00478     case ERR_FSAL_PERM:
00479     case ERR_FSAL_IO:
00480     case ERR_FSAL_NXIO:
00481     case ERR_FSAL_NOT_OPENED:
00482     case ERR_FSAL_NOMEM:
00483     case ERR_FSAL_FAULT:
00484     case ERR_FSAL_XDEV:
00485     case ERR_FSAL_INVAL:
00486     case ERR_FSAL_FBIG:
00487     case ERR_FSAL_NOSPC:
00488     case ERR_FSAL_MLINK:
00489     case ERR_FSAL_NAMETOOLONG:
00490     case ERR_FSAL_SEC:
00491     case ERR_FSAL_SERVERFAULT:
00492       return TRUE;
00493 
00494     default:
00495       return FALSE;
00496     }
00497 
00498 }