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 "fsal.h" 00039 #include "fsal_internal.h" 00040 #include "fsal_convert.h" 00041 #include "config_parsing.h" 00042 #include <string.h> 00043 00044 /* case unsensitivity */ 00045 #define STRCMP strcasecmp 00046 00047 char *GPFSFSAL_GetFSName() 00048 { 00049 return "GPFS"; 00050 } 00051 00068 int GPFSFSAL_handlecmp(fsal_handle_t * handle_1, fsal_handle_t * handle_2, 00069 fsal_status_t * status) 00070 { 00071 gpfsfsal_handle_t *handle1 = (gpfsfsal_handle_t *)handle_1; 00072 gpfsfsal_handle_t *handle2 = (gpfsfsal_handle_t *)handle_2; 00073 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.handle.handle_size != handle2->data.handle.handle_size) 00083 return -2; 00084 00085 if(memcmp 00086 (handle1->data.handle.f_handle, handle2->data.handle.f_handle, handle1->data.handle.handle_key_size)) 00087 //FSF && (handle1->fsid[0] == handle2->fsid[0]) 00088 //FSF && (handle1->fsid[1] == handle2->fsid[1]) ) 00089 return -3; 00090 00091 return 0; 00092 } 00093 00107 unsigned int GPFSFSAL_Handle_to_HashIndex(fsal_handle_t * handle, 00108 unsigned int cookie, 00109 unsigned int alphabet_len, unsigned int index_size) 00110 { 00111 unsigned int cpt = 0; 00112 unsigned int sum = 0; 00113 unsigned int extract = 0; 00114 unsigned int mod; 00115 gpfsfsal_handle_t *p_handle = (gpfsfsal_handle_t *)handle; 00116 00117 /* XXX If the handle is not 32 bits-aligned, the last loop will get uninitialized 00118 * chars after the end of the handle. We must avoid this by skipping the last loop 00119 * and doing a special processing for the last bytes */ 00120 00121 mod = p_handle->data.handle.handle_key_size % sizeof(unsigned int); 00122 00123 sum = cookie; 00124 for(cpt = 0; cpt < p_handle->data.handle.handle_key_size - mod; cpt += sizeof(unsigned int)) 00125 { 00126 memcpy(&extract, &(p_handle->data.handle.f_handle[cpt]), sizeof(unsigned int)); 00127 sum = (3 * sum + 5 * extract + 1999) % index_size; 00128 } 00129 00130 if(mod) 00131 { 00132 extract = 0; 00133 for(cpt = p_handle->data.handle.handle_key_size - mod; cpt < p_handle->data.handle.handle_key_size; 00134 cpt++) 00135 { 00136 /* shift of 1 byte */ 00137 extract <<= 8; 00138 extract |= (unsigned int)p_handle->data.handle.f_handle[cpt]; 00139 } 00140 sum = (3 * sum + 5 * extract + 1999) % index_size; 00141 } 00142 00143 return sum; 00144 } 00145 00146 /* 00147 * FSAL_Handle_to_RBTIndex 00148 * This function is used for generating a RBT node ID 00149 * in order to identify entries into the RBT. 00150 * 00151 * \param p_handle The handle to be hashed 00152 * \param cookie Makes it possible to have different hash value for the 00153 * same handle, when cookie changes. 00154 * 00155 * \return The hash value 00156 */ 00157 00158 unsigned int GPFSFSAL_Handle_to_RBTIndex(fsal_handle_t * handle, unsigned int cookie) 00159 { 00160 unsigned int h = 0; 00161 unsigned int cpt = 0; 00162 unsigned int extract = 0; 00163 unsigned int mod; 00164 gpfsfsal_handle_t * p_handle = (gpfsfsal_handle_t *)handle; 00165 00166 h = cookie; 00167 00168 /* XXX If the handle is not 32 bits-aligned, the last loop will get uninitialized 00169 * chars after the end of the handle. We must avoid this by skipping the last loop 00170 * and doing a special processing for the last bytes */ 00171 00172 mod = p_handle->data.handle.handle_key_size % sizeof(unsigned int); 00173 00174 for(cpt = 0; cpt < p_handle->data.handle.handle_key_size - mod; cpt += sizeof(unsigned int)) 00175 { 00176 memcpy(&extract, &(p_handle->data.handle.f_handle[cpt]), sizeof(unsigned int)); 00177 h = (857 * h ^ extract) % 715827883; 00178 } 00179 00180 if(mod) 00181 { 00182 extract = 0; 00183 for(cpt = p_handle->data.handle.handle_key_size - mod; cpt < p_handle->data.handle.handle_key_size; 00184 cpt++) 00185 { 00186 /* shift of 1 byte */ 00187 extract <<= 8; 00188 extract |= (unsigned int)p_handle->data.handle.f_handle[cpt]; 00189 } 00190 h = (857 * h ^ extract) % 715827883; 00191 } 00192 00193 return h; 00194 } 00195 00210 fsal_status_t GPFSFSAL_DigestHandle(fsal_export_context_t *exp_context, /* IN */ 00211 fsal_digesttype_t output_type, /* IN */ 00212 fsal_handle_t * in_fsal_handle, /* IN */ 00213 struct fsal_handle_desc *fh_desc /* IN/OUT */ 00214 ) 00215 { 00216 gpfsfsal_export_context_t * p_expcontext = (gpfsfsal_export_context_t *)exp_context; 00217 gpfsfsal_handle_t * p_in_fsal_handle = (gpfsfsal_handle_t *)in_fsal_handle; 00218 size_t fh_size; 00219 00220 /* sanity checks */ 00221 if(!p_in_fsal_handle || !fh_desc || !p_expcontext) 00222 ReturnCode(ERR_FSAL_FAULT, 0); 00223 00224 switch (output_type) 00225 { 00226 00227 /* NFS handle digest */ 00228 case FSAL_DIGEST_NFSV2: 00229 00230 /* GPFS FSAL can no longer support NFS v2 */ 00231 ReturnCode(ERR_FSAL_NOTSUPP, 0); 00232 00233 case FSAL_DIGEST_NFSV3: 00234 case FSAL_DIGEST_NFSV4: 00235 fh_size = gpfs_sizeof_handle((struct gpfs_file_handle *)in_fsal_handle); 00236 if(fh_desc->len < fh_size) 00237 { 00238 LogMajor(COMPONENT_FSAL, 00239 "GPFSFSAL_DigestHandle: space too small for handle.Need %lu, have %lu", 00240 (unsigned long)fh_size, (unsigned long)fh_desc->len); 00241 ReturnCode(ERR_FSAL_TOOSMALL, 0); 00242 } 00243 memcpy(fh_desc->start, (caddr_t)p_in_fsal_handle, fh_size); 00244 fh_desc->len = fh_size; 00245 break; 00246 00247 /* FileId digest for NFSv2 */ 00248 case FSAL_DIGEST_FILEID2: 00249 00250 /* GPFS FSAL can no longer support NFS v2 */ 00251 ReturnCode(ERR_FSAL_NOTSUPP, 0); 00252 00253 /* FileId digest for NFSv3 */ 00254 case FSAL_DIGEST_FILEID3: 00255 00256 /* sanity check about output size */ 00257 /* If the handle_size is the full OPENHANDLE_HANDLE_LEN then we assume it's a new style GPFS handle */ 00258 if (fh_desc->len == 8) 00259 memset(fh_desc->start, 0, sizeof(uint64_t)); 00260 if(p_in_fsal_handle->data.handle.handle_size < OPENHANDLE_HANDLE_LEN) 00261 memcpy(fh_desc->start, p_in_fsal_handle->data.handle.f_handle, sizeof(uint32_t)); 00262 else 00263 memcpy(fh_desc->start, p_in_fsal_handle->data.handle.f_handle + OPENHANDLE_OFFSET_OF_FILEID, sizeof(uint64_t)); 00264 break; 00265 00266 /* FileId digest for NFSv4 */ 00267 case FSAL_DIGEST_FILEID4: 00268 00269 if(p_in_fsal_handle->data.handle.handle_size < OPENHANDLE_HANDLE_LEN) 00270 memcpy(fh_desc->start, p_in_fsal_handle->data.handle.f_handle, sizeof(uint32_t)); 00271 else 00272 memcpy(fh_desc->start, p_in_fsal_handle->data.handle.f_handle + OPENHANDLE_OFFSET_OF_FILEID, sizeof(uint64_t)); 00273 break; 00274 00275 default: 00276 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00277 } 00278 00279 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00280 00281 } 00282 00299 fsal_status_t GPFSFSAL_ExpandHandle(fsal_export_context_t *exp_context, /* IN */ 00300 fsal_digesttype_t in_type, /* IN */ 00301 struct fsal_handle_desc *fh_desc /* IN/OUT */ 00302 ) 00303 { 00304 struct gpfs_file_handle *hdl; 00305 size_t fh_size; 00306 00307 /* sanity checks */ 00308 if(!fh_desc || !fh_desc->start) 00309 ReturnCode(ERR_FSAL_FAULT, 0); 00310 00311 hdl = (struct gpfs_file_handle *)fh_desc->start; 00312 fh_size = gpfs_sizeof_handle(hdl); 00313 00314 if(in_type == FSAL_DIGEST_NFSV2) 00315 { 00316 /* GPFS FSAL can no longer support NFS v2 */ 00317 ReturnCode(ERR_FSAL_NOTSUPP, 0); 00318 } 00319 else if(in_type != FSAL_DIGEST_SIZEOF && fh_desc->len != fh_size) 00320 { 00321 LogMajor(COMPONENT_FSAL, 00322 "GPFSFSAL_ExpandHandle: size mismatch for handle. should be %lu, got %lu", 00323 fh_size, fh_desc->len); 00324 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00325 } 00326 00327 fh_desc->len = fh_size; /* pass back the actual size */ 00328 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00329 00330 } 00331 00340 fsal_status_t GPFSFSAL_SetDefault_FS_specific_parameter(fsal_parameter_t * out_parameter) 00341 { 00342 /* defensive programming... */ 00343 if(out_parameter == NULL) 00344 ReturnCode(ERR_FSAL_FAULT, 0); 00345 00346 /* set default values for all parameters of fs_specific_info */ 00347 00348 #ifdef _USE_PGSQL 00349 00350 /* pgsql db */ 00351 strcpy(out_parameter->fs_specific_info.dbparams.host, "localhost"); 00352 strcpy(out_parameter->fs_specific_info.dbparams.port, "5432"); 00353 out_parameter->fs_specific_info.dbparams.dbname[0] = '\0'; 00354 out_parameter->fs_specific_info.dbparams.login[0] = '\0'; 00355 out_parameter->fs_specific_info.dbparams.passwdfile[0] = '\0'; 00356 00357 #elif defined(_USE_MYSQL) 00358 00359 strcpy(out_parameter->fs_specific_info.dbparams.host, "localhost"); 00360 strcpy(out_parameter->fs_specific_info.dbparams.port, ""); 00361 out_parameter->fs_specific_info.dbparams.dbname[0] = '\0'; 00362 out_parameter->fs_specific_info.dbparams.login[0] = '\0'; 00363 out_parameter->fs_specific_info.dbparams.passwdfile[0] = '\0'; 00364 00365 #endif 00366 00367 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00368 00369 } 00370 00392 /* load specific filesystem configuration options */ 00393 00394 fsal_status_t GPFSFSAL_load_FS_specific_parameter_from_conf(config_file_t in_config, 00395 fsal_parameter_t * out_parameter) 00396 { 00397 int err; 00398 int var_max, var_index; 00399 char *key_name; 00400 char *key_value; 00401 config_item_t block; 00402 gpfsfs_specific_initinfo_t *initinfo 00403 = (gpfsfs_specific_initinfo_t *) &out_parameter->fs_specific_info; 00404 00405 block = config_FindItemByName(in_config, CONF_LABEL_FS_SPECIFIC); 00406 00407 /* cannot read item */ 00408 if(block == NULL) 00409 { 00410 LogCrit(COMPONENT_CONFIG, 00411 "FSAL LOAD PARAMETER: Cannot read item \"%s\" from configuration file", 00412 CONF_LABEL_FS_SPECIFIC); 00413 ReturnCode(ERR_FSAL_NOENT, 0); 00414 } 00415 else if(config_ItemType(block) != CONFIG_ITEM_BLOCK) 00416 { 00417 LogCrit(COMPONENT_CONFIG, 00418 "FSAL LOAD PARAMETER: Item \"%s\" is expected to be a block", 00419 CONF_LABEL_FS_SPECIFIC); 00420 ReturnCode(ERR_FSAL_INVAL, 0); 00421 } 00422 00423 var_max = config_GetNbItems(block); 00424 00425 for(var_index = 0; var_index < var_max; var_index++) 00426 { 00427 config_item_t item; 00428 00429 item = config_GetItemByIndex(block, var_index); 00430 00431 err = config_GetKeyValue(item, &key_name, &key_value); 00432 if(err) 00433 { 00434 LogCrit(COMPONENT_CONFIG, 00435 "FSAL LOAD PARAMETER: ERROR reading key[%d] from section \"%s\" of configuration file.", 00436 var_index, CONF_LABEL_FS_SPECIFIC); 00437 ReturnCode(ERR_FSAL_SERVERFAULT, err); 00438 } 00439 /* does the variable exists ? */ 00440 if(!STRCMP(key_name, "OpenByHandleDeviceFile")) 00441 { 00442 strncpy(initinfo->open_by_handle_dev_file, key_value, 00443 MAXPATHLEN); 00444 } 00445 else if(!STRCMP(key_name, "Use_Kernel_Module_Interface")) 00446 { 00447 int bool = StrToBoolean(key_value); 00448 if (bool == -1) 00449 { 00450 LogCrit(COMPONENT_CONFIG, 00451 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: 0 or 1 expected.", 00452 key_name); 00453 ReturnCode(ERR_FSAL_INVAL, 0); 00454 } 00455 initinfo->use_kernel_module_interface = bool; 00456 } 00457 else 00458 { 00459 LogCrit(COMPONENT_CONFIG, 00460 "FSAL LOAD PARAMETER: ERROR: Unknown or unsettable key: %s (item %s)", 00461 key_name, CONF_LABEL_FS_SPECIFIC); 00462 ReturnCode(ERR_FSAL_INVAL, 0); 00463 } 00464 } 00465 00466 if(initinfo->use_kernel_module_interface && initinfo->open_by_handle_dev_file[0] == '\0') 00467 { 00468 LogCrit(COMPONENT_CONFIG, 00469 "FSAL LOAD PARAMETER: OpenByHandleDeviceFile MUST be specified in the configuration file (item %s)", 00470 CONF_LABEL_FS_SPECIFIC); 00471 ReturnCode(ERR_FSAL_NOENT, 0); 00472 } 00473 00474 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00475 00476 } /* FSAL_load_FS_specific_parameter_from_conf */