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 *ZFSFSAL_GetFSName()
00029 {
00030   return "ZFS";
00031 }
00032 
00049 int ZFSFSAL_handlecmp(fsal_handle_t * handle1, fsal_handle_t * handle2,
00050                    fsal_status_t * status)
00051 {
00052 
00053   *status = FSAL_STATUS_NO_ERROR;
00054 
00055   if(!handle1 || !handle2)
00056     {
00057       status->major = ERR_FSAL_FAULT;
00058       return -1;
00059     }
00060 
00061   return memcmp(handle1, handle2, sizeof(zfsfsal_handle_t));
00062 }
00063 
00078 unsigned int ZFSFSAL_Handle_to_HashIndex(fsal_handle_t * handle,
00079                                       unsigned int cookie,
00080                                       unsigned int alphabet_len, unsigned int index_size)
00081 {
00082   zfsfsal_handle_t * p_handle = (zfsfsal_handle_t *)handle;
00083 
00084   /* >> here must be your implementation of your zfsfsal_handle_t hashing */
00085   return (3 * (unsigned int)(p_handle->data.zfs_handle.inode*p_handle->data.zfs_handle.generation*(p_handle->data.i_snap+1)) + 1999 + cookie) % index_size;
00086 
00087 }
00088 
00089 /*
00090  * FSAL_Handle_to_RBTIndex
00091  * This function is used for generating a RBT node ID
00092  * in order to identify entries into the RBT.
00093  *
00094  * \param p_handle      The handle to be hashed
00095  * \param cookie        Makes it possible to have different hash value for the
00096  *                      same handle, when cookie changes.
00097  *
00098  * \return The hash value
00099  */
00100 
00101 unsigned int ZFSFSAL_Handle_to_RBTIndex(fsal_handle_t * handle, unsigned int cookie)
00102 {
00103   zfsfsal_handle_t * p_handle = (zfsfsal_handle_t *)handle;
00104 
00105   /* >> here must be your implementation of your zfsfsal_handle_t hashing << */
00106   return (unsigned int)(0xABCD1234 ^ (p_handle->data.zfs_handle.inode*p_handle->data.zfs_handle.generation*(p_handle->data.i_snap+1)) ^ cookie);
00107 
00108 }
00109 
00126 fsal_status_t ZFSFSAL_DigestHandle(fsal_export_context_t * exp_context,     /* IN */
00127                                    fsal_digesttype_t output_type,       /* IN */
00128                                    fsal_handle_t *in_fsal_handle, /* IN */
00129                                    struct fsal_handle_desc *fh_desc     /* IN/OUT */ )
00130 {
00131   uint32_t ino32;
00132   zfsfsal_export_context_t * p_expcontext = (zfsfsal_export_context_t *)exp_context;
00133   zfsfsal_handle_t * p_in_fsal_handle = (zfsfsal_handle_t *)in_fsal_handle;
00134   size_t fh_size;
00135 
00136   /* sanity checks */
00137   if(!p_in_fsal_handle || !fh_desc || !fh_desc->start || !p_expcontext)
00138     ReturnCode(ERR_FSAL_FAULT, 0);
00139 
00140 
00141   switch (output_type)
00142    {
00143      /* NFS handle digest */
00144      case FSAL_DIGEST_NFSV2:
00145      case FSAL_DIGEST_NFSV3:
00146      case FSAL_DIGEST_NFSV4:
00147        fh_size = sizeof(p_in_fsal_handle->data) ;
00148        if(fh_desc->len < fh_size)
00149          {
00150                LogMajor( COMPONENT_FSAL,
00151                              "ZFS DigestHandle: space too small for handle.  need %lu, have %lu",
00152                              fh_size, fh_desc->len);
00153                ReturnCode(ERR_FSAL_TOOSMALL, 0);
00154             }
00155        memcpy(fh_desc->start, (caddr_t)p_in_fsal_handle, fh_size);
00156        fh_desc->len = fh_size;
00157        break;
00158      /* FileId digest for NFSv3 */
00159      case FSAL_DIGEST_FILEID2:
00160       ino32 = (uint32_t)(in_fsal_handle->data.zfs_handle.inode);
00161       memset(fh_desc->start, 0, FSAL_DIGEST_SIZE_FILEID2);
00162       memcpy(fh_desc->start, &ino32, sizeof( ino32 ));
00163       fh_desc->len = FSAL_DIGEST_SIZE_FILEID2; 
00164       break;
00165 
00166       /* FileId digest for NFSv3 */
00167     case FSAL_DIGEST_FILEID3:
00168       memset(fh_desc->start, 0, FSAL_DIGEST_SIZE_FILEID3);
00169       memcpy(fh_desc->start, &(p_in_fsal_handle->data.zfs_handle.inode), sizeof(fsal_u64_t));
00170       fh_desc->len = FSAL_DIGEST_SIZE_FILEID3;
00171       break;
00172 
00173       /* FileId digest for NFSv4 */
00174     case FSAL_DIGEST_FILEID4:
00175       memset(fh_desc->start, 0, FSAL_DIGEST_SIZE_FILEID4);
00176       memcpy(fh_desc->start, &(p_in_fsal_handle->data.zfs_handle.inode), sizeof(fsal_u64_t));
00177       fh_desc->len = FSAL_DIGEST_SIZE_FILEID4;
00178       break;
00179 
00180     default:
00181       ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00182     }
00183 
00184   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00185 
00186 }                               /* FSAL_DigestHandle */
00187 
00203 fsal_status_t ZFSFSAL_ExpandHandle(fsal_export_context_t * pexpcontext,     /* IN not used */
00204                                    fsal_digesttype_t in_type,   /* IN */
00205                                    struct fsal_handle_desc *fh_desc  /* IN/OUT */ )
00206 {
00207   zfsfsal_handle_t dummy_handle ;
00208   size_t fh_size;
00209 
00210   /* sanity checks */
00211   if(!fh_desc || !fh_desc->start || !pexpcontext)
00212     ReturnCode(ERR_FSAL_FAULT, 0);
00213 
00214   fh_size = sizeof( dummy_handle.data ); /* All ZFS handle have the same size */
00215   if(in_type == FSAL_DIGEST_NFSV2)
00216     {
00217       if(fh_desc->len < fh_size)
00218         {
00219           LogMajor(COMPONENT_FSAL,
00220                    "ZFS ExpandHandle: V2 size too small for handle.  should be %lu, got %lu",
00221                    fh_size, fh_desc->len);
00222           ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00223         }
00224     }
00225   else if(in_type != FSAL_DIGEST_SIZEOF && fh_desc->len != fh_size)
00226     {
00227       LogMajor(COMPONENT_FSAL,
00228                "ZFS ExpandHandle: size mismatch for handle.  should be %lu, got %lu",
00229                fh_size, fh_desc->len);
00230       ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00231     }
00232   fh_desc->len = fh_size;  /* pass back the actual size */
00233  
00234   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00235 }
00236 
00245 fsal_status_t ZFSFSAL_SetDefault_FS_specific_parameter(fsal_parameter_t * out_parameter)
00246 {
00247   /* defensive programming... */
00248   if(out_parameter == NULL)
00249     ReturnCode(ERR_FSAL_FAULT, 0);
00250 
00251   /* >> set your default FS configuration into the
00252      out_parameter->fs_specific_info structure << */
00253 
00254   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00255 
00256 }
00257 
00279 /* load specific filesystem configuration options */
00280 
00281 fsal_status_t ZFSFSAL_load_FS_specific_parameter_from_conf(config_file_t in_config,
00282                                                         fsal_parameter_t * out_parameter)
00283 {
00284   int err;
00285   int var_max, var_index;
00286   char *key_name;
00287   char *key_value;
00288   config_item_t block;
00289   zfsfs_specific_initinfo_t *specific_info =
00290           (zfsfs_specific_initinfo_t *) &out_parameter->fs_specific_info;
00291 
00292   block = config_FindItemByName(in_config, CONF_LABEL_FS_SPECIFIC);
00293 
00294   /* cannot read item */
00295   if(block == NULL)
00296     {
00297       LogCrit(COMPONENT_FSAL,"FSAL LOAD PARAMETER: Cannot read item \"%s\" from configuration file",
00298                  CONF_LABEL_FS_SPECIFIC);
00299       ReturnCode(ERR_FSAL_NOENT, 0);
00300     }
00301   else if(config_ItemType(block) != CONFIG_ITEM_BLOCK)
00302     {
00303       LogCrit(COMPONENT_FSAL,"FSAL LOAD PARAMETER: Item \"%s\" is expected to be a block",
00304                  CONF_LABEL_FS_SPECIFIC);
00305       ReturnCode(ERR_FSAL_INVAL, 0);
00306     }
00307 
00308   /* makes an iteration on the (key, value) couplets */
00309 
00310   var_max = config_GetNbItems(block);
00311 
00312   for(var_index = 0; var_index < var_max; var_index++)
00313     {
00314       config_item_t item;
00315 
00316       item = config_GetItemByIndex(block, var_index);
00317 
00318       err = config_GetKeyValue(item, &key_name, &key_value);
00319       if(err)
00320         {
00321           LogCrit(COMPONENT_FSAL,
00322               "FSAL LOAD PARAMETER: ERROR reading key[%d] from section \"%s\" of configuration file.",
00323                var_index, CONF_LABEL_FS_SPECIFIC);
00324           ReturnCode(ERR_FSAL_SERVERFAULT, err);
00325         }
00326 
00327       /* what parameter is it ? */
00328 
00329       if(!STRCMP(key_name, "zpool"))
00330           strncpy(specific_info->psz_zpool, key_value, 256);
00331       else if(!STRCMP(key_name, "auto_snapshots"))
00332           specific_info->auto_snapshots = !STRCMP(key_value, "TRUE");
00333       else if(!STRCMP(key_name, "snap_hourly_prefix"))
00334           strncpy(specific_info->psz_snap_hourly_prefix, key_value, 256);
00335       else if(!STRCMP(key_name, "snap_hourly_time"))
00336           specific_info->snap_hourly_time = atoi(key_value);
00337       else if(!STRCMP(key_name, "snap_hourly_number"))
00338           specific_info->snap_hourly_number = atoi(key_value);
00339       else if(!STRCMP(key_name, "snap_daily_prefix"))
00340           strncpy(specific_info->psz_snap_daily_prefix, key_value, 256);
00341       else if(!STRCMP(key_name, "snap_daily_time"))
00342           specific_info->snap_daily_time = atoi(key_value);
00343       else if(!STRCMP(key_name, "snap_daily_number"))
00344           specific_info->snap_daily_number = atoi(key_value);
00345       else
00346         {
00347           LogCrit(COMPONENT_FSAL,
00348               "FSAL LOAD PARAMETER: ERROR: Unknown or unsettable key: %s (item %s)",
00349                key_name, CONF_LABEL_FS_SPECIFIC);
00350           ReturnCode(ERR_FSAL_INVAL, 0);
00351         }
00352 
00353     }
00354 
00355   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00356 
00357 }                               /* FSAL_load_FS_specific_parameter_from_conf */