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 #include <stddef.h> 00044 00045 /* case unsensitivity */ 00046 #define STRCMP strcasecmp 00047 00048 char *VFSFSAL_GetFSName() 00049 { 00050 return "VFS"; 00051 } 00052 00069 int VFSFSAL_handlecmp(fsal_handle_t * handle_1, fsal_handle_t * handle_2, 00070 fsal_status_t * status) 00071 { 00072 vfsfsal_handle_t * handle1 = (vfsfsal_handle_t *)handle_1; 00073 vfsfsal_handle_t * handle2 = (vfsfsal_handle_t *)handle_2; 00074 00075 *status = FSAL_STATUS_NO_ERROR; 00076 00077 if(!handle1 || !handle2) 00078 { 00079 status->major = ERR_FSAL_FAULT; 00080 return -1; 00081 } 00082 00083 if(handle1->data.vfs_handle.handle_bytes != handle2->data.vfs_handle.handle_bytes) 00084 return -2; 00085 00086 if(memcmp(&handle1->data.vfs_handle, &handle2->data.vfs_handle, sizeof( vfs_file_handle_t) ) ) 00087 return -3; 00088 00089 return 0; 00090 } 00091 00105 unsigned int VFSFSAL_Handle_to_HashIndex(fsal_handle_t *handle, 00106 unsigned int cookie, 00107 unsigned int alphabet_len, unsigned int index_size) 00108 { 00109 vfsfsal_handle_t * p_handle = (vfsfsal_handle_t *)handle; 00110 unsigned int cpt = 0; 00111 unsigned int sum = 0; 00112 unsigned int extract = 0; 00113 unsigned int mod; 00114 00115 /* XXX If the handle is not 32 bits-aligned, the last loop will get uninitialized 00116 * chars after the end of the handle. We must avoid this by skipping the last loop 00117 * and doing a special processing for the last bytes */ 00118 00119 mod = p_handle->data.vfs_handle.handle_bytes % sizeof(unsigned int); 00120 00121 sum = cookie; 00122 for(cpt = 0; cpt < p_handle->data.vfs_handle.handle_bytes - mod; cpt += sizeof(unsigned int)) 00123 { 00124 memcpy(&extract, &(p_handle->data.vfs_handle.handle[cpt]), sizeof(unsigned int)); 00125 sum = (3 * sum + 5 * extract + 1999) % index_size; 00126 } 00127 00128 if(mod) 00129 { 00130 extract = 0; 00131 for(cpt = p_handle->data.vfs_handle.handle_bytes - mod; cpt < p_handle->data.vfs_handle.handle_bytes; cpt++ ) 00132 { 00133 /* shift of 1 byte */ 00134 extract <<= 8; 00135 extract |= (unsigned int)p_handle->data.vfs_handle.handle[cpt]; 00136 } 00137 sum = (3 * sum + 5 * extract + 1999) % index_size; 00138 } 00139 00140 return sum; 00141 } 00142 00143 /* 00144 * FSAL_Handle_to_RBTIndex 00145 * This function is used for generating a RBT node ID 00146 * in order to identify entries into the RBT. 00147 * 00148 * \param p_handle The handle to be hashed 00149 * \param cookie Makes it possible to have different hash value for the 00150 * same handle, when cookie changes. 00151 * 00152 * \return The hash value 00153 */ 00154 00155 unsigned int VFSFSAL_Handle_to_RBTIndex(fsal_handle_t *handle, unsigned int cookie) 00156 { 00157 vfsfsal_handle_t * p_handle = (vfsfsal_handle_t *)handle; 00158 unsigned int h = 0; 00159 unsigned int cpt = 0; 00160 unsigned int extract = 0; 00161 unsigned int mod; 00162 00163 h = cookie; 00164 00165 /* XXX If the handle is not 32 bits-aligned, the last loop will get uninitialized 00166 * chars after the end of the handle. We must avoid this by skipping the last loop 00167 * and doing a special processing for the last bytes */ 00168 00169 mod = p_handle->data.vfs_handle.handle_bytes % sizeof(unsigned int); 00170 00171 for(cpt = 0; cpt < p_handle->data.vfs_handle.handle_bytes - mod; cpt += sizeof(unsigned int)) 00172 { 00173 memcpy(&extract, &(p_handle->data.vfs_handle.handle[cpt]), sizeof(unsigned int)); 00174 h = (857 * h ^ extract) % 715827883; 00175 } 00176 00177 if(mod) 00178 { 00179 extract = 0; 00180 for(cpt = p_handle->data.vfs_handle.handle_bytes - mod; cpt < p_handle->data.vfs_handle.handle_bytes; 00181 cpt++) 00182 { 00183 /* shift of 1 byte */ 00184 extract <<= 8; 00185 extract |= (unsigned int)p_handle->data.vfs_handle.handle[cpt]; 00186 } 00187 h = (857 * h ^ extract) % 715827883; 00188 } 00189 00190 return h; 00191 } 00192 00209 fsal_status_t VFSFSAL_DigestHandle(fsal_export_context_t * p_expcontext, /* IN */ 00210 fsal_digesttype_t output_type, /* IN */ 00211 fsal_handle_t *in_fsal_handle, /* IN */ 00212 struct fsal_handle_desc *fh_desc /* IN/OUT */ 00213 ) 00214 { 00215 uint32_t ino32; 00216 uint64_t ino64; 00217 size_t fh_size; 00218 vfsfsal_handle_t * p_in_fsal_handle = (vfsfsal_handle_t *)in_fsal_handle; 00219 00220 /* sanity checks */ 00221 if(!p_in_fsal_handle || !fh_desc || !fh_desc->start || !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 case FSAL_DIGEST_NFSV3: 00230 case FSAL_DIGEST_NFSV4: 00231 fh_size = vfs_sizeof_handle((struct file_handle *)in_fsal_handle); 00232 if(fh_desc->len < fh_size) 00233 { 00234 LogMajor(COMPONENT_FSAL, 00235 "VFS DigestHandle: space too small for handle. need %lu, have %lu", 00236 fh_size, fh_desc->len); 00237 ReturnCode(ERR_FSAL_TOOSMALL, 0); 00238 } 00239 memcpy(fh_desc->start, (caddr_t)p_in_fsal_handle, fh_size); 00240 fh_desc->len = fh_size; 00241 break; 00242 00243 case FSAL_DIGEST_FILEID2: 00244 memcpy(fh_desc->start, p_in_fsal_handle->data.vfs_handle.handle, FSAL_DIGEST_SIZE_FILEID2); 00245 fh_desc->len = FSAL_DIGEST_SIZE_FILEID2; 00246 break; 00247 00248 case FSAL_DIGEST_FILEID3: 00249 /* Extracting FileId from VFS handle requires internal knowledge on the handle's structure 00250 * which is given by 'struct fid' in kernel's sources. For most FS, it looks like this: 00251 * struct fid { 00252 union { 00253 struct { 00254 u32 ino; 00255 u32 gen; 00256 u32 parent_ino; 00257 u32 parent_gen; 00258 } i32; 00259 struct { 00260 u32 block; 00261 u16 partref; 00262 u16 parent_partref; 00263 u32 generation; 00264 u32 parent_block; 00265 u32 parent_generation; 00266 } udf; 00267 __u32 raw[0]; 00268 }; 00269 }; 00270 This means that in most cases, fileid will be found in the first 32 bits of the structure. But there are exception 00271 BTRFS is one of them, with a struct fid like this 00272 struct btrfs_fid { 00273 u64 objectid; 00274 u64 root_objectid; 00275 u32 gen; 00276 00277 u64 parent_objectid; 00278 u32 parent_gen; 00279 00280 u64 parent_root_objectid; 00281 } __attribute__ ((packed));*/ 00282 memcpy(&ino32, p_in_fsal_handle->data.vfs_handle.handle, sizeof(ino32)); 00283 ino64 = ino32; 00284 memcpy(fh_desc->start, &ino64, FSAL_DIGEST_SIZE_FILEID3); 00285 fh_desc->len = FSAL_DIGEST_SIZE_FILEID3; 00286 break; 00287 00288 00289 case FSAL_DIGEST_FILEID4: 00290 memcpy(&ino32, p_in_fsal_handle->data.vfs_handle.handle, sizeof(ino32)); 00291 ino64 = ino32; 00292 memcpy(fh_desc->start, &ino64, FSAL_DIGEST_SIZE_FILEID4); 00293 fh_desc->len = FSAL_DIGEST_SIZE_FILEID4; 00294 break; 00295 00296 default: 00297 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00298 00299 } 00300 00301 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00302 00303 } 00304 00321 fsal_status_t VFSFSAL_ExpandHandle(fsal_export_context_t * p_expcontext, /* IN not used */ 00322 fsal_digesttype_t in_type, /* IN */ 00323 struct fsal_handle_desc *fh_desc /* IN/OUT */ ) 00324 { 00325 struct file_handle *hdl; 00326 size_t fh_size; 00327 00328 /* sanity checks */ 00329 if( !fh_desc || !fh_desc->start) 00330 ReturnCode(ERR_FSAL_FAULT, 0); 00331 00332 hdl = (struct file_handle *)fh_desc->start; 00333 fh_size = vfs_sizeof_handle(hdl); 00334 if(in_type == FSAL_DIGEST_NFSV2) 00335 { 00336 if(fh_desc->len < fh_size) 00337 { 00338 LogMajor(COMPONENT_FSAL, 00339 "VFS ExpandHandle: V2 size too small for handle. should be %lu, got %lu", 00340 fh_size, fh_desc->len); 00341 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00342 } 00343 } 00344 else if(in_type != FSAL_DIGEST_SIZEOF && fh_desc->len != fh_size) 00345 { 00346 LogMajor(COMPONENT_FSAL, 00347 "VFS ExpandHandle: size mismatch for handle. should be %lu, got %lu", 00348 fh_size, fh_desc->len); 00349 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00350 } 00351 fh_desc->len = fh_size; /* pass back the actual size */ 00352 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00353 00354 } 00355 00364 fsal_status_t VFSFSAL_SetDefault_FS_specific_parameter(fsal_parameter_t * out_parameter) 00365 { 00366 /* defensive programming... */ 00367 if(out_parameter == NULL) 00368 ReturnCode(ERR_FSAL_FAULT, 0); 00369 00370 /* set default values for all parameters of fs_specific_info */ 00371 00372 #ifdef _USE_PGSQL 00373 00374 /* pgsql db */ 00375 q strcpy(out_parameter->fs_specific_info.dbparams.host, "localhost"); 00376 strcpy(out_parameter->fs_specific_info.dbparams.port, "5432"); 00377 out_parameter->fs_specific_info.dbparams.dbname[0] = '\0'; 00378 out_parameter->fs_specific_info.dbparams.login[0] = '\0'; 00379 out_parameter->fs_specific_info.dbparams.passwdfile[0] = '\0'; 00380 00381 #elif defined(_USE_MYSQL) 00382 00383 strcpy(out_parameter->fs_specific_info.dbparams.host, "localhost"); 00384 strcpy(out_parameter->fs_specific_info.dbparams.port, ""); 00385 out_parameter->fs_specific_info.dbparams.dbname[0] = '\0'; 00386 out_parameter->fs_specific_info.dbparams.login[0] = '\0'; 00387 out_parameter->fs_specific_info.dbparams.passwdfile[0] = '\0'; 00388 00389 #endif 00390 00391 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00392 00393 } 00394 00416 /* load FSAL init info */ 00417 00418 00419 /* load specific filesystem configuration options */ 00420 fsal_status_t VFSFSAL_load_FS_specific_parameter_from_conf(config_file_t in_config, 00421 fsal_parameter_t * 00422 out_parameter) 00423 { 00424 00425 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00426 00427 } /* FSAL_load_FS_specific_parameter_from_conf */