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 
00017 #ifdef HAVE_CONFIG_H
00018 #include "config.h"
00019 #endif
00020 
00021 #include  "fsal.h"
00022 #include "fsal_internal.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 /* you can define here your supported attributes
00034  * if your filesystem is "homogenous".
00035  */
00036 #define YOUR_SUPPORTED_ATTRIBUTES (                                       \
00037           FSAL_ATTR_SUPPATTR | FSAL_ATTR_TYPE     | FSAL_ATTR_SIZE      | \
00038           FSAL_ATTR_FSID     | FSAL_ATTR_ACL      | FSAL_ATTR_FILEID    | \
00039           FSAL_ATTR_MODE     | FSAL_ATTR_NUMLINKS | FSAL_ATTR_OWNER     | \
00040           FSAL_ATTR_GROUP    | FSAL_ATTR_ATIME    | FSAL_ATTR_CREATION  | \
00041           FSAL_ATTR_CTIME    | FSAL_ATTR_MTIME    | FSAL_ATTR_SPACEUSED | \
00042           FSAL_ATTR_MOUNTFILEID | FSAL_ATTR_CHGTIME  )
00043 
00044 /* filesystem info for your filesystem */
00045 static fsal_staticfsinfo_t default_hpss_info = {
00046   0xFFFFFFFFFFFFFFFFLL,         /* max file size (64bits) */
00047   1024,                         /* max links for an object of your filesystem */
00048   FSAL_MAX_NAME_LEN,            /* max filename */
00049   FSAL_MAX_PATH_LEN,            /* min filename */
00050   TRUE,                         /* no_trunc */
00051   TRUE,                         /* chown restricted */
00052   FALSE,                        /* case insensitivity */
00053   TRUE,                         /* case preserving */
00054   FSAL_EXPTYPE_VOLATILE,        /* FH expire type */
00055   TRUE,                         /* hard link support */
00056   TRUE,                         /* symlink support */
00057   FALSE,                        /* lock support */
00058   FALSE,                        /* lock owners */
00059   FALSE,                        /* async blocking locks */
00060   TRUE,                         /* named attributes */
00061   TRUE,                         /* handles are unique and persistent */
00062   {10, 0},                      /* Duration of lease at FS in seconds */
00063   FSAL_ACLSUPPORT_ALLOW,        /* ACL support */
00064   TRUE,                         /* can change times */
00065   TRUE,                         /* homogenous */
00066   YOUR_SUPPORTED_ATTRIBUTES,    /* supported attributes */
00067   (1024 * 1024),                /* maxread size */
00068   (1024 * 1024),                /* maxwrite size */
00069   0,                            /* default umask */
00070   0,                            /* don't allow cross fileset export path */
00071   0400,                         /* default access rights for xattrs: root=RW, owner=R */
00072   0,                            /* default access check support in FSAL */
00073   0,                            /* default share reservation support in FSAL */
00074   0                             /* default share reservation support with open owners in FSAL */
00075 };
00076 
00077 /* filesystem operations */
00078 struct ganefuse_operations *p_fs_ops = NULL;
00079 
00080 /* filesystem data */
00081 void *fs_user_data = NULL;
00082 void *fs_private_data = NULL;
00083 
00084 /* variables for limiting the calls to the filesystem */
00085 static int limit_calls = FALSE;
00086 semaphore_t sem_fs_calls;
00087 
00088 /* threads keys for stats */
00089 static pthread_key_t key_stats;
00090 static pthread_once_t once_key = PTHREAD_ONCE_INIT;
00091 
00092 /* init keys */
00093 static void init_keys(void)
00094 {
00095   if(pthread_key_create(&key_stats, NULL) == -1)
00096     LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_KEY_CREATE, errno);
00097 
00098   return;
00099 }                               /* init_keys */
00100 
00112 void fsal_increment_nbcall(int function_index, fsal_status_t status)
00113 {
00114 
00115   fsal_statistics_t *bythread_stat = NULL;
00116 
00117   /* verify index */
00118 
00119   if(function_index >= FSAL_NB_FUNC)
00120     return;
00121 
00122   /* first, we init the keys if this is the first time */
00123 
00124   if(pthread_once(&once_key, init_keys) != 0)
00125     {
00126       LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno);
00127       return;
00128     }
00129 
00130   /* we get the specific value */
00131 
00132   bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats);
00133 
00134   /* we allocate stats if this is the first time */
00135 
00136   if(bythread_stat == NULL)
00137     {
00138       int i;
00139 
00140       bythread_stat = gsh_malloc(sizeof(fsal_statistics_t));
00141 
00142       if(bythread_stat == NULL)
00143         {
00144           LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM);
00145         }
00146 
00147       /* inits the struct */
00148 
00149       for(i = 0; i < FSAL_NB_FUNC; i++)
00150         {
00151           bythread_stat->func_stats.nb_call[i] = 0;
00152           bythread_stat->func_stats.nb_success[i] = 0;
00153           bythread_stat->func_stats.nb_err_retryable[i] = 0;
00154           bythread_stat->func_stats.nb_err_unrecover[i] = 0;
00155         }
00156 
00157       /* set the specific value */
00158       pthread_setspecific(key_stats, (void *)bythread_stat);
00159 
00160     }
00161 
00162   /* we increment the values */
00163 
00164   if(bythread_stat)
00165     {
00166       bythread_stat->func_stats.nb_call[function_index]++;
00167 
00168       if(!FSAL_IS_ERROR(status))
00169         bythread_stat->func_stats.nb_success[function_index]++;
00170       else if(status.major == ERR_FSAL_DELAY )
00171         bythread_stat->func_stats.nb_err_retryable[function_index]++;
00172       else
00173         bythread_stat->func_stats.nb_err_unrecover[function_index]++;
00174     }
00175 
00176   return;
00177 }
00178 
00189 void fsal_internal_getstats(fsal_statistics_t * output_stats)
00190 {
00191 
00192   fsal_statistics_t *bythread_stat = NULL;
00193 
00194   /* first, we init the keys if this is the first time */
00195   if(pthread_once(&once_key, init_keys) != 0)
00196     {
00197       LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno);
00198       return;
00199     }
00200 
00201   /* we get the specific value */
00202   bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats);
00203 
00204   /* we allocate stats if this is the first time */
00205   if(bythread_stat == NULL)
00206     {
00207       int i;
00208 
00209       if((bythread_stat =
00210           gsh_malloc(sizeof(fsal_statistics_t))) == NULL)
00211         LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM);
00212 
00213       /* inits the struct */
00214       for(i = 0; i < FSAL_NB_FUNC; i++)
00215         {
00216           bythread_stat->func_stats.nb_call[i] = 0;
00217           bythread_stat->func_stats.nb_success[i] = 0;
00218           bythread_stat->func_stats.nb_err_retryable[i] = 0;
00219           bythread_stat->func_stats.nb_err_unrecover[i] = 0;
00220         }
00221 
00222       /* set the specific value */
00223       pthread_setspecific(key_stats, (void *)bythread_stat);
00224 
00225     }
00226 
00227   if(output_stats)
00228     (*output_stats) = (*bythread_stat);
00229 
00230   return;
00231 
00232 }
00233 
00237 void TakeTokenFSCall()
00238 {
00239   /* no limits */
00240   if(limit_calls == FALSE)
00241     return;
00242 
00243   /* there is a limit */
00244   semaphore_P(&sem_fs_calls);
00245 
00246 }
00247 
00248 void ReleaseTokenFSCall()
00249 {
00250   /* no limits */
00251   if(limit_calls == FALSE)
00252     return;
00253 
00254   /* there is a limit */
00255   semaphore_V(&sem_fs_calls);
00256 
00257 }
00258 
00259 /*
00260  *  This function initializes shared variables of the fsal.
00261  */
00262 fsal_status_t fsal_internal_init_global(fsal_init_info_t * fsal_info,
00263                                         fs_common_initinfo_t * fs_common_info)
00264 {
00265 
00266   /* sanity check */
00267   if(!fsal_info || !fs_common_info)
00268     ReturnCode(ERR_FSAL_FAULT, 0);
00269 
00270   /* inits FS call semaphore */
00271   if(fsal_info->max_fs_calls > 0)
00272     {
00273       int rc;
00274 
00275       limit_calls = TRUE;
00276 
00277       rc = semaphore_init(&sem_fs_calls, fsal_info->max_fs_calls);
00278 
00279       if(rc != 0)
00280         ReturnCode(ERR_FSAL_SERVERFAULT, rc);
00281 
00282       LogDebug(COMPONENT_FSAL,
00283                "FSAL INIT: Max simultaneous calls to filesystem is limited to %u.",
00284                fsal_info->max_fs_calls);
00285 
00286     }
00287   else
00288     {
00289       LogDebug(COMPONENT_FSAL,
00290                "FSAL INIT: Max simultaneous calls to filesystem is unlimited.");
00291     }
00292 
00293   /* setting default values. */
00294   global_fs_info = default_hpss_info;
00295 
00296   /* Analyzing fs_common_info struct */
00297 
00298   if((fs_common_info->behaviors.maxfilesize != FSAL_INIT_FS_DEFAULT) ||
00299      (fs_common_info->behaviors.maxlink != FSAL_INIT_FS_DEFAULT) ||
00300      (fs_common_info->behaviors.maxnamelen != FSAL_INIT_FS_DEFAULT) ||
00301      (fs_common_info->behaviors.maxpathlen != FSAL_INIT_FS_DEFAULT) ||
00302      (fs_common_info->behaviors.no_trunc != FSAL_INIT_FS_DEFAULT) ||
00303      (fs_common_info->behaviors.case_insensitive != FSAL_INIT_FS_DEFAULT) ||
00304      (fs_common_info->behaviors.case_preserving != FSAL_INIT_FS_DEFAULT) ||
00305      (fs_common_info->behaviors.named_attr != FSAL_INIT_FS_DEFAULT) ||
00306      (fs_common_info->behaviors.lease_time != FSAL_INIT_FS_DEFAULT) ||
00307      (fs_common_info->behaviors.supported_attrs != FSAL_INIT_FS_DEFAULT) ||
00308      (fs_common_info->behaviors.homogenous != FSAL_INIT_FS_DEFAULT))
00309     ReturnCode(ERR_FSAL_NOTSUPP, 0);
00310 
00311   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, symlink_support);
00312   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, link_support);
00313   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support);
00314   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_owner);
00315   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_async_block);
00316   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, cansettime);
00317 
00318   SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxread);
00319   SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxwrite);
00320 
00321   SET_BITMAP_PARAM(global_fs_info, fs_common_info, umask);
00322 
00323   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, auth_exportpath_xdev);
00324 
00325   SET_BITMAP_PARAM(global_fs_info, fs_common_info, xattr_access_rights);
00326 
00327   display_fsinfo(&global_fs_info);
00328 
00329   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00330 }
00331 
00345 fsal_boolean_t fsal_do_log(fsal_status_t status)
00346 {
00347 
00348   switch (status.major)
00349     {
00350 
00351       /* here are the code, we want to trace */
00352     case ERR_FSAL_DELAY:
00353     case ERR_FSAL_PERM:
00354     case ERR_FSAL_IO:
00355     case ERR_FSAL_NXIO:
00356     case ERR_FSAL_NOT_OPENED:
00357     case ERR_FSAL_NOMEM:
00358     case ERR_FSAL_FAULT:
00359     case ERR_FSAL_XDEV:
00360     case ERR_FSAL_INVAL:
00361     case ERR_FSAL_FBIG:
00362     case ERR_FSAL_NOSPC:
00363     case ERR_FSAL_MLINK:
00364     case ERR_FSAL_NAMETOOLONG:
00365     case ERR_FSAL_SEC:
00366     case ERR_FSAL_SERVERFAULT:
00367       return TRUE;
00368 
00369     default:
00370       return FALSE;
00371     }
00372 
00373 }
00374 
00375 /* pthread key for fuse context */
00376 static pthread_key_t key_ctx;
00377 static pthread_once_t once_ctx = PTHREAD_ONCE_INIT;
00378 
00379 /* init keys */
00380 static void init_ctx_key(void)
00381 {
00382   if(pthread_key_create(&key_ctx, NULL) == -1)
00383     LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_KEY_CREATE, errno);
00384 
00385   return;
00386 }
00387 
00394 int fsal_set_thread_context(fsal_op_context_t * p_ctx)
00395 {
00396   /* first, we init the key if this is the first time */
00397   if(pthread_once(&once_ctx, init_ctx_key) != 0)
00398     {
00399       int rc = errno;
00400       LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, rc);
00401       return rc;
00402     }
00403 
00404   return pthread_setspecific(key_ctx, (void *)p_ctx);
00405 }
00406 
00410 fsal_op_context_t *fsal_get_thread_context()
00411 {
00412   return pthread_getspecific(key_ctx);
00413 }