nfs-ganesha 1.4
|
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_convert.h" 00020 #include "config_parsing.h" 00021 #include <string.h> 00022 00023 /* case unsensitivity */ 00024 #define STRCMP strcasecmp 00025 00026 char *POSIXFSAL_GetFSName() 00027 { 00028 return "POSIX"; 00029 } 00030 00047 int POSIXFSAL_handlecmp(fsal_handle_t * hdl1, fsal_handle_t * hdl2, 00048 fsal_status_t * status) 00049 { 00050 posixfsal_handle_t * handle1 = (posixfsal_handle_t *) hdl1; 00051 posixfsal_handle_t * handle2 = (posixfsal_handle_t *) hdl2; 00052 *status = FSAL_STATUS_NO_ERROR; 00053 00054 if(!handle1 || !handle2) 00055 { 00056 status->major = ERR_FSAL_FAULT; 00057 return -1; 00058 } 00059 00060 return (handle1->data.id != handle2->data.id) || (handle1->data.ts != handle2->data.ts); 00061 00062 } 00063 00078 unsigned int POSIXFSAL_Handle_to_HashIndex(fsal_handle_t * handle, 00079 unsigned int cookie, 00080 unsigned int alphabet_len, 00081 unsigned int index_size) 00082 { 00083 posixfsal_handle_t * p_handle = (posixfsal_handle_t *) handle; 00084 unsigned int h; 00085 h = (cookie * alphabet_len + ((unsigned int)p_handle->data.id ^ (unsigned int)p_handle->data.ts)); 00086 return (3 * h + 1999) % index_size; 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 POSIXFSAL_Handle_to_RBTIndex(fsal_handle_t * handle, 00102 unsigned int cookie) 00103 { 00104 #define MAGIC 0xABCD1234 00105 posixfsal_handle_t * p_handle = (posixfsal_handle_t *) handle; 00106 unsigned int h; 00107 00108 h = (cookie ^ (unsigned int)p_handle->data.id ^ (unsigned int)p_handle->data.ts ^ MAGIC); 00109 return h; 00110 } 00111 00128 fsal_status_t POSIXFSAL_DigestHandle(fsal_export_context_t * expcontext, /* IN */ 00129 fsal_digesttype_t output_type, /* IN */ 00130 fsal_handle_t * in_fsal_handle, /* IN */ 00131 struct fsal_handle_desc *fh_desc /* IN/OUT */ 00132 ) 00133 { 00134 posixfsal_export_context_t * p_expcontext 00135 = (posixfsal_export_context_t *) expcontext; 00136 posixfsal_handle_t * p_in_fsal_handle = (posixfsal_handle_t *) in_fsal_handle; 00137 size_t fh_size; 00138 caddr_t fh_data; 00139 00140 /* sanity checks */ 00141 if(!p_in_fsal_handle || !fh_desc || !fh_desc->start || !p_expcontext) 00142 ReturnCode(ERR_FSAL_FAULT, 0); 00143 00144 switch (output_type) 00145 { 00146 /* NFS handle digest */ 00147 case FSAL_DIGEST_NFSV2: 00148 case FSAL_DIGEST_NFSV3: 00149 case FSAL_DIGEST_NFSV4: 00150 fh_size = sizeof(p_in_fsal_handle->data.id) + sizeof(p_in_fsal_handle->data.ts); 00151 fh_data = (caddr_t) p_in_fsal_handle; 00152 break; 00153 00154 /* FileId digest */ 00155 case FSAL_DIGEST_FILEID2: 00156 case FSAL_DIGEST_FILEID3: 00157 case FSAL_DIGEST_FILEID4: 00158 /* XXX: does fh_desc need to be padded to FSAL_DIGEST_SIZE_FILEID{2,3,4} ? 00159 * or is setting fh_size = sizeof(ino_t) sufficient? */ 00160 fh_size = sizeof(p_in_fsal_handle->data.info.inode); 00161 fh_data = (caddr_t) &p_in_fsal_handle->data.info.inode; 00162 break; 00163 00164 /* Nodetype digest. */ 00165 case FSAL_DIGEST_NODETYPE: 00166 /* XXX: should fh_desc be padded to FSAL_DIGEST_SIZE_NODETYPE ? */ 00167 fh_size = sizeof(p_in_fsal_handle->data.info.ftype); 00168 fh_data = (caddr_t) &p_in_fsal_handle->data.info.ftype; 00169 break; 00170 00171 default: 00172 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00173 } 00174 00175 if(fh_desc->len < fh_size) 00176 { 00177 LogMajor( COMPONENT_FSAL, "POSIX DigestHandle: too small for handle. need %lu, have %lu", 00178 fh_size, fh_desc->len); 00179 ReturnCode(ERR_FSAL_TOOSMALL, 0); 00180 } 00181 00182 memcpy(fh_desc->start, fh_data, fh_size); 00183 fh_desc->len = fh_size; 00184 00185 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00186 } 00187 00201 fsal_status_t POSIXFSAL_ExpandHandle(fsal_export_context_t * expcontext, /* IN */ 00202 fsal_digesttype_t in_type, /* IN */ 00203 struct fsal_handle_desc *fh_desc /* IN/OUT */ 00204 ) 00205 { 00206 posixfsal_export_context_t * p_expcontext 00207 = (posixfsal_export_context_t *) expcontext; 00208 00209 /* sanity checks */ 00210 if(!fh_desc || !fh_desc->start || !p_expcontext) 00211 ReturnCode(ERR_FSAL_FAULT, 0); 00212 00213 size_t fh_size = sizeof(fsal_u64_t) + sizeof(int); 00214 if (in_type == FSAL_DIGEST_NFSV2 && fh_desc->len < fh_size) 00215 { 00216 LogMajor(COMPONENT_FSAL, 00217 "POSIX ExpandHandle: V2 size too small for handle. should be %lu, got %lu", 00218 fh_size, fh_desc->len); 00219 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00220 } 00221 else if (in_type != FSAL_DIGEST_SIZEOF && fh_desc->len != fh_size) 00222 { 00223 LogMajor(COMPONENT_FSAL, 00224 "POSIX ExpandHandle: size mismatch for handle. should be %lu, got %lu", 00225 fh_size, fh_desc->len); 00226 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00227 } 00228 00229 fh_desc->len = fh_size; /* pass back the actual size */ 00230 00231 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00232 } 00233 00242 fsal_status_t POSIXFSAL_SetDefault_FS_specific_parameter(fsal_parameter_t * out_parameter) 00243 { 00244 posixfs_specific_initinfo_t * p_init_info; 00245 00246 /* defensive programming... */ 00247 if(out_parameter == NULL) 00248 ReturnCode(ERR_FSAL_FAULT, 0); 00249 00250 /* set default values for all parameters of fs_specific_info */ 00251 p_init_info = (posixfs_specific_initinfo_t *)&out_parameter->fs_specific_info; 00252 00253 #ifdef _USE_PGSQL 00254 00255 /* pgsql db */ 00256 strcpy(p_init_info->dbparams.host, "localhost"); 00257 strcpy(p_init_info->dbparams.port, "5432"); 00258 p_init_info->dbparams.dbname[0] = '\0'; 00259 p_init_info->dbparams.login[0] = '\0'; 00260 p_init_info->dbparams.passwdfile[0] = '\0'; 00261 00262 #elif defined(_USE_MYSQL) 00263 00264 strcpy(p_init_info->dbparams.host, "localhost"); 00265 strcpy(p_init_info->dbparams.port, ""); 00266 p_init_info->dbparams.dbname[0] = '\0'; 00267 p_init_info->dbparams.login[0] = '\0'; 00268 p_init_info->dbparams.passwdfile[0] = '\0'; 00269 00270 #endif 00271 00272 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00273 00274 } 00275 00297 /* load FSAL init info */ 00298 00299 fsal_status_t POSIXFSAL_load_FS_specific_parameter_from_conf(config_file_t in_config, 00300 fsal_parameter_t * 00301 out_parameter) 00302 { 00303 posixfs_specific_initinfo_t * p_init_info; 00304 int err; 00305 int var_max, var_index; 00306 char *key_name; 00307 char *key_value; 00308 config_item_t block; 00309 00310 /* defensive programming... */ 00311 if(out_parameter == NULL) 00312 ReturnCode(ERR_FSAL_FAULT, 0); 00313 00314 /* set default values for all parameters of fs_specific_info */ 00315 p_init_info = (posixfs_specific_initinfo_t *)&out_parameter->fs_specific_info; 00316 00317 block = config_FindItemByName(in_config, CONF_LABEL_FS_SPECIFIC); 00318 00319 /* cannot read item */ 00320 if(block == NULL) 00321 { 00322 LogCrit(COMPONENT_CONFIG, "FSAL LOAD PARAMETER: Cannot read item \"%s\" from configuration file", 00323 CONF_LABEL_FS_SPECIFIC); 00324 ReturnCode(ERR_FSAL_NOENT, 0); 00325 } 00326 else if(config_ItemType(block) != CONFIG_ITEM_BLOCK) 00327 { 00328 LogCrit(COMPONENT_CONFIG, "FSAL LOAD PARAMETER: Item \"%s\" is expected to be a block", 00329 CONF_LABEL_FS_SPECIFIC); 00330 ReturnCode(ERR_FSAL_INVAL, 0); 00331 } 00332 00333 var_max = config_GetNbItems(block); 00334 00335 for(var_index = 0; var_index < var_max; var_index++) 00336 { 00337 config_item_t item; 00338 00339 item = config_GetItemByIndex(block, var_index); 00340 00341 err = config_GetKeyValue(item, &key_name, &key_value); 00342 if(err) 00343 { 00344 LogCrit(COMPONENT_CONFIG, 00345 "FSAL LOAD PARAMETER: ERROR reading key[%d] from section \"%s\" of configuration file.", 00346 var_index, CONF_LABEL_FS_SPECIFIC); 00347 ReturnCode(ERR_FSAL_SERVERFAULT, err); 00348 } 00349 /* does the variable exists ? */ 00350 if(!STRCMP(key_name, "DB_Host")) 00351 { 00352 strncpy(p_init_info->dbparams.host, 00353 key_value, FSAL_MAX_DBHOST_NAME_LEN); 00354 } 00355 else if(!STRCMP(key_name, "DB_Port")) 00356 { 00357 int port; 00358 port = atoi(key_value); /* XXX: replace atoi by my_atoi ?! */ 00359 if(port <= 0 || port > USHRT_MAX) 00360 { 00361 LogCrit(COMPONENT_CONFIG, 00362 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: positive integer (< %i) expected.", 00363 key_name, USHRT_MAX); 00364 ReturnCode(ERR_FSAL_INVAL, 0); 00365 } 00366 strncpy(p_init_info->dbparams.port, 00367 key_value, FSAL_MAX_DBPORT_STR_LEN); 00368 } 00369 else if(!STRCMP(key_name, "DB_Name")) 00370 { 00371 strncpy(p_init_info->dbparams.dbname, 00372 key_value, FSAL_MAX_DB_NAME_LEN); 00373 } 00374 else if(!STRCMP(key_name, "DB_Login")) 00375 { 00376 strncpy(p_init_info->dbparams.login, 00377 key_value, FSAL_MAX_DB_LOGIN_LEN); 00378 } 00379 else if(!STRCMP(key_name, "DB_keytab")) 00380 { 00381 strncpy(p_init_info->dbparams.passwdfile, 00382 key_value, FSAL_MAX_PATH_LEN); 00383 } 00384 else 00385 { 00386 LogCrit(COMPONENT_CONFIG, 00387 "FSAL LOAD PARAMETER: ERROR: Unknown or unsettable key: %s (item %s)", 00388 key_name, CONF_LABEL_FS_SPECIFIC); 00389 ReturnCode(ERR_FSAL_INVAL, 0); 00390 } 00391 } 00392 00393 if(p_init_info->dbparams.host[0] == '\0' 00394 || p_init_info->dbparams.dbname[0] == '\0') 00395 { 00396 LogCrit(COMPONENT_CONFIG, 00397 "FSAL LOAD PARAMETER: DB_Host and DB_Name MUST be specified in the configuration file"); 00398 ReturnCode(ERR_FSAL_NOENT, 0); 00399 } 00400 00401 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00402 00403 } /* FSAL_load_FS_specific_parameter_from_conf */