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