nfs-ganesha 1.4

fsal_internal.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2010 The Linx Box Corporation
00003  * Contributor : Adam C. Emerson
00004  *
00005  * Some Portions Copyright CEA/DAM/DIF  (2008)
00006  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00007  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00008  *
00009  *
00010  * This program is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 3 of the License, or (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023  *
00024  * ---------------------------------------
00025  */
00026 
00034 #define FSAL_INTERNAL_C
00035 #ifdef HAVE_CONFIG_H
00036 #include "config.h"
00037 #endif
00038 
00039 #include  "fsal.h"
00040 #include "fsal_internal.h"
00041 #include "SemN.h"
00042 #include "nfs4.h"
00043 #include "HashTable.h"
00044 #include "abstract_mem.h"
00045 
00046 #include <pthread.h>
00047 
00048 /* static filesystem info.
00049  * The access is thread-safe because
00050  * it is read-only, except during initialization.
00051  */
00052 fsal_staticfsinfo_t global_fs_info;
00053 cephfs_specific_initinfo_t global_spec_info;
00054 
00055 #define SUPPORTED_ATTRIBUTES (                                       \
00056           FSAL_ATTR_SUPPATTR | FSAL_ATTR_TYPE     | FSAL_ATTR_SIZE      | \
00057           FSAL_ATTR_FSID     | FSAL_ATTR_FILEID   | \
00058           FSAL_ATTR_MODE     | FSAL_ATTR_NUMLINKS | FSAL_ATTR_OWNER     | \
00059           FSAL_ATTR_GROUP    | FSAL_ATTR_ATIME    | FSAL_ATTR_RAWDEV    | \
00060           FSAL_ATTR_CTIME    | FSAL_ATTR_MTIME    | FSAL_ATTR_SPACEUSED | \
00061           FSAL_ATTR_CHGTIME  )
00062 
00063 #ifdef _PNFS_MDS
00064 static layouttype4 layout_type_list[] = {LAYOUT4_NFSV4_1_FILES};
00065 #endif /* _PNFS_MDS */
00066 
00067 /* filesystem info for your filesystem */
00068 static fsal_staticfsinfo_t default_ceph_info = {
00069   .maxfilesize = UINT64_MAX,
00070   .maxlink = 1024,
00071   .maxnamelen = FSAL_MAX_NAME_LEN,
00072   .maxpathlen = FSAL_MAX_PATH_LEN,
00073   .no_trunc = TRUE,
00074   .chown_restricted = TRUE,
00075   .case_insensitive = FALSE,
00076   .case_preserving = TRUE,
00077   .fh_expire_type = FSAL_EXPTYPE_PERSISTENT,
00078   .link_support = TRUE,
00079   .symlink_support = TRUE,
00080   .lock_support = FALSE,
00081   .lock_support_owner = FALSE,
00082   .lock_support_async_block = FALSE,
00083   .named_attr = TRUE,
00084   .unique_handles = TRUE,
00085   .lease_time = {10, 0},
00086   .acl_support = FSAL_ACLSUPPORT_DENY,
00087   .cansettime = TRUE,
00088   .homogenous = TRUE,
00089   .supported_attrs = SUPPORTED_ATTRIBUTES,
00090   .maxread = 0x400000,
00091   .maxwrite = 0x400000,
00092   .umask = 0,
00093   .auth_exportpath_xdev = 0,
00094   .xattr_access_rights = 0400,
00095   .accesscheck_support = 0,
00096   .share_support = 0,
00097   .share_support_owner = 0,
00098 #ifdef _PNFS_MDS
00099   .pnfs_supported = TRUE,
00100   .layout_blksize = 0x400000,
00101   .max_segment_count = 1,
00102   .loc_buffer_size = 256,
00103   .dsaddr_buffer_size = 5120
00104 #endif /* _PNFS_MDS */
00105 };
00106 
00107 /* variables for limiting the calls to the filesystem */
00108 static int limit_calls = FALSE;
00109 semaphore_t sem_fs_calls;
00110 
00111 /* threads keys for stats */
00112 static pthread_key_t key_stats;
00113 static pthread_once_t once_key = PTHREAD_ONCE_INIT;
00114 
00115 /* init keys */
00116 static void init_keys(void)
00117 {
00118   if(pthread_key_create(&key_stats, NULL) == -1)
00119     LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_KEY_CREATE, errno);
00120 
00121   return;
00122 }                               /* init_keys */
00123 
00135 void fsal_increment_nbcall(int function_index, fsal_status_t status)
00136 {
00137   fsal_statistics_t *bythread_stat = NULL;
00138 
00139   /* verify index */
00140 
00141   if(function_index >= FSAL_NB_FUNC)
00142     return;
00143 
00144   /* first, we init the keys if this is the first time */
00145 
00146   if(pthread_once(&once_key, init_keys) != 0)
00147     {
00148       LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno);
00149       return;
00150     }
00151 
00152   /* we get the specific value */
00153 
00154   bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats);
00155 
00156   /* we allocate stats if this is the first time */
00157 
00158   if(bythread_stat == NULL)
00159     {
00160       int i;
00161 
00162       bythread_stat = gsh_malloc(sizeof(fsal_statistics_t));
00163 
00164       if(bythread_stat == NULL)
00165         {
00166           LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM);
00167         }
00168 
00169       /* inits the struct */
00170 
00171       for(i = 0; i < FSAL_NB_FUNC; i++)
00172         {
00173           bythread_stat->func_stats.nb_call[i] = 0;
00174           bythread_stat->func_stats.nb_success[i] = 0;
00175           bythread_stat->func_stats.nb_err_retryable[i] = 0;
00176           bythread_stat->func_stats.nb_err_unrecover[i] = 0;
00177         }
00178 
00179       /* set the specific value */
00180       pthread_setspecific(key_stats, (void *)bythread_stat);
00181 
00182     }
00183 
00184   /* we increment the values */
00185 
00186   if(bythread_stat)
00187     {
00188       bythread_stat->func_stats.nb_call[function_index]++;
00189 
00190       if(!FSAL_IS_ERROR(status))
00191         bythread_stat->func_stats.nb_success[function_index]++;
00192       else if(status.major == ERR_FSAL_DELAY)   /* Error is retryable */
00193         bythread_stat->func_stats.nb_err_retryable[function_index]++;
00194       else
00195         bythread_stat->func_stats.nb_err_unrecover[function_index]++;
00196     }
00197 
00198   return;
00199 }
00200 
00211 void fsal_internal_getstats(fsal_statistics_t * output_stats)
00212 {
00213 
00214   fsal_statistics_t *bythread_stat = NULL;
00215 
00216   /* first, we init the keys if this is the first time */
00217   if(pthread_once(&once_key, init_keys) != 0)
00218     {
00219       LogError(COMPONENT_FSAL, ERR_SYS, ERR_PTHREAD_ONCE, errno);
00220       return;
00221     }
00222 
00223   /* we get the specific value */
00224   bythread_stat = (fsal_statistics_t *) pthread_getspecific(key_stats);
00225 
00226   /* we allocate stats if this is the first time */
00227   if(bythread_stat == NULL)
00228     {
00229       int i;
00230 
00231       if((bythread_stat =
00232           gsh_alloc(sizeof(fsal_statistics_t))) == NULL)
00233         LogError(COMPONENT_FSAL, ERR_SYS, ERR_MALLOC, ENOMEM);
00234 
00235       /* inits the struct */
00236       for(i = 0; i < FSAL_NB_FUNC; i++)
00237         {
00238           bythread_stat->func_stats.nb_call[i] = 0;
00239           bythread_stat->func_stats.nb_success[i] = 0;
00240           bythread_stat->func_stats.nb_err_retryable[i] = 0;
00241           bythread_stat->func_stats.nb_err_unrecover[i] = 0;
00242         }
00243 
00244       /* set the specific value */
00245       pthread_setspecific(key_stats, (void *)bythread_stat);
00246 
00247     }
00248 
00249   if(output_stats)
00250     (*output_stats) = (*bythread_stat);
00251 
00252   return;
00253 }
00254 
00258 void TakeTokenFSCall()
00259 {
00260   /* no limits */
00261   if(limit_calls == FALSE)
00262     return;
00263 
00264   /* there is a limit */
00265   semaphore_P(&sem_fs_calls);
00266 
00267 }
00268 
00269 void ReleaseTokenFSCall()
00270 {
00271   /* no limits */
00272   if(limit_calls == FALSE)
00273     return;
00274 
00275   /* there is a limit */
00276   semaphore_V(&sem_fs_calls);
00277 
00278 }
00279 
00280 #define SET_INTEGER_PARAM( cfg, p_init_info, _field )         \
00281     switch( (p_init_info)->behaviors._field ){                    \
00282     case FSAL_INIT_FORCE_VALUE :                                  \
00283       /* force the value in any case */                           \
00284       cfg._field = (p_init_info)->values._field;                  \
00285       break;                                                      \
00286     case FSAL_INIT_MAX_LIMIT :                                    \
00287       /* check the higher limit */                                \
00288       if ( cfg._field > (p_init_info)->values._field )            \
00289         cfg._field = (p_init_info)->values._field ;               \
00290       break;                                                      \
00291     case FSAL_INIT_MIN_LIMIT :                                    \
00292       /* check the lower limit */                                 \
00293       if ( cfg._field < (p_init_info)->values._field )            \
00294         cfg._field = (p_init_info)->values._field ;               \
00295       break;                                                      \
00296     case FSAL_INIT_FS_DEFAULT:                                    \
00297     default:                                                      \
00298     /* In the other cases, we keep the default value. */          \
00299         break;                                                    \
00300     }
00301 
00302 #define SET_BITMAP_PARAM( cfg, p_init_info, _field )          \
00303     switch( (p_init_info)->behaviors._field ){                    \
00304     case FSAL_INIT_FORCE_VALUE :                                  \
00305         /* force the value in any case */                         \
00306         cfg._field = (p_init_info)->values._field;                \
00307         break;                                                    \
00308     case FSAL_INIT_MAX_LIMIT :                                    \
00309       /* proceed a bit AND */                                     \
00310       cfg._field &= (p_init_info)->values._field ;                \
00311       break;                                                      \
00312     case FSAL_INIT_MIN_LIMIT :                                    \
00313       /* proceed a bit OR */                                      \
00314       cfg._field |= (p_init_info)->values._field ;                \
00315       break;                                                      \
00316     case FSAL_INIT_FS_DEFAULT:                                    \
00317     default:                                                      \
00318     /* In the other cases, we keep the default value. */          \
00319         break;                                                    \
00320     }
00321 
00322 #define SET_BOOLEAN_PARAM( cfg, p_init_info, _field )         \
00323     switch( (p_init_info)->behaviors._field ){                    \
00324     case FSAL_INIT_FORCE_VALUE :                                  \
00325         /* force the value in any case */                         \
00326         cfg._field = (p_init_info)->values._field;                \
00327         break;                                                    \
00328     case FSAL_INIT_MAX_LIMIT :                                    \
00329       /* proceed a boolean AND */                                 \
00330       cfg._field = cfg._field && (p_init_info)->values._field ;   \
00331       break;                                                      \
00332     case FSAL_INIT_MIN_LIMIT :                                    \
00333       /* proceed a boolean OR */                                  \
00334       cfg._field = cfg._field && (p_init_info)->values._field ;   \
00335       break;                                                      \
00336     case FSAL_INIT_FS_DEFAULT:                                    \
00337     default:                                                      \
00338     /* In the other cases, we keep the default value. */          \
00339         break;                                                    \
00340     }
00341 
00342 /*
00343    Check the access from an existing fsal_attrib_list_t or struct stat
00344 */
00345 fsal_status_t fsal_internal_testAccess(cephfsal_op_context_t* context,
00346                                        fsal_accessflags_t access_type,
00347                                        struct stat * st,
00348                                        fsal_attrib_list_t * object_attributes)
00349 {
00350   fsal_accessflags_t missing_access;
00351   unsigned int is_grp, i;
00352   fsal_uid_t uid;
00353   fsal_gid_t gid;
00354   fsal_accessmode_t mode;
00355   fsal_uid_t userid = context->credential.user;
00356   fsal_uid_t groupid = context->credential.group;
00357 
00358   /* sanity checks. */
00359 
00360   if((!object_attributes && !st) || !context)
00361     ReturnCode(ERR_FSAL_FAULT, 0);
00362 
00363   /* If the FSAL_F_OK flag is set, returns ERR INVAL */
00364 
00365   if(access_type & FSAL_F_OK)
00366     ReturnCode(ERR_FSAL_INVAL, 0);
00367 
00368   /* test root access */
00369 
00370   if(userid == 0)
00371     ReturnCode(ERR_FSAL_NO_ERROR, 0);
00372 
00373   /* unsatisfied flags */
00374 
00375   missing_access = FSAL_MODE_MASK(access_type); /* only modes, no ACLs here */
00376 
00377   if(object_attributes)
00378     {
00379       uid = object_attributes->owner;
00380       gid = object_attributes->group;
00381       mode = object_attributes->mode;
00382     }
00383   else
00384     {
00385       uid = st->st_uid;
00386       gid = st->st_gid;
00387       mode = unix2fsal_mode(st->st_mode);
00388     }
00389 
00390   /* Test if file belongs to user. */
00391 
00392   if(userid == uid)
00393     {
00394 
00395       LogFullDebug(COMPONENT_FSAL, "File belongs to user %d", uid);
00396 
00397       if(mode & FSAL_MODE_RUSR)
00398         missing_access &= ~FSAL_R_OK;
00399 
00400       if(mode & FSAL_MODE_WUSR)
00401         missing_access &= ~FSAL_W_OK;
00402 
00403       if(mode & FSAL_MODE_XUSR)
00404         missing_access &= ~FSAL_X_OK;
00405 
00406       if((missing_access & FSAL_OWNER_OK) != 0)
00407         missing_access = 0;
00408 
00409       if(missing_access == 0)
00410         ReturnCode(ERR_FSAL_NO_ERROR, 0);
00411       else
00412         {
00413           LogFullDebug(COMPONENT_FSAL,
00414                             "Mode=%#o, Access=%#o, Rights missing: %#o", mode,
00415                             access_type, missing_access);
00416           ReturnCode(ERR_FSAL_ACCESS, 0);
00417         }
00418 
00419     }
00420 
00421   /* Test if the file belongs to user's group. */
00422 
00423   is_grp = (groupid == gid);
00424 
00425   if(is_grp)
00426     LogFullDebug(COMPONENT_FSAL, "File belongs to user's group %d",
00427                       groupid);
00428 
00429 
00430   /* Test if file belongs to alt user's groups */
00431 
00432   if(!is_grp)
00433     {
00434       for(i = 0; i < context->credential.nbgroups; i++)
00435         {
00436           is_grp = context->credential.alt_groups[i] == gid;
00437 
00438           if(is_grp)
00439             LogFullDebug(COMPONENT_FSAL,
00440                          "File belongs to user's alt group %d",
00441                          context->credential.alt_groups[i]);
00442 
00443           // exits loop if found
00444           if(is_grp)
00445             break;
00446         }
00447     }
00448 
00449   /* finally apply group rights */
00450 
00451   if(is_grp)
00452     {
00453       if(mode & FSAL_MODE_RGRP)
00454         missing_access &= ~FSAL_R_OK;
00455 
00456       if(mode & FSAL_MODE_WGRP)
00457         missing_access &= ~FSAL_W_OK;
00458 
00459       if(mode & FSAL_MODE_XGRP)
00460         missing_access &= ~FSAL_X_OK;
00461 
00462       if(missing_access == 0)
00463         ReturnCode(ERR_FSAL_NO_ERROR, 0);
00464       else
00465         ReturnCode(ERR_FSAL_ACCESS, 0);
00466 
00467     }
00468 
00469   /* test other perms */
00470 
00471   if(mode & FSAL_MODE_ROTH)
00472     missing_access &= ~FSAL_R_OK;
00473 
00474   if(mode & FSAL_MODE_WOTH)
00475     missing_access &= ~FSAL_W_OK;
00476 
00477   if(mode & FSAL_MODE_XOTH)
00478     missing_access &= ~FSAL_X_OK;
00479 
00480   if(missing_access == 0)
00481     ReturnCode(ERR_FSAL_NO_ERROR, 0);
00482   else
00483     ReturnCode(ERR_FSAL_ACCESS, 0);
00484 
00485 }
00486 
00487 /*
00488  *  This function initializes shared variables of the fsal.
00489  */
00490 fsal_status_t fsal_internal_init_global(fsal_init_info_t * fsal_info,
00491                                         fs_common_initinfo_t * fs_common_info,
00492                                         fs_specific_initinfo_t * fs_specific_info)
00493 {
00494   /* sanity check */
00495   if(!fsal_info || !fs_common_info || !fs_specific_info)
00496     ReturnCode(ERR_FSAL_FAULT, 0);
00497 
00498   /* inits FS call semaphore */
00499   if(fsal_info->max_fs_calls > 0)
00500     {
00501       int rc;
00502 
00503       limit_calls = TRUE;
00504 
00505       rc = semaphore_init(&sem_fs_calls, fsal_info->max_fs_calls);
00506 
00507       if(rc != 0)
00508         ReturnCode(ERR_FSAL_SERVERFAULT, rc);
00509 
00510       LogDebug(COMPONENT_FSAL,
00511                         "FSAL INIT: Max simultaneous calls to filesystem is limited to %u.",
00512                         fsal_info->max_fs_calls);
00513 
00514     }
00515   else
00516     {
00517       LogDebug(COMPONENT_FSAL,
00518                         "FSAL INIT: Max simultaneous calls to filesystem is unlimited.");
00519     }
00520 
00521 #ifdef _PNFS_MDS
00522   default_ceph_info.fs_layout_types.fattr4_fs_layout_types_val
00523     = layout_type_list;
00524   default_ceph_info.fs_layout_types.fattr4_fs_layout_types_len
00525     = 1;
00526 #endif /* _PNFS_MDS */
00527 
00528   /* setting default values. */
00529   global_fs_info = default_ceph_info;
00530 
00531   LogDebug(COMPONENT_FSAL, "{");
00532   LogDebug(COMPONENT_FSAL, "  maxfilesize  = %llX    ",
00533            default_ceph_info.maxfilesize);
00534   LogDebug(COMPONENT_FSAL, "  maxlink  = %lu   ",
00535            default_ceph_info.maxlink);
00536   LogDebug(COMPONENT_FSAL, "  maxnamelen  = %lu  ",
00537            default_ceph_info.maxnamelen);
00538   LogDebug(COMPONENT_FSAL, "  maxpathlen  = %lu  ",
00539            default_ceph_info.maxpathlen);
00540   LogDebug(COMPONENT_FSAL, "  no_trunc  = %d ",
00541            default_ceph_info.no_trunc);
00542   LogDebug(COMPONENT_FSAL, "  chown_restricted  = %d ",
00543            default_ceph_info.chown_restricted);
00544   LogDebug(COMPONENT_FSAL, "  case_insensitive  = %d ",
00545            default_ceph_info.case_insensitive);
00546   LogDebug(COMPONENT_FSAL, "  case_preserving  = %d ",
00547            default_ceph_info.case_preserving);
00548   LogDebug(COMPONENT_FSAL, "  fh_expire_type  = %hu ",
00549            default_ceph_info.fh_expire_type);
00550   LogDebug(COMPONENT_FSAL, "  link_support  = %d  ",
00551            default_ceph_info.link_support);
00552   LogDebug(COMPONENT_FSAL, "  symlink_support  = %d  ",
00553            default_ceph_info.symlink_support);
00554   LogDebug(COMPONENT_FSAL, "  lock_support  = %d  ",
00555            default_ceph_info.lock_support);
00556   LogDebug(COMPONENT_FSAL, "  lock_support_owner  = %d  ",
00557            global_fs_info.lock_support_owner);
00558   LogDebug(COMPONENT_FSAL, "  lock_support_async_block  = %d  ",
00559            global_fs_info.lock_support_async_block);
00560   LogDebug(COMPONENT_FSAL, "  named_attr  = %d  ",
00561            default_ceph_info.named_attr);
00562   LogDebug(COMPONENT_FSAL, "  unique_handles  = %d  ",
00563            default_ceph_info.unique_handles);
00564   LogDebug(COMPONENT_FSAL, "  acl_support  = %hu  ",
00565            default_ceph_info.acl_support);
00566   LogDebug(COMPONENT_FSAL, "  cansettime  = %d  ",
00567            default_ceph_info.cansettime);
00568   LogDebug(COMPONENT_FSAL, "  homogenous  = %d  ",
00569            default_ceph_info.homogenous);
00570   LogDebug(COMPONENT_FSAL, "  supported_attrs  = %llX  ",
00571            default_ceph_info.supported_attrs);
00572   LogDebug(COMPONENT_FSAL, "  maxread  = %llX     ",
00573            default_ceph_info.maxread);
00574   LogDebug(COMPONENT_FSAL, "  maxwrite  = %llX     ",
00575            default_ceph_info.maxwrite);
00576   LogDebug(COMPONENT_FSAL, "  umask  = %X ", default_ceph_info.umask);
00577   LogDebug(COMPONENT_FSAL, "}");
00578 
00579   /* Analyzing fs_common_info struct */
00580 
00581 #ifdef _PNFS_MDS
00582   if((fs_common_info->behaviors.maxfilesize != FSAL_INIT_FS_DEFAULT) ||
00583      (fs_common_info->behaviors.maxlink != FSAL_INIT_FS_DEFAULT) ||
00584      (fs_common_info->behaviors.maxnamelen != FSAL_INIT_FS_DEFAULT) ||
00585      (fs_common_info->behaviors.maxpathlen != FSAL_INIT_FS_DEFAULT) ||
00586      (fs_common_info->behaviors.no_trunc != FSAL_INIT_FS_DEFAULT) ||
00587      (fs_common_info->behaviors.case_insensitive != FSAL_INIT_FS_DEFAULT) ||
00588      (fs_common_info->behaviors.case_preserving != FSAL_INIT_FS_DEFAULT) ||
00589      (fs_common_info->behaviors.named_attr != FSAL_INIT_FS_DEFAULT) ||
00590      (fs_common_info->behaviors.lease_time != FSAL_INIT_FS_DEFAULT) ||
00591      (fs_common_info->behaviors.supported_attrs != FSAL_INIT_FS_DEFAULT) ||
00592      (fs_common_info->behaviors.homogenous != FSAL_INIT_FS_DEFAULT) ||
00593      (fs_common_info->behaviors.fs_layout_types != FSAL_INIT_FS_DEFAULT) ||
00594      (fs_common_info->behaviors.layout_blksize != FSAL_INIT_FS_DEFAULT))
00595 #else /* !_PNFS_MDS */
00596   if((fs_common_info->behaviors.maxfilesize != FSAL_INIT_FS_DEFAULT) ||
00597      (fs_common_info->behaviors.maxlink != FSAL_INIT_FS_DEFAULT) ||
00598      (fs_common_info->behaviors.maxnamelen != FSAL_INIT_FS_DEFAULT) ||
00599      (fs_common_info->behaviors.maxpathlen != FSAL_INIT_FS_DEFAULT) ||
00600      (fs_common_info->behaviors.no_trunc != FSAL_INIT_FS_DEFAULT) ||
00601      (fs_common_info->behaviors.case_insensitive != FSAL_INIT_FS_DEFAULT) ||
00602      (fs_common_info->behaviors.case_preserving != FSAL_INIT_FS_DEFAULT) ||
00603      (fs_common_info->behaviors.named_attr != FSAL_INIT_FS_DEFAULT) ||
00604      (fs_common_info->behaviors.lease_time != FSAL_INIT_FS_DEFAULT) ||
00605      (fs_common_info->behaviors.supported_attrs != FSAL_INIT_FS_DEFAULT) ||
00606      (fs_common_info->behaviors.homogenous != FSAL_INIT_FS_DEFAULT))
00607 #endif /* !_PNFS_MDS */
00608     {
00609       ReturnCode(ERR_FSAL_NOTSUPP, 0);
00610     }
00611 
00612   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, symlink_support);
00613   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, link_support);
00614   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support);
00615   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_owner);
00616   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, lock_support_async_block);
00617   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, cansettime);
00618 #ifdef _PNFS_MDS
00619   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, pnfs_supported);
00620 #endif /* _PNFS_MDS */
00621 
00622   SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxread);
00623   SET_INTEGER_PARAM(global_fs_info, fs_common_info, maxwrite);
00624 
00625   SET_BITMAP_PARAM(global_fs_info, fs_common_info, umask);
00626 
00627   SET_BOOLEAN_PARAM(global_fs_info, fs_common_info, auth_exportpath_xdev);
00628 
00629   SET_BITMAP_PARAM(global_fs_info, fs_common_info, xattr_access_rights);
00630 
00631   LogFullDebug(COMPONENT_FSAL,
00632                "Supported attributes constant = 0x%llX.",
00633                SUPPORTED_ATTRIBUTES);
00634 
00635   LogFullDebug(COMPONENT_FSAL,
00636                "Supported attributes default = 0x%llX.",
00637                default_ceph_info.supported_attrs);
00638 
00639   LogDebug(COMPONENT_FSAL,
00640                     "FSAL INIT: Supported attributes mask = 0x%llX.",
00641                     global_fs_info.supported_attrs);
00642 
00643   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00644 }