nfs-ganesha 1.4

fsal_tools.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright CEA/DAM/DIF  (2008)
00005  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00006  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 3 of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  * ------------- 
00024  */
00025 
00034 #ifdef HAVE_CONFIG_H
00035 #include "config.h"
00036 #endif
00037 
00038 #include <assert.h>
00039 #include "fsal.h"
00040 #include "fsal_internal.h"
00041 #include "fsal_convert.h"
00042 #include "config_parsing.h"
00043 #include <string.h>
00044 
00045 /* case unsensitivity */
00046 #define STRCMP   strcasecmp
00047 
00048 char *XFSFSAL_GetFSName()
00049 {
00050   return "XFS";
00051 }
00052 
00069 int XFSFSAL_handlecmp(fsal_handle_t * hdl1, fsal_handle_t * hdl2,
00070                       fsal_status_t * status)
00071 {
00072   xfsfsal_handle_t * handle1 = (xfsfsal_handle_t *)hdl1;
00073   xfsfsal_handle_t * handle2 = (xfsfsal_handle_t *)hdl2;
00074   *status = FSAL_STATUS_NO_ERROR;
00075 
00076   if(!handle1 || !handle2)
00077     {
00078       status->major = ERR_FSAL_FAULT;
00079       return -1;
00080     }
00081 
00082   if((handle1->data.inode != handle2->data.inode) ||
00083      (handle1->data.type != handle2->data.type) ||
00084      (handle1->data.handle_len != handle2->data.handle_len))
00085     return 1;
00086 
00087   return memcmp(handle1->data.handle_val, handle2->data.handle_val, handle2->data.handle_len);
00088 }
00089 
00103 unsigned int XFSFSAL_Handle_to_HashIndex(fsal_handle_t * handle,
00104                                          unsigned int cookie,
00105                                          unsigned int alphabet_len,
00106                                          unsigned int index_size)
00107 {
00108   xfsfsal_handle_t * p_handle = (xfsfsal_handle_t *)handle;
00109   unsigned int cpt = 0;
00110   unsigned int sum = 0;
00111   unsigned int extract = 0;
00112   unsigned int mod = 0;
00113 
00114   /* XXX If the handle is not 32 bits-aligned, the last loop will get uninitialized
00115    * chars after the end of the handle. We must avoid this by skipping the last loop
00116    * and doing a special processing for the last bytes */
00117 
00118   mod = p_handle->data.handle_len % sizeof(unsigned int);
00119 
00120   sum = cookie;
00121   for(cpt = 0; cpt < p_handle->data.handle_len - mod; cpt += sizeof(unsigned int))
00122     {
00123       memcpy(&extract, &(p_handle->data.handle_val[cpt]), sizeof(unsigned int));
00124       sum = (3 * sum + 5 * extract + 1999) % index_size;
00125     }
00126 
00127   if(mod)
00128     {
00129       extract = 0;
00130       for(cpt = p_handle->data.handle_len - mod; cpt < p_handle->data.handle_len; cpt++)
00131         {
00132           /* shift of 1 byte */
00133           extract <<= 8;
00134           extract |= (unsigned int)p_handle->data.handle_val[cpt];
00135         }
00136       sum = (3 * sum + 5 * extract + 1999) % index_size;
00137     }
00138 
00139   return sum;
00140 }
00141 
00142 /*
00143  * FSAL_Handle_to_RBTIndex
00144  * This function is used for generating a RBT node ID
00145  * in order to identify entries into the RBT.
00146  *
00147  * \param p_handle      The handle to be hashed
00148  * \param cookie        Makes it possible to have different hash value for the
00149  *                      same handle, when cookie changes.
00150  *
00151  * \return The hash value
00152  */
00153 
00154 unsigned int XFSFSAL_Handle_to_RBTIndex(fsal_handle_t * handle, unsigned int cookie)
00155 {
00156   xfsfsal_handle_t * p_handle = (xfsfsal_handle_t *)handle;
00157   unsigned int h = 0;
00158   unsigned int cpt = 0;
00159   unsigned int extract = 0;
00160   unsigned int mod = 0;
00161 
00162   h = cookie;
00163 
00164   /* XXX If the handle is not 32 bits-aligned, the last loop will get uninitialized
00165    * chars after the end of the handle. We must avoid this by skipping the last loop
00166    * and doing a special processing for the last bytes */
00167 
00168   mod = p_handle->data.handle_len % sizeof(unsigned int);
00169 
00170   for(cpt = 0; cpt < p_handle->data.handle_len - mod; cpt += sizeof(unsigned int))
00171     {
00172       memcpy(&extract, &(p_handle->data.handle_val[cpt]), sizeof(unsigned int));
00173       h = (857 * h ^ extract) % 715827883;
00174     }
00175 
00176   if(mod)
00177     {
00178       extract = 0;
00179       for(cpt = p_handle->data.handle_len - mod; cpt < p_handle->data.handle_len; cpt++)
00180         {
00181           /* shift of 1 byte */
00182           extract <<= 8;
00183           extract |= (unsigned int)p_handle->data.handle_val[cpt];
00184         }
00185       h = (857 * h ^ extract) % 715827883;
00186     }
00187 
00188   return h;
00189 }
00190 
00191 static ssize_t xfs_sizeof_handle(const xfsfsal_handle_t *hdl)
00192 {
00193         /* data.handle_len is unsigned */
00194         if(hdl->data.handle_len >= FSAL_XFS_HANDLE_LEN)
00195           {
00196                 LogMajor(COMPONENT_FSAL, "Incorrect XFS handle length %d",
00197                          hdl->data.handle_len);
00198                 return (size_t)-1;
00199           }
00200         return offsetof(xfsfsal_handle_t, data.handle_val) + hdl->data.handle_len;
00201 }
00202 
00222 fsal_status_t XFSFSAL_DigestHandle(fsal_export_context_t * p_expcontext,     /* IN */
00223                                    fsal_digesttype_t output_type,      /* IN */
00224                                    fsal_handle_t * handle, /* IN */
00225                                    struct fsal_handle_desc * fh_desc  /* OUT */
00226     )
00227 {
00228   const xfsfsal_handle_t * xfs_handle = (const xfsfsal_handle_t *)handle;
00229   const void *start;
00230   ssize_t sz;
00231   unsigned int ino32;
00232 
00233   /* sanity checks */
00234   if(!handle || !fh_desc || !fh_desc->start || !p_expcontext)
00235     ReturnCode(ERR_FSAL_FAULT, 0);
00236 
00237   switch (output_type)
00238     {
00239     case FSAL_DIGEST_NFSV2:
00240     case FSAL_DIGEST_NFSV3:
00241     case FSAL_DIGEST_NFSV4:
00242       sz = xfs_sizeof_handle(xfs_handle);
00243       start = xfs_handle;
00244       break;
00245 
00246     case FSAL_DIGEST_FILEID2:
00247       ino32 = my_low32m(xfs_handle->data.inode);
00248       if (ino32 != xfs_handle->data.inode)
00249           ReturnCode(ERR_FSAL_OVERFLOW, 0);
00250       sz = sizeof(ino32);
00251       start = &ino32;
00252       break;
00253 
00254     case FSAL_DIGEST_FILEID3:
00255     case FSAL_DIGEST_FILEID4:
00256       sz = sizeof(xfs_handle->data.inode);
00257       start = &xfs_handle->data.inode;  
00258       break;
00259 
00260     default:
00261       ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00262     }
00263 
00264     if(fh_desc->len < sz)
00265       {
00266         LogMajor(COMPONENT_FSAL,
00267                  "buffer too small - need %zd, have %zd", sz, fh_desc->len);
00268         ReturnCode(ERR_FSAL_TOOSMALL, 0);
00269       }
00270     memcpy(fh_desc->start, start, sz);
00271     fh_desc->len = sz;
00272     ReturnCode(ERR_FSAL_NO_ERROR, 0);
00273 }
00274 
00287 fsal_status_t XFSFSAL_ExpandHandle(fsal_export_context_t * p_expcontext,     /* IN */
00288                                    fsal_digesttype_t in_type,   /* IN */
00289                                    struct fsal_handle_desc *fh_desc /* IN/OUT */
00290     )
00291 {
00292   ssize_t fh_size;
00293   const xfsfsal_handle_t *xh = (const xfsfsal_handle_t *)fh_desc->start;
00294 
00295   /* sanity checks */
00296   if( !fh_desc || !fh_desc->start)
00297     ReturnCode(ERR_FSAL_FAULT, 0);
00298 
00299   fh_size = xfs_sizeof_handle(xh);
00300   if(fh_size < 0)
00301     ReturnCode(ERR_FSAL_BADHANDLE, 0);
00302 
00303   switch(xh->data.type)
00304     {
00305     case DT_LNK:
00306     case DT_BLK:
00307     case DT_SOCK:
00308     case DT_CHR:
00309     case DT_FIFO:
00310     case DT_REG:
00311     case DT_DIR:
00312         break;
00313     default:
00314         LogMajor(COMPONENT_FSAL,
00315                  "Corrupted filehandle - unexpected file type %d",
00316                  xh->data.type);
00317         ReturnCode(ERR_FSAL_BADHANDLE, EINVAL);
00318     }
00319 
00320   switch(in_type)
00321     {
00322     case FSAL_DIGEST_NFSV2:
00323       if(fh_desc->len < fh_size)
00324         {
00325           LogMajor(COMPONENT_FSAL,
00326                    "buffer too small for handle.  should be %zd, got %zd",
00327                    fh_size, fh_desc->len);
00328           ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00329         }
00330       break;
00331     case FSAL_DIGEST_NFSV3:
00332     case FSAL_DIGEST_NFSV4:
00333       if(fh_desc->len != fh_size)
00334         {
00335           LogMajor(COMPONENT_FSAL,
00336                    "size mismatch for handle.  should be %zd, got %zd",
00337                    fh_size, fh_desc->len);
00338           ReturnCode(ERR_FSAL_BADHANDLE, 0);
00339         }
00340       break;
00341     case FSAL_DIGEST_SIZEOF:
00342       break;
00343     default: /* Catch FILEID2, FILEID3, FILEID4 */
00344       ReturnCode(ERR_FSAL_SERVERFAULT, 0);
00345     }
00346   fh_desc->len = fh_size;  /* pass back the actual size */
00347   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00348 }
00349 
00358 fsal_status_t XFSFSAL_SetDefault_FS_specific_parameter(fsal_parameter_t * out_parameter)
00359 {
00360   /* defensive programming... */
00361   if(out_parameter == NULL)
00362     ReturnCode(ERR_FSAL_FAULT, 0);
00363 
00364   /* set default values for all parameters of fs_specific_info */
00365 
00366 #ifdef _USE_PGSQL
00367 
00368   /* pgsql db */
00369   strcpy(out_parameter->fs_specific_info.dbparams.host, "localhost");
00370   strcpy(out_parameter->fs_specific_info.dbparams.port, "5432");
00371   out_parameter->fs_specific_info.dbparams.dbname[0] = '\0';
00372   out_parameter->fs_specific_info.dbparams.login[0] = '\0';
00373   out_parameter->fs_specific_info.dbparams.passwdfile[0] = '\0';
00374 
00375 #elif defined(_USE_MYSQL)
00376 
00377   strcpy(out_parameter->fs_specific_info.dbparams.host, "localhost");
00378   strcpy(out_parameter->fs_specific_info.dbparams.port, "");
00379   out_parameter->fs_specific_info.dbparams.dbname[0] = '\0';
00380   out_parameter->fs_specific_info.dbparams.login[0] = '\0';
00381   out_parameter->fs_specific_info.dbparams.passwdfile[0] = '\0';
00382 
00383 #endif
00384 
00385   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00386 
00387 }
00388 
00410 /* load specific filesystem configuration options */
00411 
00412 fsal_status_t XFSFSAL_load_FS_specific_parameter_from_conf(config_file_t in_config,
00413                                                            fsal_parameter_t *
00414                                                            out_parameter)
00415 {
00416 
00417   ReturnCode(ERR_FSAL_NO_ERROR, 0);
00418 
00419 }                               /* FSAL_load_FS_specific_parameter_from_conf */