nfs-ganesha 1.4
|
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 */