nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright (C) 2010 The Linux Box, Inc. 00005 * Contributor : Adam C. Emerson <aemerson@linuxbox.com> 00006 * 00007 * Portions copyright CEA/DAM/DIF (2008) 00008 * contributeur : Philippe DENIEL philippe.deniel@cea.fr 00009 * Thomas LEIBOVICI thomas.leibovici@cea.fr 00010 * 00011 * 00012 * This program is free software; you can redistribute it and/or 00013 * modify it under the terms of the GNU Lesser General Public 00014 * License as published by the Free Software Foundation; either 00015 * version 3 of the License, or (at your option) any later version. 00016 * 00017 * This program is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00020 * Lesser General Public License for more details. 00021 * 00022 * You should have received a copy of the GNU Lesser General Public 00023 * License along with this library; if not, write to the Free Software 00024 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00025 * 00026 * ------------- 00027 */ 00028 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 #define low32m( a ) ( (unsigned int)a ) 00047 00048 char *CEPHFSAL_GetFSName() 00049 { 00050 return "CEPH"; 00051 } 00052 00067 int 00068 CEPHFSAL_handlecmp(fsal_handle_t *exthandle1, 00069 fsal_handle_t *exthandle2, 00070 fsal_status_t *status) 00071 { 00072 cephfsal_handle_t *handle1 = (cephfsal_handle_t *)exthandle1; 00073 cephfsal_handle_t *handle2 = (cephfsal_handle_t *)exthandle2; 00074 *status = FSAL_STATUS_NO_ERROR; 00075 00076 if (!handle1 || !handle2) { 00077 status->major = ERR_FSAL_FAULT; 00078 return -1; 00079 } 00080 00081 if ((VINODE(handle1).ino.val == VINODE(handle2).ino.val) && 00082 (VINODE(handle1).snapid.val == VINODE(handle2).snapid.val)) { 00083 return 0; 00084 } else { 00085 return 1; 00086 } 00087 } 00088 00104 unsigned int 00105 CEPHFSAL_Handle_to_HashIndex(fsal_handle_t *exthandle, 00106 unsigned int cookie, 00107 unsigned int alphabet_len, 00108 unsigned int index_size) 00109 { 00110 cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle; 00111 00112 return (unsigned int) 00113 ((VINODE(handle).ino.val + VINODE(handle).snapid.val) % 00114 index_size); 00115 } 00116 00130 unsigned int 00131 CEPHFSAL_Handle_to_RBTIndex(fsal_handle_t *exthandle, 00132 unsigned int cookie) 00133 { 00134 cephfsal_handle_t* handle = (cephfsal_handle_t *)exthandle; 00135 return (unsigned int)(0xABCD1234 ^ VINODE(handle).ino.val ^ 00136 VINODE(handle).snapid.val ^ cookie); 00137 } 00138 00153 fsal_status_t 00154 CEPHFSAL_DigestHandle(fsal_export_context_t *extexport, 00155 fsal_digesttype_t output_type, 00156 fsal_handle_t *exthandle, 00157 struct fsal_handle_desc *fh_desc) 00158 { 00159 cephfsal_handle_t *handle = (cephfsal_handle_t *)exthandle; 00160 size_t fh_len = 0; 00161 void *fh_data = NULL; 00162 00163 fh_len = sizeof(handle->data); 00164 fh_data = &handle->data; 00165 00166 switch (output_type) { 00167 /* Digested Handles */ 00168 case FSAL_DIGEST_NFSV2: 00169 case FSAL_DIGEST_NFSV3: 00170 case FSAL_DIGEST_NFSV4: 00171 if (fh_desc->len < fh_len) { 00172 LogMajor(COMPONENT_FSAL, 00173 "Ceph DigestHandle: space too small for handle. " 00174 "Need %zu, have %zu", fh_len, fh_desc->len); 00175 ReturnCode(ERR_FSAL_TOOSMALL, 0); 00176 } else { 00177 memcpy(fh_desc->start, fh_data, 00178 fh_len); 00179 fh_desc->len = fh_len; 00180 } 00181 break; 00182 00183 /* Integer IDs */ 00184 00185 case FSAL_DIGEST_FILEID2: 00186 memcpy(fh_desc->start, &VINODE(handle), FSAL_DIGEST_SIZE_FILEID2); 00187 fh_desc->len = FSAL_DIGEST_SIZE_FILEID2; 00188 break; 00189 case FSAL_DIGEST_FILEID3: 00190 memcpy(fh_desc->start, &VINODE(handle).ino.val, 00191 FSAL_DIGEST_SIZE_FILEID3); 00192 fh_desc->len = FSAL_DIGEST_SIZE_FILEID3; 00193 break; 00194 case FSAL_DIGEST_FILEID4: 00195 memcpy(fh_desc->start, &VINODE(handle).ino.val, 00196 FSAL_DIGEST_SIZE_FILEID4); 00197 fh_desc->len = FSAL_DIGEST_SIZE_FILEID4; 00198 break; 00199 00200 default: 00201 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00202 } 00203 00204 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00205 } /* FSAL_DigestHandle */ 00206 00222 fsal_status_t 00223 CEPHFSAL_ExpandHandle(fsal_export_context_t *extexport, 00224 fsal_digesttype_t in_type, 00225 struct fsal_handle_desc *fh_desc) 00226 { 00227 cephfsal_handle_t* handle = (cephfsal_handle_t*) fh_desc->start; 00228 cephfsal_export_context_t* export = (cephfsal_export_context_t*)extexport; 00229 struct ceph_mount_info *cmount = export->cmount; 00230 int rc = 0; 00231 00232 if (in_type != FSAL_DIGEST_SIZEOF) { 00233 if (fh_desc->len != sizeof(handle->data)) { 00234 LogMajor(COMPONENT_FSAL, 00235 "VFS ExpandHandle: size mismatch. " 00236 "should be %zu, got %zu", 00237 sizeof(VINODE(handle)), fh_desc->len); 00238 ReturnCode(ERR_FSAL_SERVERFAULT, 0); 00239 } 00240 00241 #ifdef _PNFS 00242 if (handle->data.layout.fl_stripe_unit == 0) { 00243 rc = ceph_ll_connectable_m(cmount, &VINODE(handle), 00244 handle->data.parent_ino, 00245 handle->data.parent_hash); 00246 if (rc < 0) { 00247 ReturnCode(posix2fsal_error(rc), 0); 00248 } 00249 } 00250 #else /* !_PNFS */ 00251 rc = ceph_ll_connectable_m(cmount, &VINODE(handle), 00252 handle->data.parent_ino, 00253 handle->data.parent_hash); 00254 if (rc < 0) { 00255 ReturnCode(posix2fsal_error(rc), 0); 00256 } 00257 #endif /* !_PNFS */ 00258 } else { 00259 fh_desc->len = sizeof(handle->data); 00260 } 00261 00262 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00263 } 00264 00272 fsal_status_t CEPHFSAL_SetDefault_FSAL_parameter(fsal_parameter_t * out_parameter) 00273 { 00274 /* defensive programming... */ 00275 if(out_parameter == NULL) 00276 ReturnCode(ERR_FSAL_FAULT, 0); 00277 00278 /* init max FS calls = unlimited */ 00279 out_parameter->fsal_info.max_fs_calls = 0; 00280 00281 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00282 } 00283 00284 fsal_status_t CEPHFSAL_SetDefault_FS_common_parameter(fsal_parameter_t * out_parameter) 00285 { 00286 /* defensive programming... */ 00287 if(out_parameter == NULL) 00288 ReturnCode(ERR_FSAL_FAULT, 0); 00289 00290 /* set default values for all parameters of fs_common_info */ 00291 00292 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, maxfilesize); 00293 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, maxlink); 00294 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, maxnamelen); 00295 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, maxpathlen); 00296 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, no_trunc); 00297 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, chown_restricted); 00298 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, case_insensitive); 00299 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, case_preserving); 00300 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, fh_expire_type); 00301 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, link_support); 00302 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, symlink_support); 00303 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, named_attr); 00304 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, unique_handles); 00305 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, lease_time); 00306 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, acl_support); 00307 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, cansettime); 00308 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, homogenous); 00309 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, supported_attrs); 00310 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, maxread); 00311 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, maxwrite); 00312 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, umask); 00313 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, auth_exportpath_xdev); 00314 FSAL_SET_INIT_DEFAULT(out_parameter->fs_common_info, xattr_access_rights); 00315 00316 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00317 00318 } 00319 00320 fsal_status_t CEPHFSAL_SetDefault_FS_specific_parameter(fsal_parameter_t * out_parameter) 00321 { 00322 /* defensive programming... */ 00323 if(out_parameter == NULL) 00324 ReturnCode(ERR_FSAL_FAULT, 0); 00325 00326 strcpy(&((cephfs_specific_initinfo_t) 00327 out_parameter->fs_specific_info).cephserver[0], "localhost"); 00328 00329 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00330 } 00331 00353 /* load FSAL init info */ 00354 00355 fsal_status_t CEPHFSAL_load_FSAL_parameter_from_conf(config_file_t in_config, 00356 fsal_parameter_t * out_parameter) 00357 { 00358 int err; 00359 int var_max, var_index; 00360 char *key_name; 00361 char *key_value; 00362 config_item_t block; 00363 00364 int DebugLevel = -1; 00365 00366 block = config_FindItemByName(in_config, CONF_LABEL_FSAL); 00367 00368 /* cannot read item */ 00369 00370 if(block == NULL) 00371 ReturnCode(ERR_FSAL_NOENT, 0); 00372 else if(config_ItemType(block) != CONFIG_ITEM_BLOCK) 00373 ReturnCode(ERR_FSAL_INVAL, 0); 00374 00375 /* read variable for fsal init */ 00376 00377 var_max = config_GetNbItems(block); 00378 00379 for(var_index = 0; var_index < var_max; var_index++) 00380 { 00381 config_item_t item; 00382 00383 item = config_GetItemByIndex(block, var_index); 00384 00385 err = config_GetKeyValue(item, &key_name, &key_value); 00386 if(err) 00387 { 00388 ReturnCode(ERR_FSAL_SERVERFAULT, err); 00389 } 00390 00391 if(!STRCMP(key_name, "DebugLevel")) 00392 { 00393 DebugLevel = ReturnLevelAscii(key_value); 00394 00395 if(DebugLevel == -1) 00396 { 00397 ReturnCode(ERR_FSAL_INVAL, -1); 00398 } 00399 00400 } 00401 else if(!STRCMP(key_name, "Max_FS_calls")) 00402 { 00403 00404 int maxcalls = s_read_int(key_value); 00405 00406 if(maxcalls < 0) 00407 { 00408 ReturnCode(ERR_FSAL_INVAL, 0); 00409 } 00410 00411 out_parameter->fsal_info.max_fs_calls = (unsigned int)maxcalls; 00412 00413 } 00414 else 00415 { 00416 ReturnCode(ERR_FSAL_INVAL, 0); 00417 } 00418 00419 } 00420 00421 00422 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00423 00424 } /* FSAL_load_FSAL_parameter_from_conf */ 00425 00426 /* load general filesystem configuration options */ 00427 00428 fsal_status_t CEPHFSAL_load_FS_common_parameter_from_conf(config_file_t in_config, 00429 fsal_parameter_t * out_parameter) 00430 { 00431 int err; 00432 int var_max, var_index; 00433 char *key_name; 00434 char *key_value; 00435 config_item_t block; 00436 00437 block = config_FindItemByName(in_config, CONF_LABEL_FS_COMMON); 00438 00439 /* cannot read item */ 00440 if(block == NULL) 00441 { 00442 LogCrit(COMPONENT_CONFIG, 00443 "FSAL LOAD PARAMETER: Cannot read item \"%s\" from configuration file", 00444 CONF_LABEL_FS_COMMON); 00445 ReturnCode(ERR_FSAL_NOENT, 0); 00446 } 00447 else if(config_ItemType(block) != CONFIG_ITEM_BLOCK) 00448 { 00449 LogCrit(COMPONENT_CONFIG, 00450 "FSAL LOAD PARAMETER: Item \"%s\" is expected to be a block", 00451 CONF_LABEL_FS_COMMON); 00452 ReturnCode(ERR_FSAL_INVAL, 0); 00453 } 00454 00455 /* 00456 configurable common info for filesystem are: 00457 link_support # hardlink support 00458 symlink_support # symlinks support 00459 cansettime # Is it possible to change file times 00460 maxread # Max read size from FS 00461 maxwrite # Max write size to FS 00462 umask 00463 auth_exportpath_xdev 00464 xattr_access_rights 00465 pnfs_supported 00466 */ 00467 00468 var_max = config_GetNbItems(block); 00469 00470 for(var_index = 0; var_index < var_max; var_index++) 00471 { 00472 config_item_t item; 00473 00474 item = config_GetItemByIndex(block, var_index); 00475 00476 err = config_GetKeyValue(item, &key_name, &key_value); 00477 if(err) 00478 { 00479 LogCrit(COMPONENT_CONFIG, 00480 "FSAL LOAD PARAMETER: ERROR reading key[%d] from section \"%s\" of configuration file.", 00481 var_index, CONF_LABEL_FS_COMMON); 00482 ReturnCode(ERR_FSAL_SERVERFAULT, err); 00483 } 00484 00485 /* does the variable exists ? */ 00486 if(!STRCMP(key_name, "link_support")) 00487 { 00488 00489 int boolv = StrToBoolean(key_value); 00490 00491 if(boolv == -1) 00492 { 00493 LogCrit(COMPONENT_CONFIG, 00494 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: 0 or 1 expected.", 00495 key_name); 00496 ReturnCode(ERR_FSAL_INVAL, 0); 00497 } 00498 00499 /* if set to false, force value to false. 00500 * else keep fs default. 00501 */ 00502 FSAL_SET_INIT_INFO(out_parameter->fs_common_info, link_support, 00503 FSAL_INIT_MAX_LIMIT, boolv); 00504 00505 } 00506 else if(!STRCMP(key_name, "symlink_support")) 00507 { 00508 int boolv = StrToBoolean(key_value); 00509 00510 if(boolv == -1) 00511 { 00512 LogCrit(COMPONENT_CONFIG, 00513 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: 0 or 1 expected.", 00514 key_name); 00515 ReturnCode(ERR_FSAL_INVAL, 0); 00516 } 00517 00518 /* if set to false, force value to false. 00519 * else keep fs default. 00520 */ 00521 FSAL_SET_INIT_INFO(out_parameter->fs_common_info, symlink_support, 00522 FSAL_INIT_MAX_LIMIT, boolv); 00523 } 00524 else if(!STRCMP(key_name, "cansettime")) 00525 { 00526 int boolv = StrToBoolean(key_value); 00527 00528 if(boolv == -1) 00529 { 00530 LogCrit(COMPONENT_CONFIG, 00531 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: 0 or 1 expected.", 00532 key_name); 00533 ReturnCode(ERR_FSAL_INVAL, 0); 00534 } 00535 00536 /* if set to false, force value to false. 00537 * else keep fs default. 00538 */ 00539 FSAL_SET_INIT_INFO(out_parameter->fs_common_info, cansettime, 00540 FSAL_INIT_MAX_LIMIT, boolv); 00541 00542 } 00543 else if(!STRCMP(key_name, "maxread")) 00544 { 00545 fsal_u64_t size; 00546 00547 if(s_read_int64(key_value, &size)) 00548 { 00549 LogCrit(COMPONENT_CONFIG, 00550 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: positive integer expected.", 00551 key_name); 00552 ReturnCode(ERR_FSAL_INVAL, 0); 00553 } 00554 00555 FSAL_SET_INIT_INFO(out_parameter->fs_common_info, maxread, 00556 FSAL_INIT_FORCE_VALUE, size); 00557 00558 } 00559 else if(!STRCMP(key_name, "maxwrite")) 00560 { 00561 fsal_u64_t size; 00562 00563 if(s_read_int64(key_value, &size)) 00564 { 00565 LogCrit(COMPONENT_CONFIG, 00566 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: positive integer expected.", 00567 key_name); 00568 ReturnCode(ERR_FSAL_INVAL, 0); 00569 } 00570 00571 FSAL_SET_INIT_INFO(out_parameter->fs_common_info, maxwrite, 00572 FSAL_INIT_FORCE_VALUE, size); 00573 00574 } 00575 else if(!STRCMP(key_name, "umask")) 00576 { 00577 int mode = s_read_octal(key_value); 00578 00579 if(mode < 0) 00580 { 00581 LogCrit(COMPONENT_CONFIG, 00582 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: octal expected.", 00583 key_name); 00584 ReturnCode(ERR_FSAL_INVAL, 0); 00585 } 00586 00587 FSAL_SET_INIT_INFO(out_parameter->fs_common_info, umask, 00588 FSAL_INIT_FORCE_VALUE, unix2fsal_mode(mode)); 00589 00590 } 00591 else if(!STRCMP(key_name, "auth_xdev_export")) 00592 { 00593 int boolv = StrToBoolean(key_value); 00594 00595 if(boolv == -1) 00596 { 00597 LogCrit(COMPONENT_CONFIG, 00598 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: boolean expected.", 00599 key_name); 00600 ReturnCode(ERR_FSAL_INVAL, 0); 00601 } 00602 00603 FSAL_SET_INIT_INFO(out_parameter->fs_common_info, auth_exportpath_xdev, 00604 FSAL_INIT_FORCE_VALUE, boolv); 00605 } 00606 else if(!STRCMP(key_name, "xattr_access_rights")) 00607 { 00608 int mode = s_read_octal(key_value); 00609 00610 if(mode < 0) 00611 { 00612 LogCrit(COMPONENT_CONFIG, 00613 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: octal expected.", 00614 key_name); 00615 ReturnCode(ERR_FSAL_INVAL, 0); 00616 } 00617 00618 FSAL_SET_INIT_INFO(out_parameter->fs_common_info, xattr_access_rights, 00619 FSAL_INIT_FORCE_VALUE, unix2fsal_mode(mode)); 00620 00621 } 00622 #ifdef _PNFS_MDS 00623 else if(!STRCMP(key_name, "pnfs_supported")) 00624 { 00625 int pnfs_supported = StrToBoolean(key_value); 00626 00627 if(pnfs_supported < 0) 00628 { 00629 LogCrit(COMPONENT_CONFIG, 00630 "FSAL LOAD PARAMETER: ERROR: Unexpected value for %s: boolean expected.", 00631 key_name); 00632 ReturnCode(ERR_FSAL_INVAL, 0); 00633 } 00634 00635 FSAL_SET_INIT_INFO(out_parameter->fs_common_info, 00636 pnfs_supported, 00637 FSAL_INIT_FORCE_VALUE, pnfs_supported); 00638 } 00639 #endif /* !_PNFS_MDS */ 00640 else 00641 { 00642 LogCrit(COMPONENT_CONFIG, 00643 "FSAL LOAD PARAMETER: ERROR: Unknown or unsettable key: %s (item %s)", 00644 key_name, CONF_LABEL_FS_COMMON); 00645 ReturnCode(ERR_FSAL_INVAL, 0); 00646 } 00647 } 00648 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00649 } /* FSAL_load_FS_common_parameter_from_conf */ 00650 00651 /* load specific filesystem configuration options */ 00652 00653 fsal_status_t CEPHFSAL_load_FS_specific_parameter_from_conf(config_file_t in_config, 00654 fsal_parameter_t * out_parameter) 00655 { 00656 int err; 00657 int var_max, var_index; 00658 char *key_name; 00659 char *key_value; 00660 config_item_t block; 00661 00662 block = config_FindItemByName(in_config, CONF_LABEL_FS_SPECIFIC); 00663 00664 /* cannot read item */ 00665 if(block == NULL) 00666 { 00667 ReturnCode(ERR_FSAL_NOENT, 0); 00668 } 00669 else if(config_ItemType(block) != CONFIG_ITEM_BLOCK) 00670 { 00671 ReturnCode(ERR_FSAL_INVAL, 0); 00672 } 00673 00674 /* makes an iteration on the (key, value) couplets */ 00675 00676 var_max = config_GetNbItems(block); 00677 00678 for(var_index = 0; var_index < var_max; var_index++) 00679 { 00680 config_item_t item; 00681 00682 item = config_GetItemByIndex(block, var_index); 00683 00684 err = config_GetKeyValue(item, &key_name, &key_value); 00685 if(err) 00686 { 00687 ReturnCode(ERR_FSAL_SERVERFAULT, err); 00688 } 00689 00690 /* what parameter is it ? */ 00691 00692 if(!STRCMP(key_name, "cephserver")) 00693 { 00694 strncpy(&((cephfs_specific_initinfo_t) 00695 out_parameter->fs_specific_info).cephserver[0], 00696 key_value, FSAL_MAX_NAME_LEN); 00697 } 00698 else 00699 { 00700 ReturnCode(ERR_FSAL_INVAL, 0); 00701 } 00702 00703 } 00704 00705 ReturnCode(ERR_FSAL_NO_ERROR, 0); 00706 00707 } /* FSAL_load_FS_specific_parameter_from_conf */