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_common.h" 00020 #include "fsal_convert.h" 00021 #include "config_parsing.h" 00022 #include "fsal_common.h" 00023 #include <string.h> 00024 00025 /* case unsensitivity */ 00026 #define STRCMP strcasecmp 00027 00028 char *ZFSFSAL_GetFSName() 00029 { 00030 return "ZFS"; 00031 } 00032 00049 int ZFSFSAL_handlecmp(fsal_handle_t * handle1, fsal_handle_t * handle2, 00050 fsal_status_t * status) 00051 { 00052 00053 *status = FSAL_STATUS_NO_ERROR; 00054 00055 if(!handle1 || !handle2) 00056 { 00057 status->major = ERR_FSAL_FAULT; 00058 return -1; 00059 } 00060 00061 return memcmp(handle1, handle2, sizeof(zfsfsal_handle_t)); 00062 } 00063 00078 unsigned int ZFSFSAL_Handle_to_HashIndex(fsal_handle_t * handle, 00079 unsigned int cookie, 00080 unsigned int alphabet_len, unsigned int index_size) 00081 { 00082 zfsfsal_handle_t * p_handle = (zfsfsal_handle_t *)handle; 00083 00084 /* >> here must be your implementation of your zfsfsal_handle_t hashing */ 00085 return (3 * (unsigned int)(p_handle->data.zfs_handle.inode*p_handle->data.zfs_handle.generation*(p_handle->data.i_snap+1)) + 1999 + cookie) % index_size; 00086 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 ZFSFSAL_Handle_to_RBTIndex(fsal_handle_t * handle, unsigned int cookie) 00102 { 00103 zfsfsal_handle_t * p_handle = (zfsfsal_handle_t *)handle; 00104 00105 /* >> here must be your implementation of your zfsfsal_handle_t hashing << */ 00106 return (unsigned int)(0xABCD1234 ^ (p_handle->data.zfs_handle.inode*p_handle->data.zfs_handle.generation*(p_handle->data.i_snap+1)) ^ cookie); 00107 00108 } 00109 00126 fsal_status_t ZFSFSAL_DigestHandle(fsal_export_context_t * exp_context, /* IN */ 00127 fsal_digesttype_t output_type, /* IN */ 00128 fsal_handle_t *in_fsal_handle, /* IN */ 00129 struct fsal_handle_desc *fh_desc /* IN/OUT */ ) 00130 { 00131 uint32_t ino32; 00132 zfsfsal_export_context_t * p_expcontext = (zfsfsal_export_context_t *)exp_context; 00133 zfsfsal_handle_t * p_in_fsal_handle = (zfsfsal_handle_t *)in_fsal_handle; 00134 size_t fh_size; 00135 00136 /* sanity checks */ 00137 if(!p_in_fsal_handle || !fh_desc || !fh_desc->start || !p_expcontext) 00138 ReturnCode(ERR_FSAL_FAULT, 0); 00139 00140 00141 switch (output_type) 00142 { 00143 /* NFS handle digest */ 00144 case FSAL_DIGEST_NFSV2: 00145 case FSAL_DIGEST_NFSV3: 00146 case FSAL_DIGEST_NFSV4: 00147 fh_size = sizeof(p_in_fsal_handle->data) ; 00148 if(fh_desc->len < fh_size) 00149 { 00150 LogMajor( COMPONENT_FSAL, 00151 "ZFS DigestHandle: space too small for handle. need %lu, have %lu", 00152 fh_size, fh_desc->len); 00153 ReturnCode(ERR_FSAL_TOOSMALL, 0); 00154 } 00155 memcpy(fh_desc->start, (caddr_t)p_in_fsal_handle, fh_size); 00156 fh_desc->len = fh_size; 00157 break; 00158 /* FileId digest for NFSv3 */ 00159 case FSAL_DIGEST_FILEID2: 00160 ino32 = (uint32_t)(in_fsal_handle->data.zfs_handle.inode); 00161 memset(fh_desc->start, 0, FSAL_DIGEST_SIZE_FILEID2); 00162 memcpy(fh_desc->start, &ino32, sizeof( ino32 )); 00163 fh_desc->len = FSAL_DIGEST_SIZE_FILEID2; 00164 break; 00165 00166 /* FileId digest for NFSv3 */ 00167 case FSAL_DIGEST_FILEID3: 00168 memset(fh_desc->start, 0, FSAL_DIGEST_SIZE_FILEID3); 00169 memcpy(fh_desc->start, &(p_in_fsal_handle->data.zfs_handle.inode), sizeof(fsal_u64_t)); 00170 fh_desc->len = FSAL_DIGEST_SIZE_FILEID3; 00171 break; 00172 00173 /* FileId digest for NFSv4 */ 00174 case FSAL_DIGEST_FILEID4: 00175 memset(fh_desc->start, 0, FSAL_DIGEST_SIZE_FILEID4); 00176 memcpy(fh_desc->start, &(p_in_fsal_handle->data.zfs_handle.inode), sizeof(fsal_u64_t)); 00177 fh_desc->len = FSAL_DIGEST_SIZE_FILEID4; 00178 break; 00179 00180 default: 00181 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00182 } 00183 00184 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00185 00186 } /* FSAL_DigestHandle */ 00187 00203 fsal_status_t ZFSFSAL_ExpandHandle(fsal_export_context_t * pexpcontext, /* IN not used */ 00204 fsal_digesttype_t in_type, /* IN */ 00205 struct fsal_handle_desc *fh_desc /* IN/OUT */ ) 00206 { 00207 zfsfsal_handle_t dummy_handle ; 00208 size_t fh_size; 00209 00210 /* sanity checks */ 00211 if(!fh_desc || !fh_desc->start || !pexpcontext) 00212 ReturnCode(ERR_FSAL_FAULT, 0); 00213 00214 fh_size = sizeof( dummy_handle.data ); /* All ZFS handle have the same size */ 00215 if(in_type == FSAL_DIGEST_NFSV2) 00216 { 00217 if(fh_desc->len < fh_size) 00218 { 00219 LogMajor(COMPONENT_FSAL, 00220 "ZFS ExpandHandle: V2 size too small for handle. should be %lu, got %lu", 00221 fh_size, fh_desc->len); 00222 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00223 } 00224 } 00225 else if(in_type != FSAL_DIGEST_SIZEOF && fh_desc->len != fh_size) 00226 { 00227 LogMajor(COMPONENT_FSAL, 00228 "ZFS ExpandHandle: size mismatch for handle. should be %lu, got %lu", 00229 fh_size, fh_desc->len); 00230 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00231 } 00232 fh_desc->len = fh_size; /* pass back the actual size */ 00233 00234 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00235 } 00236 00245 fsal_status_t ZFSFSAL_SetDefault_FS_specific_parameter(fsal_parameter_t * out_parameter) 00246 { 00247 /* defensive programming... */ 00248 if(out_parameter == NULL) 00249 ReturnCode(ERR_FSAL_FAULT, 0); 00250 00251 /* >> set your default FS configuration into the 00252 out_parameter->fs_specific_info structure << */ 00253 00254 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00255 00256 } 00257 00279 /* load specific filesystem configuration options */ 00280 00281 fsal_status_t ZFSFSAL_load_FS_specific_parameter_from_conf(config_file_t in_config, 00282 fsal_parameter_t * out_parameter) 00283 { 00284 int err; 00285 int var_max, var_index; 00286 char *key_name; 00287 char *key_value; 00288 config_item_t block; 00289 zfsfs_specific_initinfo_t *specific_info = 00290 (zfsfs_specific_initinfo_t *) &out_parameter->fs_specific_info; 00291 00292 block = config_FindItemByName(in_config, CONF_LABEL_FS_SPECIFIC); 00293 00294 /* cannot read item */ 00295 if(block == NULL) 00296 { 00297 LogCrit(COMPONENT_FSAL,"FSAL LOAD PARAMETER: Cannot read item \"%s\" from configuration file", 00298 CONF_LABEL_FS_SPECIFIC); 00299 ReturnCode(ERR_FSAL_NOENT, 0); 00300 } 00301 else if(config_ItemType(block) != CONFIG_ITEM_BLOCK) 00302 { 00303 LogCrit(COMPONENT_FSAL,"FSAL LOAD PARAMETER: Item \"%s\" is expected to be a block", 00304 CONF_LABEL_FS_SPECIFIC); 00305 ReturnCode(ERR_FSAL_INVAL, 0); 00306 } 00307 00308 /* makes an iteration on the (key, value) couplets */ 00309 00310 var_max = config_GetNbItems(block); 00311 00312 for(var_index = 0; var_index < var_max; var_index++) 00313 { 00314 config_item_t item; 00315 00316 item = config_GetItemByIndex(block, var_index); 00317 00318 err = config_GetKeyValue(item, &key_name, &key_value); 00319 if(err) 00320 { 00321 LogCrit(COMPONENT_FSAL, 00322 "FSAL LOAD PARAMETER: ERROR reading key[%d] from section \"%s\" of configuration file.", 00323 var_index, CONF_LABEL_FS_SPECIFIC); 00324 ReturnCode(ERR_FSAL_SERVERFAULT, err); 00325 } 00326 00327 /* what parameter is it ? */ 00328 00329 if(!STRCMP(key_name, "zpool")) 00330 strncpy(specific_info->psz_zpool, key_value, 256); 00331 else if(!STRCMP(key_name, "auto_snapshots")) 00332 specific_info->auto_snapshots = !STRCMP(key_value, "TRUE"); 00333 else if(!STRCMP(key_name, "snap_hourly_prefix")) 00334 strncpy(specific_info->psz_snap_hourly_prefix, key_value, 256); 00335 else if(!STRCMP(key_name, "snap_hourly_time")) 00336 specific_info->snap_hourly_time = atoi(key_value); 00337 else if(!STRCMP(key_name, "snap_hourly_number")) 00338 specific_info->snap_hourly_number = atoi(key_value); 00339 else if(!STRCMP(key_name, "snap_daily_prefix")) 00340 strncpy(specific_info->psz_snap_daily_prefix, key_value, 256); 00341 else if(!STRCMP(key_name, "snap_daily_time")) 00342 specific_info->snap_daily_time = atoi(key_value); 00343 else if(!STRCMP(key_name, "snap_daily_number")) 00344 specific_info->snap_daily_number = atoi(key_value); 00345 else 00346 { 00347 LogCrit(COMPONENT_FSAL, 00348 "FSAL LOAD PARAMETER: ERROR: Unknown or unsettable key: %s (item %s)", 00349 key_name, CONF_LABEL_FS_SPECIFIC); 00350 ReturnCode(ERR_FSAL_INVAL, 0); 00351 } 00352 00353 } 00354 00355 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00356 00357 } /* FSAL_load_FS_specific_parameter_from_conf */