nfs-ganesha 1.4

fsal_tools.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016 
00017 #include "fsal.h"
00018 #include "fsal_internal.h"
00019 #include "fsal_common.h"
00020 #include "fsal_convert.h"
00021 #include "config_parsing.h"
00022 #include "fsal_common.h"
00023 #include <string.h>
00024 
00025 /* case unsensitivity */
00026 #define STRCMP   strcasecmp
00027 
00028 char *FUSEFSAL_GetFSName()
00029 {
00030   return "FUSE";
00031 }
00032 
00049 int FUSEFSAL_handlecmp(fsal_handle_t * handle_1, fsal_handle_t * handle_2,
00050                        fsal_status_t * status)
00051 {
00052   fusefsal_handle_t * handle1 = (fusefsal_handle_t *)handle_1;
00053   fusefsal_handle_t * handle2 = (fusefsal_handle_t *)handle_2;
00054 
00055   *status = FSAL_STATUS_NO_ERROR;
00056 
00057   if(!handle1 || !handle2)
00058     {
00059       status->major = ERR_FSAL_FAULT;
00060       return -1;
00061     }
00062 
00063   if((handle1->data.inode > handle2->data.inode) || (handle1->data.device > handle2->data.device))
00064     return 1;
00065   else if((handle1->data.inode < handle2->data.inode) || (handle1->data.device < handle2->data.device))
00066     return -1;
00067   else
00068     return 0;
00069 
00070 }
00071 
00086 unsigned int FUSEFSAL_Handle_to_HashIndex(fsal_handle_t *handle,
00087                                           unsigned int cookie,
00088                                           unsigned int alphabet_len,
00089                                           unsigned int index_size)
00090 {
00091   fusefsal_handle_t * p_handle = (fusefsal_handle_t *)handle;
00092 
00093   /* >> here must be your implementation of your fusefsal_handle_t hashing */
00094   return (3 * (unsigned int)p_handle->data.inode + 5 * (unsigned int)p_handle->data.device + 1999 +
00095           cookie) % index_size;
00096 
00097 }
00098 
00099 /*
00100  * FSAL_Handle_to_RBTIndex
00101  * This function is used for generating a RBT node ID
00102  * in order to identify entries into the RBT.
00103  *
00104  * \param p_handle      The handle to be hashed
00105  * \param cookie        Makes it possible to have different hash value for the
00106  *                      same handle, when cookie changes.
00107  *
00108  * \return The hash value
00109  */
00110 
00111 unsigned int FUSEFSAL_Handle_to_RBTIndex(fsal_handle_t *handle,
00112                                          unsigned int cookie)
00113 {
00114   fusefsal_handle_t * p_handle = (fusefsal_handle_t *)handle;
00115 
00116   /* >> here must be your implementation of your fusefsal_handle_t hashing << */
00117   return (unsigned int)(0xABCD1234 ^ p_handle->data.inode ^ cookie ^ p_handle->data.device);
00118 
00119 }
00120 
00137 fsal_status_t FUSEFSAL_DigestHandle(fsal_export_context_t * exp_context,     /* IN */
00138                                       fsal_digesttype_t output_type,       /* IN */
00139                                       fsal_handle_t *in_fsal_handle, /* IN */
00140                                       struct fsal_handle_desc *fh_desc     /* IN/OUT */ )
00141 {
00142   fusefsal_export_context_t * p_expcontext = (fusefsal_export_context_t *)exp_context;
00143   fusefsal_handle_t * p_in_fsal_handle = (fusefsal_handle_t *)in_fsal_handle;
00144   size_t fh_size;
00145 
00146   /* sanity checks */
00147   if(!p_in_fsal_handle || !fh_desc || !fh_desc->start || !p_expcontext)
00148     ReturnCode(ERR_FSAL_FAULT, 0);
00149 
00150 
00151   switch (output_type)
00152     {
00153     /* NFS handle digest */
00154     case FSAL_DIGEST_NFSV2:
00155     case FSAL_DIGEST_NFSV3:
00156     case FSAL_DIGEST_NFSV4:
00157       fh_size = sizeof(p_in_fsal_handle->data) ;
00158       if(fh_desc->len < fh_size)
00159         {
00160                LogMajor( COMPONENT_FSAL,
00161                              "FUSE DigestHandle: space too small for handle.  need %lu, have %lu",
00162                              fh_size, fh_desc->len);
00163                ReturnCode(ERR_FSAL_TOOSMALL, 0);
00164             }
00165       memcpy(fh_desc->start, (caddr_t)p_in_fsal_handle, fh_size);
00166       fh_desc->len = fh_size;
00167       break;
00168 
00169       /* FileId digest for NFSv2 */
00170     case FSAL_DIGEST_FILEID2:
00171       {
00172         int cast2 = (int)in_fsal_handle->data.inode;
00173 
00174 #ifndef _NO_CHECKS
00175 
00176         /* sanity check about output size */
00177 
00178         if(sizeof(cast2) > FSAL_DIGEST_SIZE_FILEID2)
00179           ReturnCode(ERR_FSAL_TOOSMALL, 0);
00180 
00181 #endif
00182         memset(fh_desc->start, 0, FSAL_DIGEST_SIZE_FILEID2);
00183         memcpy(fh_desc->start, &cast2, sizeof( cast2 ));
00184         fh_desc->len = FSAL_DIGEST_SIZE_FILEID2; 
00185       }
00186       break;
00187 
00188       /* FileId digest for NFSv3 */
00189     case FSAL_DIGEST_FILEID3:
00190       {
00191         fsal_u64_t cast3 = (fsal_u64_t) in_fsal_handle->data.inode;
00192 
00193 #ifndef _NO_CHECKS
00194 
00195         /* sanity check about output size */
00196 
00197         if(sizeof(cast3) > FSAL_DIGEST_SIZE_FILEID3)
00198           ReturnCode(ERR_FSAL_TOOSMALL, 0);
00199 
00200 #endif
00201 
00202         memset(fh_desc->start, 0, FSAL_DIGEST_SIZE_FILEID3);
00203         memcpy(fh_desc->start, &cast3, sizeof( cast3 ));
00204         fh_desc->len = FSAL_DIGEST_SIZE_FILEID3; 
00205       }
00206       break;
00207 
00208       /* FileId digest for NFSv4 */
00209 
00210     case FSAL_DIGEST_FILEID4:
00211       {
00212         fsal_u64_t cast4 = (fsal_u64_t) in_fsal_handle->data.inode;
00213 
00214 #ifndef _NO_CHECKS
00215 
00216         /* sanity check about output size */
00217 
00218         if(sizeof(cast4) > FSAL_DIGEST_SIZE_FILEID4)
00219           ReturnCode(ERR_FSAL_TOOSMALL, 0);
00220 
00221 #endif
00222 
00223         memset(fh_desc->start, 0, FSAL_DIGEST_SIZE_FILEID4);
00224         memcpy(fh_desc->start, &cast4, sizeof( cast4 ));
00225         fh_desc->len = FSAL_DIGEST_SIZE_FILEID4; 
00226       }
00227       break;
00228 
00229     default:
00230       ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00231     }
00232 
00233   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00234 
00235 }                               /* FSAL_DigestHandle */
00236 
00252 fsal_status_t FUSEFSAL_ExpandHandle(fsal_export_context_t * pexpcontext,     /* IN not used */
00253                                    fsal_digesttype_t in_type,   /* IN */
00254                                    struct fsal_handle_desc *fh_desc  /* IN/OUT */ )
00255 {
00256   fusefsal_export_context_t * p_expcontext = (fusefsal_export_context_t *)pexpcontext;
00257   fusefsal_handle_t dummy_handle ;
00258   size_t fh_size;
00259 
00260   /* sanity checks */
00261   if(!fh_desc || !fh_desc->start || !p_expcontext)
00262     ReturnCode(ERR_FSAL_FAULT, 0);
00263 
00264   fh_size = sizeof( dummy_handle.data ); /* All LUSTRE handle have the same size */
00265   if(in_type == FSAL_DIGEST_NFSV2)
00266     {
00267       if(fh_desc->len < fh_size)
00268         {
00269           LogMajor(COMPONENT_FSAL,
00270                    "LUSTRE ExpandHandle: V2 size too small for handle.  should be %lu, got %lu",
00271                    fh_size, fh_desc->len);
00272           ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00273         }
00274     }
00275   else if(in_type != FSAL_DIGEST_SIZEOF && fh_desc->len != fh_size)
00276     {
00277       LogMajor(COMPONENT_FSAL,
00278                "LUSTRE ExpandHandle: size mismatch for handle.  should be %lu, got %lu",
00279                fh_size, fh_desc->len);
00280       ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00281     }
00282   fh_desc->len = fh_size;  /* pass back the actual size */
00283   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00284 }
00285 
00294 fsal_status_t FUSEFSAL_SetDefault_FS_specific_parameter(fsal_parameter_t * out_parameter)
00295 {
00296   /* defensive programming... */
00297   if(out_parameter == NULL)
00298     ReturnCode(ERR_FSAL_FAULT, 0);
00299 
00300   /* >> set your default FS configuration into the
00301      out_parameter->fs_specific_info structure << */
00302 
00303   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00304 
00305 }
00306 
00328 /* load specific filesystem configuration options */
00329 
00330 fsal_status_t FUSEFSAL_load_FS_specific_parameter_from_conf(config_file_t in_config,
00331                                                             fsal_parameter_t *
00332                                                             out_parameter)
00333 {
00334   int err;
00335   int var_max, var_index;
00336   char *key_name;
00337   char *key_value;
00338   config_item_t block;
00339 
00340   block = config_FindItemByName(in_config, CONF_LABEL_FS_SPECIFIC);
00341 
00342   /* cannot read item */
00343   if(block == NULL)
00344     {
00345       LogCrit(COMPONENT_CONFIG, "FSAL LOAD PARAMETER: Cannot read item \"%s\" from configuration file",
00346               CONF_LABEL_FS_SPECIFIC);
00347       ReturnCode(ERR_FSAL_NOENT, 0);
00348     }
00349   else if(config_ItemType(block) != CONFIG_ITEM_BLOCK)
00350     {
00351       LogCrit(COMPONENT_CONFIG, "FSAL LOAD PARAMETER: Item \"%s\" is expected to be a block",
00352               CONF_LABEL_FS_SPECIFIC);
00353       ReturnCode(ERR_FSAL_INVAL, 0);
00354     }
00355 
00356   /* makes an iteration on the (key, value) couplets */
00357 
00358   var_max = config_GetNbItems(block);
00359 
00360   for(var_index = 0; var_index < var_max; var_index++)
00361     {
00362       config_item_t item;
00363 
00364       item = config_GetItemByIndex(block, var_index);
00365 
00366       err = config_GetKeyValue(item, &key_name, &key_value);
00367       if(err)
00368         {
00369           LogCrit(COMPONENT_CONFIG,
00370                   "FSAL LOAD PARAMETER: ERROR reading key[%d] from section \"%s\" of configuration file.",
00371                   var_index, CONF_LABEL_FS_SPECIFIC);
00372           ReturnCode(ERR_FSAL_SERVERFAULT, err);
00373         }
00374 
00375       /* what parameter is it ? */
00376 
00377       if(!STRCMP(key_name, "my_parameter_name1"))
00378         {
00379           /* >> interpret the parameter string and fill the fs_specific_info structure << */
00380         }
00381       else if(!STRCMP(key_name, "my_parameter_name2"))
00382         {
00383           /* >> interpret the parameter string and fill the fs_specific_info structure << */
00384         }
00385       /* etc... */
00386       else
00387         {
00388           LogCrit(COMPONENT_CONFIG,
00389                   "FSAL LOAD PARAMETER: ERROR: Unknown or unsettable key: %s (item %s)",
00390                   key_name, CONF_LABEL_FS_SPECIFIC);
00391           ReturnCode(ERR_FSAL_INVAL, 0);
00392         }
00393 
00394     }
00395 
00396   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00397 
00398 }                               /* FSAL_load_FS_specific_parameter_from_conf */