/* * Convert a buffer descriptor to an fsal path. */ fsal_status_t dpmfsal_buffdesc2path(fsal_buffdesc_t * in_buf, fsal_path_t * out_path) { if (!in_buf || !out_path) ReturnCode(ERR_FSAL_FAULT, 0); return FSAL_str2path(in_buf->pointer, in_buf->len, out_path); }
fsal_status_t SNMPFSAL_readlink(snmpfsal_handle_t * linkhandle, /* IN */ snmpfsal_op_context_t * p_context, /* IN */ fsal_path_t * p_link_content, /* OUT */ fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */ ) { int rc; fsal_status_t st; char link_content_out[FSAL_MAX_PATH_LEN]; /* sanity checks. * note : link_attributes is optional. */ if(!linkhandle || !p_context || !p_link_content) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink); TakeTokenFSCall(); /* >> call your filesystem readlink function << */ ReleaseTokenFSCall(); /* >> convert error code and return on error << */ /* >> convert fs output to fsal_path_t * for example, if this is a char * (link_content_out) : */ st = FSAL_str2path(link_content_out, FSAL_MAX_PATH_LEN, p_link_content); if(FSAL_IS_ERROR(st)) Return(st.major, st.minor, INDEX_FSAL_readlink); /* retrieves object attributes, if asked */ if(link_attributes) { fsal_status_t status; status = SNMPFSAL_getattrs(linkhandle, p_context, link_attributes); /* On error, we set a flag in the returned attributes */ if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(link_attributes->asked_attributes); FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink); }
fsal_status_t ZFSFSAL_readlink(zfsfsal_handle_t * linkhandle, /* IN */ zfsfsal_op_context_t * p_context, /* IN */ fsal_path_t * p_link_content, /* OUT */ fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */ ) { int rc; fsal_status_t st; char link_content_out[FSAL_MAX_PATH_LEN]; /* sanity checks. * note : link_attributes is optional. */ if(!linkhandle || !p_context || !p_link_content) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink); TakeTokenFSCall(); rc = libzfswrap_readlink(p_context->export_context->p_vfs, &p_context->user_credential.cred, linkhandle->data.zfs_handle, link_content_out, sizeof(link_content_out)); ReleaseTokenFSCall(); /* >> convert error code and return on error << */ /* >> convert fs output to fsal_path_t * for example, if this is a char * (link_content_out) : */ st = FSAL_str2path(link_content_out, FSAL_MAX_PATH_LEN, p_link_content); if(FSAL_IS_ERROR(st)) Return(st.major, st.minor, INDEX_FSAL_readlink); /* retrieves object attributes, if asked */ if(link_attributes) { fsal_status_t status; status = ZFSFSAL_getattrs(linkhandle, p_context, link_attributes); /* On error, we set a flag in the returned attributes */ if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(link_attributes->asked_attributes); FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink); }
int fsal_internal_proxy_fsal_utf8_2_path(fsal_path_t * ppath, utf8string * utf8str) { char tmpstr[FSAL_MAX_PATH_LEN]; fsal_status_t fsal_status; if(ppath == NULL || utf8str == NULL) return FALSE; if(utf82str(tmpstr, sizeof(tmpstr), utf8str) == -1) return FALSE; fsal_status = FSAL_str2path(tmpstr, FSAL_MAX_PATH_LEN, ppath); if(fsal_status.major != ERR_FSAL_NO_ERROR) return FALSE; return TRUE; } /* fsal_internal_proxy_fsal_utf8_2_path */
int main(int argc, char **argv) { char localmachine[256]; char *test; fsal_parameter_t init_param; fsal_status_t st; uid_t uid; fsal_export_context_t export_ctx; fsal_op_context_t op_ctx; fsal_handle_t root_handle, handle; fsal_name_t name; fsal_path_t path; fsal_attrib_list_t attribs; fsal_attrib_mask_t mask; char tracebuff[256]; if(argc < 2) { usage(); exit(-1); } test = argv[1]; /* retrieving params */ #ifndef _NO_BUDDY_SYSTEM BuddyInit(NULL); #endif /* init debug */ SetNamePgm("test_fsal"); SetDefaultLogging("TEST"); SetNameFunction("main"); InitLogging(); /* Obtention du nom de la machine */ if(gethostname(localmachine, sizeof(localmachine)) != 0) { LogError(COMPONENT_STDOUT,ERR_SYS, ERR_GETHOSTNAME, errno); exit(1); } else SetNameHost(localmachine); AddFamilyError(ERR_FSAL, "FSAL related Errors", tab_errstatus_FSAL); /* prepare fsal_init */ /* 1 - fs specific info */ #ifdef _USE_HPSS_51 init_param.fs_specific_info.behaviors.PrincipalName = FSAL_INIT_FORCE_VALUE; strcpy(init_param.fs_specific_info.hpss_config.PrincipalName, "hpss_nfs"); init_param.fs_specific_info.behaviors.KeytabPath = FSAL_INIT_FORCE_VALUE; strcpy(init_param.fs_specific_info.hpss_config.KeytabPath, "/krb5/hpssserver.keytab"); #elif defined _USE_HPSS_62 init_param.fs_specific_info.behaviors.AuthnMech = FSAL_INIT_FORCE_VALUE; init_param.fs_specific_info.hpss_config.AuthnMech = hpss_authn_mech_krb5; init_param.fs_specific_info.behaviors.Principal = FSAL_INIT_FORCE_VALUE; strcpy(init_param.fs_specific_info.Principal, "hpssfs"); init_param.fs_specific_info.behaviors.KeytabPath = FSAL_INIT_FORCE_VALUE; strcpy(init_param.fs_specific_info.KeytabPath, "/var/hpss/etc/hpss.keytab"); #endif /* 2-common info (default) */ FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxfilesize); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxlink); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxnamelen); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxpathlen); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, no_trunc); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, chown_restricted); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, case_insensitive); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, case_preserving); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, fh_expire_type); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, link_support); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, symlink_support); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, named_attr); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, unique_handles); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, lease_time); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, acl_support); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, cansettime); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, homogenous); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, supported_attrs); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxread); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxwrite); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, umask); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, auth_exportpath_xdev); /* 3- fsal info */ init_param.fsal_info.max_fs_calls = 0; /* Init */ if(FSAL_IS_ERROR(st = FSAL_Init(&init_param))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } /* getting creds */ uid = getuid(); LogTest("uid = %d", uid); st = FSAL_BuildExportContext(&export_ctx, NULL, NULL); if(FSAL_IS_ERROR(st)) LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); st = FSAL_InitClientContext(&op_ctx); if(FSAL_IS_ERROR(st)) LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); st = FSAL_GetClientContext(&op_ctx, &export_ctx, uid, -1, NULL, 0); if(FSAL_IS_ERROR(st)) LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); /* getting root handle */ if(FSAL_IS_ERROR(st = FSAL_lookup(NULL, NULL, &op_ctx, &root_handle, NULL))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } snprintHandle(tracebuff, 256, &root_handle); LogTest("Root handle = %s", tracebuff); /* getting what are the supported attributes */ attribs.asked_attributes = 0; FSAL_SET_MASK(attribs.asked_attributes, FSAL_ATTR_SUPPATTR); LogTest("asked attributes :"); printmask(attribs.asked_attributes); if(FSAL_IS_ERROR(st = ZFSFSAL_getattrs(&root_handle, &op_ctx, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } LogTest("supported attributes :"); printmask(attribs.supported_attributes); mask = attribs.supported_attributes; /* TEST 1 */ if(test[0] == '1') { attribs.asked_attributes = 0; FSAL_SET_MASK(attribs.asked_attributes, FSAL_ATTR_SUPPATTR); LogTest("asked attributes :"); printmask(attribs.asked_attributes); if(FSAL_IS_ERROR(st = ZFSFSAL_getattrs(&root_handle, &op_ctx, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } LogTest("supported attributes :"); /* getting all spported attributes of root */ attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = ZFSFSAL_getattrs(&root_handle, &op_ctx, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } printattributes(attribs); } else /* TEST 2 */ if(test[0] == '2') { /* getting handle and attributes for subdirectory "OSF1_V5" */ if(FSAL_IS_ERROR(st = FSAL_str2name("cea", 4, &name))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_lookup(&root_handle, &name, &op_ctx, &handle, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } snprintHandle(tracebuff, 256, &handle); LogTest("/cea handle = %s", tracebuff); /* displaying attributes */ printattributes(attribs); /* getting handle and attributes for subdirectory "bin" */ if(FSAL_IS_ERROR(st = FSAL_str2name("prot", 5, &name))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } root_handle = handle; attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_lookup(&root_handle, &name, &op_ctx, &handle, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } snprintHandle(tracebuff, 256, &handle); LogTest("/cea/prot handle = %s", tracebuff); /* displaying attributes */ printattributes(attribs); /* getting handle and attributes for symlink "AglaePwrSW" */ if(FSAL_IS_ERROR(st = FSAL_str2name("lama", 5, &name))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } root_handle = handle; attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_lookup(&root_handle, &name, &op_ctx, &handle, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } snprintHandle(tracebuff, 256, &handle); LogTest("/cea/prot/lama handle = %s", tracebuff); /* displaying attributes */ printattributes(attribs); } else /* TEST 3 */ if(test[0] == '3') { /* lookup root */ if(FSAL_IS_ERROR(st = FSAL_str2path("/", 30, &path))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_lookupPath(&path, &op_ctx, &handle, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } snprintHandle(tracebuff, 256, &handle); LogTest("/ handle = %s", tracebuff); /* displaying attributes */ printattributes(attribs); /* lookup path */ if(FSAL_IS_ERROR(st = FSAL_str2path("/cea/prot/lama", 15, &path))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_lookupPath(&path, &op_ctx, &handle, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } snprintHandle(tracebuff, 256, &handle); LogTest("/cea/prot/lama handle = %s", tracebuff); /* displaying attributes */ printattributes(attribs); } else /* TEST 4 */ if(test[0] == '4') { /* readdir on root */ fsal_dir_t dir; fsal_cookie_t from, to; fsal_dirent_t entries[READDIR_SIZE]; fsal_count_t number; fsal_boolean_t eod = FALSE; int error = FALSE; attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_opendir(&root_handle, &op_ctx, &dir, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } LogTest("'/' attributes :"); /* displaying attributes */ printattributes(attribs); from = FSAL_READDIR_FROM_BEGINNING; while(!error && !eod) { unsigned int i; char cookiebuff[256]; snprintCookie(cookiebuff, 256, &from); LogTest("\nReaddir cookie = %s", cookiebuff); if(FSAL_IS_ERROR(st = FSAL_readdir(&dir, from, mask, READDIR_SIZE * sizeof(fsal_dirent_t), entries, &to, &number, &eod))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); error = TRUE; } for(i = 0; (!error) && (i < number); i++) { snprintHandle(tracebuff, 256, &entries[i].handle); snprintCookie(cookiebuff, 256, &entries[i].cookie); LogTest("\t%s : %s (cookie %s)", tracebuff, entries[i].name.name, cookiebuff); } /* preparing next call */ from = to; } LogTest("Fin de boucle : error=%d ; eod=%d", error, eod); } else /* TEST 5 */ if(test[0] == '5') { /* readdir on root */ fsal_dir_t dir; fsal_cookie_t from, to; fsal_dirent_t entries[READDIR_SIZE]; fsal_count_t number; fsal_boolean_t eod = FALSE; int error = FALSE; attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_opendir(&root_handle, &op_ctx, &dir, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } LogTest("'/' attributes :"); /* displaying attributes */ printattributes(attribs); from = FSAL_READDIR_FROM_BEGINNING; while(!error && !eod) { fsal_dirent_t *curr; char cookiebuff[256]; snprintCookie(cookiebuff, 256, &from); LogTest("\nReaddir cookie = %s", cookiebuff); if(FSAL_IS_ERROR(st = FSAL_readdir(&dir, from, mask, READDIR_SIZE * sizeof(fsal_dirent_t), entries, &to, &number, &eod))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); error = TRUE; } if(number > 0) { curr = entries; do { snprintHandle(tracebuff, 256, &curr->handle); snprintCookie(cookiebuff, 256, &curr->cookie); LogTest("\t%s : %s (cookie %s)", tracebuff, curr->name.name, cookiebuff); } while(curr = curr->nextentry); } /* preparing next call */ from = to; } LogTest("Fin de boucle : error=%d ; eod=%d", error, eod); } else /* TEST 6 */ if(test[0] == '6') { /* readdir on root */ fsal_dir_t dir; fsal_cookie_t from, to; fsal_dirent_t entries[READDIR_SIZE]; fsal_count_t number; fsal_boolean_t eod = FALSE; int error = FALSE; attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_opendir(&root_handle, &op_ctx, &dir, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } LogTest("'/' attributes :"); /* displaying attributes */ printattributes(attribs); from = FSAL_READDIR_FROM_BEGINNING; while(!error && !eod) { unsigned int i; snprintCookie(tracebuff, 256, &from); LogTest("\nReaddir cookie = %s", tracebuff); st = FSAL_readdir(&dir, from, mask, READDIR_SIZE * sizeof(fsal_dirent_t), entries, &to, &number, &eod); if(FSAL_IS_ERROR(st)) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); error = TRUE; } /* for each entry, we compare the result of FSAL_access * to FSAL_test_access. */ for(i = 0; (!error) && (i < number); i++) { fsal_status_t st1, st2; char cookiebuff[256]; snprintHandle(tracebuff, 256, &entries[i].handle); snprintCookie(cookiebuff, 256, &entries[i].cookie); LogTest("\t%s : %s (cookie %s)", tracebuff, entries[i].name.name, cookiebuff); if(FSAL_IS_ERROR(st = ZFSFSAL_getattrs(&entries[i].handle, &op_ctx, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } /* 1 - test R access */ st1 = FSAL_access(&entries[i].handle, &op_ctx, FSAL_R_OK, NULL); st2 = FSAL_test_access(&op_ctx, FSAL_R_OK, &attribs); LogError(COMPONENT_STDOUT, ERR_FSAL, st1.major, st1.minor); LogError(COMPONENT_STDOUT, ERR_FSAL, st2.major, st2.minor); if(st1.major != st2.major) { LogTest ("Error : different access permissions given by FSAL_access and FSAL_test_access : %d <>%d", st1.major, st2.major); } /* 2 - test W access */ st1 = FSAL_access(&entries[i].handle, &op_ctx, FSAL_W_OK, NULL); st2 = FSAL_test_access(&op_ctx, FSAL_W_OK, &attribs); LogError(COMPONENT_STDOUT, ERR_FSAL, st1.major, st1.minor); LogError(COMPONENT_STDOUT, ERR_FSAL, st2.major, st2.minor); if(st1.major != st2.major) { LogTest ("Error : different access permissions given by FSAL_access and FSAL_test_access : %d <>%d", st1.major, st2.major); } /* 3 - test X access */ st1 = FSAL_access(&entries[i].handle, &op_ctx, FSAL_X_OK, NULL); st2 = FSAL_test_access(&op_ctx, FSAL_X_OK, &attribs); LogError(COMPONENT_STDOUT, ERR_FSAL, st1.major, st1.minor); LogError(COMPONENT_STDOUT, ERR_FSAL, st2.major, st2.minor); if(st1.major != st2.major) { LogTest ("Error : different access permissions given by FSAL_access and FSAL_test_access : %d <>%d", st1.major, st2.major); } } /* preparing next call */ from = to; } LogTest("Fin de boucle : error=%d ; eod=%d", error, eod); } else /* TEST 7 */ if(test[0] == '7') { /* test snprintmem and sscanmem */ char test_string[] = "Ceci est une chaine d'essai.\nLes chiffres : 0123456789\nLes lettres : ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char buffer[256]; char string[200]; /* 200 suffit car test_string fait <100 */ int size1, size2, size3, i; /* we put bad values in string, to see if it is correctly set. */ for(i = 0; i < 200; i++) string[i] = (char)i; LogTest("Initial data (%d Bytes) = <<%s>>", strlen(test_string), test_string); /* Write test_string to a buffer. */ /* We don't give the final '\0'. */ snprintmem(buffer, 256, test_string, strlen(test_string)); LogTest("Dest_Buffer (%d Bytes) = <<%s>>", strlen(buffer), buffer); /* read the value from the buffer */ sscanmem(string, strlen(test_string), buffer); /* sets the final 0 to print the content of the buffer */ LogTest("Retrieved string : following byte = %d", (int)string[strlen(test_string)]); string[strlen(test_string)] = '\0'; LogTest("Retrieved string (%d Bytes) = <<%s>>", strlen(string), string); /* Automatic tests : */ size1 = strlen(test_string); size2 = strlen(buffer); size3 = strlen(string); LogTest("-------------------------------------"); if(size1 <= 0) LogTest("***** ERROR: source size=0 !!!"); if(size1 != size3) LogTest("***** ERROR: source size <> target size"); else LogTest("OK: source size = target size"); if((size1 * 2) != size2) LogTest("***** ERROR: hexa size <> 2 * source size"); else LogTest("OK: hexa size = 2 * source size"); if(strcmp(test_string, string)) LogTest("***** ERROR: source string <> target string"); else LogTest("OK: source string = target string"); } else /* TEST 8 */ if(test[0] == '8') { fsal_handle_t dir_hdl, subdir_hdl; fsal_name_t subdir_name; /* lookup on /cea/prot/S/lama/s8/leibovic */ if(FSAL_IS_ERROR(st = FSAL_str2path("/cea/prot/S/lama/s8/leibovic", 40, &path))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_lookupPath(&path, &op_ctx, &handle, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } snprintHandle(tracebuff, 256, &handle); LogTest("/cea/prot/S/lama/s8/leibovic: handle = %s", tracebuff); sleep(1); /* creates a directory */ LogTest("------- Create a directory -------"); if(FSAL_IS_ERROR(st = FSAL_str2name("tests_GANESHA", 30, &name))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_mkdir(&handle, &name, &op_ctx, FSAL_MODE_RUSR | FSAL_MODE_WUSR | FSAL_MODE_XUSR | FSAL_MODE_RGRP | FSAL_MODE_WGRP, &dir_hdl, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } else { snprintHandle(tracebuff, 256, &dir_hdl); LogTest("newly created dir handle = %s", tracebuff); printattributes(attribs); } sleep(1); /* Try to create it again */ LogTest("------- Try to create it again -------"); if(FSAL_IS_ERROR(st = FSAL_mkdir(&handle, &name, &op_ctx, FSAL_MODE_RUSR | FSAL_MODE_WUSR | FSAL_MODE_XUSR | FSAL_MODE_RGRP | FSAL_MODE_WGRP, &dir_hdl, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } else { LogTest("**** Error: FSAL should have returned ERR_FSAL_EXIST"); } sleep(1); /* creates a subdirectory */ LogTest("------- Create a subdirectory -------"); if(FSAL_IS_ERROR(st = FSAL_str2name("subdir_GANESHA", 30, &subdir_name))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } if(FSAL_IS_ERROR(st = FSAL_mkdir(&dir_hdl, &subdir_name, &op_ctx, FSAL_MODE_RUSR | FSAL_MODE_WUSR | FSAL_MODE_XUSR | FSAL_MODE_RGRP | FSAL_MODE_WGRP, &subdir_hdl, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } else { snprintHandle(tracebuff, 256, &subdir_hdl); LogTest("newly created subdir handle = %s", tracebuff); printattributes(attribs); } /* try to removes the parent directory */ LogTest("------- Try to removes the parent directory -------"); if(FSAL_IS_ERROR(st = FSAL_unlink(&handle, &name, &op_ctx, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } else { LogTest("FSAL should not have unlinked %s because it is not empty", name.name); } sleep(1); /* removes the subdirectory */ LogTest("------- Removes the subdirectory -------"); if(FSAL_IS_ERROR(st = FSAL_unlink(&dir_hdl, &subdir_name, &op_ctx, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } else { LogTest("New attributes for parent directory:"); printattributes(attribs); } /* removes the parent directory */ LogTest("------- Removes the parent directory -------"); if(FSAL_IS_ERROR(st = FSAL_unlink(&handle, &name, &op_ctx, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } else { LogTest("Unlink %s OK", name.name); } } /* TEST 9 */ else if(test[0] == '9') { fsal_handle_t dir_hdl, subdir_hdl; fsal_name_t subdir_name; fsal_attrib_list_t attr_set; fsal_fsid_t set_fsid = { 1LL, 2LL }; #ifdef _LINUX struct tm jour_heure = { 56, 34, 12, 31, 12, 110, 0, 0, 0, 0, 0 }; #else struct tm jour_heure = { 56, 34, 12, 31, 12, 110, 0, 0, 0 }; #endif /* lookup on /cea/prot/S/lama/s8/leibovic */ if(FSAL_IS_ERROR(st = FSAL_str2path("/cea/prot/S/lama/s8/leibovic", 40, &path))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_lookupPath(&path, &op_ctx, &handle, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } snprintHandle(tracebuff, 256, &handle); LogTest("/cea/prot/S/lama/s8/leibovic: handle = %s", tracebuff); sleep(1); /* creates a file */ LogTest("------- Create a file -------"); if(FSAL_IS_ERROR(st = FSAL_str2name("tests_GANESHA_setattrs", 30, &name))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_create(&handle, &name, &op_ctx, FSAL_MODE_RUSR | FSAL_MODE_WUSR | FSAL_MODE_XUSR | FSAL_MODE_RGRP | FSAL_MODE_WGRP, &dir_hdl, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } else { snprintHandle(tracebuff, 256, &dir_hdl); LogTest("newly created file handle = %s", tracebuff); printattributes(attribs); } sleep(1); LogTest("------- Try to change its attributes -------"); /* Macro that try to change the value for an attribute */ #define CHANGE_ATTRS( str_nom, nom, flag, new_val ) do {\ memset(&attr_set, 0, sizeof(fsal_attrib_list_t) ); \ LogTest("\nTry to change '%s' :",str_nom); \ FSAL_SET_MASK( attr_set.asked_attributes , flag ); \ attr_set.nom = new_val; \ attribs.asked_attributes = attr_set.asked_attributes; \ /* attribs.asked_attributes = mask; */\ st = FSAL_setattrs( &dir_hdl, &op_ctx, &attr_set, &attribs );\ if ( FSAL_IS_ERROR(st) ) \ LogError(COMPONENT_STDOUT,ERR_FSAL,st.major,st.minor);\ else \ printattributes( attribs ); \ } while(0) CHANGE_ATTRS("supported_attributes", supported_attributes, FSAL_ATTR_SUPPATTR, FSAL_ATTRS_MANDATORY); CHANGE_ATTRS("type", type, FSAL_ATTR_TYPE, FSAL_TYPE_LNK); sleep(1); /* to see mtime modification by truncate */ CHANGE_ATTRS("filesize", filesize, FSAL_ATTR_SIZE, (fsal_size_t) 12); sleep(1); /* to see mtime modification by truncate */ CHANGE_ATTRS("fsid", fsid, FSAL_ATTR_FSID, set_fsid); /* @todo : ACLs */ CHANGE_ATTRS("fileid", fileid, FSAL_ATTR_FILEID, (fsal_u64_t) 1234); CHANGE_ATTRS("mode", mode, FSAL_ATTR_MODE, (FSAL_MODE_RUSR | FSAL_MODE_WUSR | FSAL_MODE_RGRP)); CHANGE_ATTRS("numlinks", numlinks, FSAL_ATTR_NUMLINKS, 7); /* FSAL_ATTR_RAWDEV */ CHANGE_ATTRS("atime", atime.seconds, FSAL_ATTR_ATIME, mktime(&jour_heure)); jour_heure.tm_min++; CHANGE_ATTRS("creation", creation.seconds, FSAL_ATTR_CREATION, mktime(&jour_heure)); jour_heure.tm_min++; CHANGE_ATTRS("mtime", mtime.seconds, FSAL_ATTR_MTIME, mktime(&jour_heure)); jour_heure.tm_min++; CHANGE_ATTRS("ctime", ctime.seconds, FSAL_ATTR_CTIME, mktime(&jour_heure)); CHANGE_ATTRS("spaceused", spaceused, FSAL_ATTR_SPACEUSED, (fsal_size_t) 12345); CHANGE_ATTRS("mounted_on_fileid", mounted_on_fileid, FSAL_ATTR_MOUNTFILEID, (fsal_u64_t) 3210); CHANGE_ATTRS("owner", owner, FSAL_ATTR_OWNER, 3051); /* deniel */ CHANGE_ATTRS("group", group, FSAL_ATTR_GROUP, 5953); /* sr */ sleep(1); /* removes the parent directory */ LogTest("------- Removes the directory -------"); if(FSAL_IS_ERROR(st = FSAL_unlink(&handle, &name, &op_ctx, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } else { LogTest("Unlink %s OK", name.name); } } else if(test[0] == 'A') { char digest_buff[FSAL_DIGEST_SIZE_HDLV3]; /* lookup on /cea/prot/S/lama/s8/leibovic */ if(FSAL_IS_ERROR(st = FSAL_str2path("/cea/prot/S/lama/s8/leibovic", 40, &path))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } attribs.asked_attributes = mask; if(FSAL_IS_ERROR(st = FSAL_lookupPath(&path, &op_ctx, &handle, &attribs))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } snprintHandle(tracebuff, 256, &handle); LogTest("/cea/prot/S/lama/s8/leibovic: handle = %s", tracebuff); /* building digest */ st = FSAL_DigestHandle(&export_ctx, FSAL_DIGEST_NFSV3, &handle, digest_buff); if(FSAL_IS_ERROR(st)) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } else { /* print digest */ snprintmem(tracebuff, 256, digest_buff, FSAL_DIGEST_SIZE_HDLV3); LogTest("/cea/prot/S/lama/s8/leibovic: handle_digest = %s", tracebuff); } memset(&handle, 0, sizeof(fsal_handle_t)); /* expend digest */ st = FSAL_ExpandHandle(&export_ctx, FSAL_DIGEST_NFSV3, digest_buff, &handle); if(FSAL_IS_ERROR(st)) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); } else { /* print expended handle */ snprintHandle(tracebuff, 256, &handle); LogTest("/cea/prot/S/lama/s8/leibovic: handle expended = %s", tracebuff); } } else if(test[0] == 'B') { fsal_dynamicfsinfo_t dyninfo; if(FSAL_IS_ERROR(st = FSAL_dynamic_fsinfo(&root_handle, &op_ctx, &dyninfo))) { LogError(COMPONENT_STDOUT, ERR_FSAL, st.major, st.minor); exit(st.major); } LogTest("total_bytes = %llu", dyninfo.total_bytes); LogTest("free_bytes = %llu", dyninfo.free_bytes); LogTest("avail_bytes = %llu", dyninfo.avail_bytes); LogTest("total_files = %llu", dyninfo.total_files); LogTest("free_files = %llu", dyninfo.free_files); LogTest("avail_files = %llu", dyninfo.avail_files); LogTest("time_delta = %u.%u", dyninfo.time_delta.seconds, dyninfo.time_delta.nseconds); } else LogTest("%s : test inconnu", test); return 0; }
int main(int argc, char *argv[]) { int c; int exportid = 0; char buffer[CMD_BUFFER_SIZE]; char str[2 * CMD_BUFFER_SIZE]; fhandle2 filehandle_v2; struct nfs_fh3 filehandle_v3; nfs_fh4 filehandle_v4; int flag_i = FALSE; char exec_name[MAXPATHLEN]; char *tempo_exec_name = NULL; cache_inode_fsal_data_t fsal_data; fsal_op_context_t fsal_op_context; fsal_export_context_t fsal_export_context; exportlist_t *pexportlist = NULL; exportlist_t *pexport = NULL; nfs_start_info_t nfs_start_info; fsal_status_t fsal_status; unsigned int nfs_version = 3; path_str_t fsal_path_lib[NB_AVAILABLE_FSAL]; #ifdef _USE_SHARED_FSAL int lentab = NB_AVAILABLE_FSAL ; #endif short cache_content_hash; char entry_path[MAXPATHLEN]; int i, nb_char; fsal_path_t export_path = FSAL_PATH_INITIALIZER; unsigned int cookie; fsal_xattrent_t xattr_array[256]; unsigned int nb_returned; int eol; char attr_buffer[4096]; size_t sz_returned; fsal_u64_t objid; char options[] = "h@f:v:i:"; char usage[] = "%s [-h][-f <cfg_path>] {-v 2|3|4 <NFS_FileHandle> | -i <inum>}\n" " -h : prints this help\n" " -f <config_file> : sets the ganesha configuration file to be used\n" " -v <nfs_version> : sets the NFS version the file handle passed as argument\n" " -i <inum> : get datacache path for the given inode number (decimal)\n"; ServerBootTime = time(NULL); SetDefaultLogging("STDERR"); /* What is the executable file's name */ if((tempo_exec_name = strrchr(argv[0], '/')) != NULL) strcpy((char *)exec_name, tempo_exec_name + 1); strncpy(config_path, DEFAULT_CONFIG_FILE, MAXPATHLEN); /* now parsing options with getopt */ while((c = getopt(argc, argv, options)) != EOF) { switch (c) { case '@': printf("%s compiled on %s at %s\n", exec_name, __DATE__, __TIME__); exit(0); break; case 'h': printf(usage, exec_name); exit(0); break; case 'f': strncpy(config_path, optarg, MAXPATHLEN); break; case 'i': if(sscanf(optarg, "%llu", &objid) != 1) { fprintf(stderr, "Invalid object_id %s (base-10 integer expected)\n", optarg); exit(1); } flag_i = TRUE; break; case 'v': nfs_version = atoi(optarg); if((nfs_version < 2) || (nfs_version > 4)) { fprintf(stderr, "Invalid nfs version %u\n", nfs_version); exit(1); } break; case '?': printf("Unknown option: %c\n", optopt); printf(usage, exec_name); exit(1); } } if(!flag_i && (optind != argc - 1)) { printf("Missing argument: <NFS_FileHandle>\n"); printf(usage, exec_name); exit(1); } /* initialize memory and logging */ nfs_prereq_init("convert_fh", "localhost", NIV_MAJ, "/dev/tty"); #ifdef _USE_SHARED_FSAL if(nfs_get_fsalpathlib_conf(config_path, fsal_path_lib, &lentab)) { fprintf(stderr, "NFS MAIN: Error parsing configuration file."); exit(1); } #endif /* _USE_SHARED_FSAL */ /* Load the FSAL library (if needed) */ if(!FSAL_LoadLibrary((char *)fsal_path_lib)) /** @todo: this part of the code and this utility has to be checked */ { fprintf(stderr, "NFS MAIN: Could not load FSAL dynamic library %s", (char *)fsal_path_lib[0]); exit(1); } /* Get the FSAL functions */ FSAL_LoadFunctions(); /* Get the FSAL consts */ FSAL_LoadConsts(); /* initialize default parameters */ nfs_set_param_default(); /* parse configuration file */ if(nfs_set_param_from_conf(&nfs_start_info)) { fprintf(stderr, "Error parsing configuration file '%s'", config_path); exit(1); } /* check parameters consitency */ if(nfs_check_param_consistency()) { fprintf(stderr, "Inconsistent parameters found"); exit(1); } if(!nfs_param.pexportlist) { fprintf(stderr, "No export entries found in configuration file !!!\n"); return -1; } pexportlist = nfs_param.pexportlist; /* not initialization is needed for converting fileid to path in datacache */ if(!flag_i) { #ifdef _USE_SHARED_FSAL fsal_status = FSAL_Init(&nfs_param.fsal_param[0]); #else fsal_status = FSAL_Init(&nfs_param.fsal_param); #endif if(FSAL_IS_ERROR(fsal_status)) { /* Failed init */ fprintf(stderr, "FSAL library could not be initialized, major=%d minor=%d\n", fsal_status.major, fsal_status.minor); exit(1); } strncpy(str, argv[optind], 2 * CMD_BUFFER_SIZE); switch (nfs_version) { case 2: if(sscanmem(filehandle_v2, sizeof(file_handle_v2_t), (char *)str) == -1) { fprintf(stderr, "Bad FH as input (expected size: %lu bytes)\n", (unsigned long)sizeof(file_handle_v2_t)); exit(1); } exportid = nfs2_FhandleToExportId(&filehandle_v2); break; case 3: if(sscanmem(buffer, sizeof(file_handle_v3_t), (char *)str) == -1) { fprintf(stderr, "Bad FH as input (expected size: %lu bytes)\n", (unsigned long)sizeof(file_handle_v3_t)); exit(1); } filehandle_v3.data.data_val = (char *)buffer; filehandle_v3.data.data_len = sizeof(file_handle_v3_t); exportid = nfs3_FhandleToExportId(&filehandle_v3); break; case 4: if(sscanmem(buffer, sizeof(file_handle_v4_t), (char *)str) == -1) { fprintf(stderr, "Bad FH as input (expected size: %lu bytes)\n", (unsigned long)sizeof(file_handle_v4_t)); exit(1); } filehandle_v4.nfs_fh4_val = (char *)buffer; filehandle_v4.nfs_fh4_len = sizeof(file_handle_v4_t); exportid = nfs4_FhandleToExportId(&filehandle_v4); break; } if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) { fprintf(stderr, "NFS FH has exportid %u which is invalid....\n", exportid); exit(1); } /* INITIALIZING A CLIENT CONTEXT FOR FSAL */ FSAL_str2path(pexport->fullpath, MAXPATHLEN, &export_path); if(FSAL_IS_ERROR (fsal_status = FSAL_BuildExportContext(&fsal_export_context, &export_path, pexport->FS_specific))) { fprintf(stderr, "Error in FSAL_BuildExportContext, major=%u, minor=%u\n", fsal_status.major, fsal_status.minor); exit(1); } fsal_status = FSAL_InitClientContext(&fsal_op_context); if(FSAL_IS_ERROR(fsal_status)) { /* Failed init */ fprintf(stderr, "Could not init client context... major=%d minor=%d\n", fsal_status.major, fsal_status.minor); exit(1); } fsal_status = FSAL_GetClientContext(&fsal_op_context, &fsal_export_context, 0, 0, NULL, 0); if(FSAL_IS_ERROR(fsal_status)) { /* Failed init */ fprintf(stderr, "Could not get cred for uid=%d gid=%d, major=%d minor=%d\n", getuid(), getgid(), fsal_status.major, fsal_status.minor); exit(1); } /* now, can use the fsal_op_context */ switch (nfs_version) { case 2: if(!nfs2_FhandleToFSAL(&filehandle_v2, &fsal_data.handle, &fsal_op_context)) { fprintf(stderr, "Cannot convert Fhandle to FSAL\n"); exit(1); } break; case 3: if(!nfs3_FhandleToFSAL(&filehandle_v3, &fsal_data.handle, &fsal_op_context)) { fprintf(stderr, "Cannot convert Fhandle to FSAL\n"); exit(1); } break; case 4: if(!nfs4_FhandleToFSAL(&filehandle_v4, &fsal_data.handle, &fsal_op_context)) { fprintf(stderr, "Cannot convert Fhandle to FSAL\n"); exit(1); } break; } printf("\n"); snprintmem((caddr_t) str, 2 * CMD_BUFFER_SIZE, (caddr_t) & fsal_data.handle, sizeof(fsal_data.handle)); printf("%-18s = %s\n", "FSAL Handle", str); /* Now, list FSAL extended attributes */ cookie = XATTRS_READLIST_FROM_BEGINNING; eol = FALSE; while(!eol) { unsigned int index; fsal_status = FSAL_ListXAttrs(&fsal_data.handle, cookie, &fsal_op_context, xattr_array, 256, &nb_returned, &eol); if(FSAL_IS_ERROR(fsal_status)) { fprintf(stderr, "Error executing FSAL_ListXAttrs\n"); exit(1); } /* list attributes and get their value */ for(index = 0; index < nb_returned; index++) { cookie = xattr_array[index].xattr_cookie; printf("%-18s = ", xattr_array[index].xattr_name.name); fsal_status = FSAL_GetXAttrValueByName(&fsal_data.handle, &xattr_array[index].xattr_name, &fsal_op_context, attr_buffer, 4096, &sz_returned); if(FSAL_IS_ERROR(fsal_status)) { fprintf(stderr, "Error executing FSAL_GetXAttrValueByName\n"); } /* Display it */ print_buffer(attr_buffer, sz_returned); } } /* get object ID */ fsal_status = FSAL_DigestHandle(&fsal_export_context, FSAL_DIGEST_FILEID4, &fsal_data.handle, (caddr_t) & objid); if(FSAL_IS_ERROR(fsal_status)) { fprintf(stderr, "Error retrieving fileid from handle\n"); } else { printf("%-18s = %llu\n", "FileId", objid); } } /* end of retrieval of objid */ /* build the path in the datacache */ cache_content_hash = HashFileID4(objid); /* for limiting the number of entries into each datacache directory * we create 256 subdirectories on 2 levels, depending on the entry's fileid. */ nb_char = snprintf(entry_path, MAXPATHLEN, "export_id=%d", 0); for(i = 0; i <= 8; i += 8) { /* concatenation of hashval */ nb_char += snprintf((char *)(entry_path + nb_char), MAXPATHLEN - nb_char, "/%02hhX", (char)((cache_content_hash >> i) & 0xFF)); } /* displays the node name */ printf("%-18s = %s/%s/node=%llx*\n", "DataCache path", nfs_param.cache_layers_param.cache_content_client_param.cache_dir, entry_path, objid); exit(0); }
main(int argc, char *argv[]) { char localmachine[256]; cache_inode_client_t client; LRU_parameter_t lru_param; LRU_status_t lru_status; cache_inode_fsal_data_t fsdata; fsal_status_t status; fsal_parameter_t init_param; fsal_name_t name; fsal_path_t path; fsal_attrib_mask_t mask; fsal_path_t pathroot; fsal_attrib_list_t attribs; fsal_handle_t root_handle; cache_inode_endofdir_t eod_met; cache_inode_dir_entry_t dirent_array[100]; cache_inode_dir_entry_t dirent_array_loop[5]; unsigned int nbfound; unsigned int begin_cookie = 0; hash_buffer_t key, value; uid_t uid; fsal_cred_t cred; cache_inode_status_t cache_status; cache_inode_parameter_t cache_param; cache_inode_client_parameter_t cache_client_param; hash_table_t *ht = NULL; fsal_attrib_list_t attrlookup; cache_entry_t *cache_entry_root = NULL; cache_entry_t *cache_entry_lookup = NULL; cache_entry_t *cache_entry_lookup2 = NULL; cache_entry_t *cache_entry_lookup3 = NULL; cache_entry_t *cache_entry_lookup4 = NULL; cache_entry_t *cache_entry_lookup5 = NULL; cache_entry_t *cache_entry_lookup6 = NULL; cache_entry_t *cache_entry_dircont = NULL; cache_inode_gc_policy_t gcpol; char *configfile = argv[1]; int i = 0; int rc = 0; /* Init the Buddy System allocation */ if((rc = BuddyInit(NULL)) != BUDDY_SUCCESS) { LogTest("Error while initializing Buddy system allocator"); exit(1); } /* init debug */ SetNamePgm("test_cache_inode"); SetDefaultLogging("TEST"); SetNameFunction("main"); InitLogging(); #if defined( _USE_GHOSTFS ) if(argc != 2) { LogTest("Please set the configuration file as parameter"); exit(1); } #endif /* Obtention du nom de la machine */ if(gethostname(localmachine, sizeof(localmachine)) != 0) { LogError(COMPONENT_STDOUT, ERR_SYS, ERR_GETHOSTNAME, errno); exit(1); } else SetNameHost(localmachine); AddFamilyError(ERR_FSAL, "FSAL related Errors", tab_errstatus_FSAL); AddFamilyError(ERR_CACHE_INODE, "FSAL related Errors", tab_errstatus_cache_inode); LogTest( "Starting the test"); LogTest( "-----------------"); #if defined( _USE_GHOSTFS ) if(FSAL_IS_ERROR(status = FSAL_str2path(configfile, strlen(configfile) + 1, &(init_param.fs_specific_info. definition_file)))) { LogError(COMPONENT_STDOUT, ERR_FSAL, status.major, status.minor); } #elif defined( _USE_HPSS ) FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, Flags); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, DebugValue); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, TransferType); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, NumRetries); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, BusyDelay); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, BusyRetries); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, TotalDelay); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, GKTotalDelay); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, LimitedRetries); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, MaxConnections); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, ReuseDataConnections); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, UsePortRange); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, RetryStageInp); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, DMAPWriteUpdates); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, ServerName); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, DescName); init_param.fs_specific_info.behaviors.PrincipalName = FSAL_INIT_FORCE_VALUE; strncpy(init_param.fs_specific_info.hpss_config.PrincipalName, HPSS_SSM, HPSS_MAX_PRINCIPAL_NAME); init_param.fs_specific_info.behaviors.KeytabPath = FSAL_INIT_FORCE_VALUE; strncpy(init_param.fs_specific_info.hpss_config.KeytabPath, HPSS_KEYTAB, HPSS_MAX_PATH_NAME); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, DebugPath); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, HostName); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, RegistrySiteName); #endif /* 2-common info (default) */ FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxfilesize); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxlink); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxnamelen); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxpathlen); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, no_trunc); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, chown_restricted); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, case_insensitive); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, case_preserving); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, fh_expire_type); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, link_support); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, symlink_support); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, named_attr); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, unique_handles); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, lease_time); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, acl_support); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, cansettime); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, homogenous); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxread); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxwrite); /* Init */ if(FSAL_IS_ERROR(status = FSAL_Init(&init_param))) { LogError(COMPONENT_STDOUT, ERR_FSAL, status.major, status.minor); } /* getting creds */ uid = getuid(); if(FSAL_IS_ERROR(status = FSAL_GetUserCred(uid, NULL, &cred))) { LogError(COMPONENT_STDOUT, ERR_FSAL, status.major, status.minor); } /* Init of the cache inode module */ cache_param.hparam.index_size = 31; cache_param.hparam.alphabet_length = 10; /* Buffer seen as a decimal polynom */ cache_param.hparam.nb_node_prealloc = 100; cache_param.hparam.hash_func_key = cache_inode_fsal_hash_func; cache_param.hparam.hash_func_rbt = cache_inode_fsal_rbt_func; cache_param.hparam.hash_func_both = NULL ; /* BUGAZOMEU */ cache_param.hparam.compare_key = cache_inode_compare_key_fsal; cache_param.hparam.key_to_str = display_key; cache_param.hparam.val_to_str = display_value; if((ht = cache_inode_init(cache_param, &cache_status)) == NULL) { LogTest( "Error %d while init hash ", cache_status); } else LogTest( "Hash Table address = %p", ht); /* We need a cache_client to acces the cache */ cache_client_param.attrmask = FSAL_ATTRS_MANDATORY | FSAL_ATTR_MTIME | FSAL_ATTR_CTIME | FSAL_ATTR_ATIME; cache_client_param.nb_prealloc_entry = 1000; cache_client_param.nb_pre_dir_data = 200; cache_client_param.nb_pre_parent = 1200; cache_client_param.nb_pre_state_v4 = 100; cache_client_param.lru_param.nb_entry_prealloc = 1000; cache_client_param.lru_param.entry_to_str = lru_entry_to_str; cache_client_param.lru_param.clean_entry = lru_clean_entry; cache_client_param.grace_period_attr = 0; cache_client_param.grace_period_link = 0; cache_client_param.grace_period_dirent = 0; cache_client_param.expire_type_attr = CACHE_INODE_EXPIRE_NEVER; cache_client_param.expire_type_link = CACHE_INODE_EXPIRE_NEVER; cache_client_param.expire_type_dirent = CACHE_INODE_EXPIRE_NEVER; /* Init the cache_inode client */ if(cache_inode_client_init(&client, cache_client_param, 0) != 0) exit(1); /* Getting the root of the FS */ if((FSAL_IS_ERROR(status = FSAL_str2path("/", 2, &pathroot)))) { LogError(COMPONENT_STDOUT, ERR_FSAL, status.major, status.minor); exit(1); } attribs.asked_attributes = cache_client_param.attrmask; if((FSAL_IS_ERROR(status = FSAL_lookupPath(pathroot, &cred, &root_handle, &attribs)))) { LogError(COMPONENT_STDOUT, ERR_FSAL, status.major, status.minor); exit(1); } fsdata.cookie = 0; fsdata.handle = root_handle; /* Cache the root of the FS */ if((cache_entry_root = cache_inode_make_root(&fsdata, 1, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't init fs's root"); exit(1); } /* A lookup in the root fsal */ if((FSAL_IS_ERROR(status = FSAL_str2name("cea", 10, &name)))) { LogError(COMPONENT_STDOUT, ERR_FSAL, status.major, status.minor); exit(1); } if((cache_entry_lookup = cache_inode_lookup(cache_entry_root, name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } /* Lookup a second time (entry should now be cached) */ if((cache_entry_lookup2 = cache_inode_lookup(cache_entry_root, name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } if(cache_entry_lookup2 != cache_entry_lookup) { LogTest("Error: lookup results should be the same"); exit(1); } /* A lookup in the root fsal */ if((FSAL_IS_ERROR(status = FSAL_str2name("log", 10, &name)))) { LogError(COMPONENT_STDOUT, ERR_FSAL, status.major, status.minor); exit(1); } if((cache_entry_lookup3 = cache_inode_lookup(cache_entry_root, name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } if((cache_entry_lookup4 = cache_inode_lookup(cache_entry_root, name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } if(cache_entry_lookup3 != cache_entry_lookup4) { LogTest("Error: lookup results should be the same"); exit(1); } /* A lookup in the root fsal */ if((FSAL_IS_ERROR(status = FSAL_str2name("cea", 10, &name)))) { LogError(COMPONENT_STDOUT, ERR_FSAL, status.major, status.minor); exit(1); } if((cache_entry_lookup = cache_inode_lookup(cache_entry_root, name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } /* A lookup in the root fsal */ if((FSAL_IS_ERROR(status = FSAL_str2name("log", 10, &name)))) { LogError(COMPONENT_STDOUT, ERR_FSAL, status.major, status.minor); exit(1); } if((cache_entry_lookup = cache_inode_lookup(cache_entry_root, name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } LogTest( "---------------------------------"); /* The end of all the tests */ LogTest( "All tests exited successfully"); exit(0); } /* main */
/** * Parse FS specific option string * to build the export entry option. */ fsal_status_t SNMPFSAL_BuildExportContext(snmpfsal_export_context_t * p_export_context, /* OUT */ fsal_path_t * p_export_path, /* IN */ char *fs_specific_options /* IN */ ) { struct tree *tree_head, *sub_tree; char snmp_path[FSAL_MAX_PATH_LEN]; int rc; /* sanity check */ if(!p_export_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_BuildExportContext); if((fs_specific_options != NULL) && (fs_specific_options[0] != '\0')) { LogCrit(COMPONENT_FSAL, "FSAL BUILD CONTEXT: ERROR: found an EXPORT::FS_Specific item whereas it is not supported for this filesystem."); } /* retrieves the MIB tree associated to this export */ /*tree_head = get_tree_head(); */ tree_head = read_all_mibs(); if(tree_head == NULL) Return(ERR_FSAL_BAD_INIT, snmp_errno, INDEX_FSAL_BuildExportContext); /* convert the path to a SNMP path */ if(p_export_path != NULL) PosixPath2SNMP(p_export_path->path, snmp_path); else strcpy(snmp_path, "."); if(!strcmp(snmp_path, ".")) { /* the exported tree is the root tree */ p_export_context->root_mib_tree = tree_head; BuildRootHandle(&p_export_context->root_handle); } else { /* convert the SNMP path to an oid */ rc = ParseSNMPPath(snmp_path, &p_export_context->root_handle); if(rc) { LogCrit(COMPONENT_FSAL, "FSAL BUILD CONTEXT: ERROR parsing SNMP path '%s'", snmp_path); Return(rc, 0, INDEX_FSAL_BuildExportContext); } /* get the subtree */ sub_tree = FSAL_GetTree(p_export_context->root_handle.data.oid_tab, p_export_context->root_handle.data.oid_len, tree_head, FALSE); if(sub_tree == NULL) Return(ERR_FSAL_NOENT, snmp_errno, INDEX_FSAL_BuildExportContext); /* if it has some childs or the object is unknown, consider it has a node */ if((sub_tree->child_list != NULL) || (sub_tree->type == TYPE_OTHER)) { p_export_context->root_handle.data.object_type_reminder = FSAL_NODETYPE_NODE; } else { LogEvent(COMPONENT_FSAL, "FSAL BUILD CONTEXT: WARNING: '%s' seems to be a leaf !!!", snmp_path); } p_export_context->root_mib_tree = tree_head; } /* save the root path (for lookupPath checks) */ if(p_export_path != NULL) p_export_context->root_path = *p_export_path; else FSAL_str2path("/", 2, &p_export_context->root_path); LogEvent(COMPONENT_FSAL, "CREATING EXPORT CONTEXT PATH=%s\n", snmp_path); if(isFullDebug(COMPONENT_FSAL)) { int i; char oidstr[2048], *p = oidstr; oidstr[0] = '\0'; for(i = 0; i < p_export_context->root_handle.data.oid_len; i++) p += sprintf(p, ".%ld", p_export_context->root_handle.data.oid_tab[i]); LogFullDebug(COMPONENT_FSAL, "oid %s", oidstr); } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_BuildExportContext); }
/** * FSAL_lookup : * Looks up for an object into a directory. * * Note : if parent handle and filename are NULL, * this retrieves root's handle. * * \param parent_directory_handle (input) * Handle of the parent directory to search the object in. * \param filename (input) * The name of the object to find. * \param p_context (input) * Authentication context for the operation (user,...). * \param object_handle (output) * The handle of the object corresponding to filename. * \param object_attributes (optional input/output) * Pointer to the attributes of the object we found. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * It can be NULL (increases performances). * * \return - ERR_FSAL_NO_ERROR, if no error. * - Another error code else. * */ fsal_status_t LUSTREFSAL_lookup(fsal_handle_t * p_parent_directory_handle, /* IN */ fsal_name_t * p_filename, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_handle_t * p_object_handle, /* OUT */ fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ ) { int rc, errsv; fsal_status_t status; struct stat buffstat; fsal_path_t pathfsal; /* sanity checks * note : object_attributes is optionnal * parent_directory_handle may be null for getting FS root. */ if(!p_object_handle || !p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); /* filename AND parent handle are NULL => lookup "/" */ if((p_parent_directory_handle && !p_filename) || (!p_parent_directory_handle && p_filename)) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup); /* get information about root */ if(!p_parent_directory_handle) { /* get handle for the mount point */ FSAL_str2path(((lustrefsal_op_context_t *)p_context)->export_context->mount_point, ((lustrefsal_op_context_t *)p_context)->export_context->mnt_len, &pathfsal); TakeTokenFSCall(); status = fsal_internal_Path2Handle(p_context, &pathfsal, p_object_handle); ReleaseTokenFSCall(); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_lookup); /* get attributes, if asked */ if(p_object_attributes) { status = LUSTREFSAL_getattrs(p_object_handle, p_context, p_object_attributes); if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } /* Done */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); } /* retrieve directory attributes */ status = fsal_internal_Handle2FidPath(p_context, p_parent_directory_handle, &pathfsal); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_lookup); /* get directory metadata */ TakeTokenFSCall(); rc = lstat(pathfsal.path, &buffstat); errsv = errno; ReleaseTokenFSCall(); if(rc) { if(errsv == ENOENT) Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_lookup); else Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lookup); } /* Be careful about junction crossing, symlinks, hardlinks,... */ switch (posix2fsal_type(buffstat.st_mode)) { case FSAL_TYPE_DIR: // OK break; case FSAL_TYPE_JUNCTION: // This is a junction Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup); case FSAL_TYPE_FILE: case FSAL_TYPE_LNK: case FSAL_TYPE_XATTR: // not a directory Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup); default: Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup); } LogFullDebug(COMPONENT_FSAL, "lookup of %s/%s\n", pathfsal.path, p_filename->name); /* check rights to enter into the directory */ status = fsal_internal_testAccess(p_context, FSAL_X_OK, &buffstat, NULL); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_lookup); status = fsal_internal_appendNameToPath(&pathfsal, p_filename); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_lookup); /* get file handle, it it exists */ TakeTokenFSCall(); status = fsal_internal_Path2Handle(p_context, &pathfsal, p_object_handle); ReleaseTokenFSCall(); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_lookup); /* get object attributes */ if(p_object_attributes) { status = LUSTREFSAL_getattrs(p_object_handle, p_context, p_object_attributes); if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(p_object_attributes->asked_attributes); FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } /* lookup complete ! */ Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup); }
int nfs_Symlink(nfs_arg_t *parg, exportlist_t *pexport, fsal_op_context_t *pcontext, nfs_worker_data_t *pworker, struct svc_req *preq, nfs_res_t *pres) { char *str_symlink_name = NULL; fsal_name_t symlink_name; char *str_target_path = NULL; cache_inode_create_arg_t create_arg; fsal_accessmode_t mode = 0777; cache_entry_t *symlink_pentry = NULL; cache_entry_t *parent_pentry; cache_inode_file_type_t parent_filetype; fsal_attrib_list_t parent_attr; fsal_attrib_list_t attr_symlink; fsal_attrib_list_t attributes_symlink; fsal_attrib_list_t attr_parent_after; fsal_attrib_list_t *ppre_attr; cache_inode_status_t cache_status; cache_inode_status_t cache_status_parent; fsal_handle_t *pfsal_handle; int rc = NFS_REQ_OK; #ifdef _USE_QUOTA fsal_status_t fsal_status ; #endif memset(&create_arg, 0, sizeof(create_arg)); if(isDebug(COMPONENT_NFSPROTO)) { char str[LEN_FH_STR]; switch (preq->rq_vers) { case NFS_V2: str_symlink_name = parg->arg_symlink2.from.name; str_target_path = parg->arg_symlink2.to; break; case NFS_V3: str_symlink_name = parg->arg_symlink3.where.name; str_target_path = parg->arg_symlink3.symlink.symlink_data; break; } nfs_FhandleToStr(preq->rq_vers, &(parg->arg_symlink2.from.dir), &(parg->arg_symlink3.where.dir), NULL, str); LogDebug(COMPONENT_NFSPROTO, "REQUEST PROCESSING: Calling nfs_Symlink handle: %s name: %s target: %s", str, str_symlink_name, str_target_path); } if(preq->rq_vers == NFS_V3) { /* to avoid setting it on each error case */ pres->res_symlink3.SYMLINK3res_u.resfail.dir_wcc.before.attributes_follow = FALSE; pres->res_symlink3.SYMLINK3res_u.resfail.dir_wcc.after.attributes_follow = FALSE; ppre_attr = NULL; } /* Convert directory file handle into a vnode */ if((parent_pentry = nfs_FhandleToCache(preq->rq_vers, &(parg->arg_symlink2.from.dir), &(parg->arg_symlink3.where.dir), NULL, &(pres->res_stat2), &(pres->res_symlink3.status), NULL, &parent_attr, pcontext, &rc)) == NULL) { /* Stale NFS FH ? */ goto out;; } /* get directory attributes before action (for V3 reply) */ ppre_attr = &parent_attr; /* Extract the filetype */ parent_filetype = cache_inode_fsal_type_convert(parent_attr.type); /* * Sanity checks: new directory name must be non-null; parent must be * a directory. */ if(parent_filetype != DIRECTORY) { switch (preq->rq_vers) { case NFS_V2: pres->res_stat2 = NFSERR_NOTDIR; break; case NFS_V3: pres->res_symlink3.status = NFS3ERR_NOTDIR; break; } rc = NFS_REQ_OK; goto out; } #ifdef _USE_QUOTA /* if quota support is active, then we should check is the FSAL allows inode creation or not */ fsal_status = FSAL_check_quota( pexport->fullpath, FSAL_QUOTA_INODES, FSAL_OP_CONTEXT_TO_UID( pcontext ) ) ; if( FSAL_IS_ERROR( fsal_status ) ) { switch (preq->rq_vers) { case NFS_V2: pres->res_stat2 = NFSERR_DQUOT ; break; case NFS_V3: pres->res_symlink3.status = NFS3ERR_DQUOT; break; } rc = NFS_REQ_OK; goto out; } #endif /* _USE_QUOTA */ switch (preq->rq_vers) { case NFS_V2: str_symlink_name = parg->arg_symlink2.from.name; str_target_path = parg->arg_symlink2.to; break; case NFS_V3: str_symlink_name = parg->arg_symlink3.where.name; str_target_path = parg->arg_symlink3.symlink.symlink_data; break; } if(str_symlink_name == NULL || *str_symlink_name == '\0'|| str_target_path == NULL || *str_target_path == '\0' || FSAL_IS_ERROR(FSAL_str2name(str_symlink_name, 0, &symlink_name)) || FSAL_IS_ERROR(FSAL_str2path(str_target_path, 0, &create_arg.link_content))) { cache_status = CACHE_INODE_INVALID_ARGUMENT; } else { /* Make the symlink */ if((symlink_pentry = cache_inode_create(parent_pentry, &symlink_name, SYMBOLIC_LINK, mode, &create_arg, &attr_symlink, pcontext, &cache_status)) != NULL) { switch (preq->rq_vers) { case NFS_V2: pres->res_stat2 = NFS_OK; break; case NFS_V3: /* Build file handle */ pfsal_handle = &symlink_pentry->handle; /* Some clients (like the Spec NFS benchmark) set attributes with the NFSPROC3_SYMLINK request */ if(nfs3_Sattr_To_FSALattr(&attributes_symlink, &parg->arg_symlink3.symlink.symlink_attributes) == 0) { pres->res_create3.status = NFS3ERR_INVAL; rc = NFS_REQ_OK; goto out; } /* Mode is managed above (in cache_inode_create), there is no need * to manage it */ if(attributes_symlink.asked_attributes & FSAL_ATTR_MODE) attributes_symlink.asked_attributes &= ~FSAL_ATTR_MODE; /* Some clients (like Solaris 10) try to set the size of the file to 0 * at creation time. The FSAL create empty file, so we ignore this */ if(attributes_symlink.asked_attributes & FSAL_ATTR_SIZE) attributes_symlink.asked_attributes &= ~FSAL_ATTR_SIZE; if(attributes_symlink.asked_attributes & FSAL_ATTR_SPACEUSED) attributes_symlink.asked_attributes &= ~FSAL_ATTR_SPACEUSED; /* If owner or owner_group are set, and the credential was * squashed, then we must squash the set owner and owner_group. */ squash_setattr(&pworker->export_perms, &pworker->user_credentials, &attributes_symlink); /* Are there attributes to be set (additional to the mode) ? */ if(attributes_symlink.asked_attributes != 0ULL && attributes_symlink.asked_attributes != FSAL_ATTR_MODE) { /* A call to cache_inode_setattr is required */ if(cache_inode_setattr(symlink_pentry, &attributes_symlink, pcontext, FALSE, &cache_status) != CACHE_INODE_SUCCESS) { goto out_error; } } if ((pres->res_symlink3.status = (nfs3_AllocateFH(&pres->res_symlink3.SYMLINK3res_u .resok.obj.post_op_fh3_u.handle))) != NFS3_OK) { pres->res_symlink3.status = NFS3ERR_IO; rc = NFS_REQ_OK; goto out; } if(nfs3_FSALToFhandle (&pres->res_symlink3.SYMLINK3res_u.resok.obj.post_op_fh3_u.handle, pfsal_handle, pexport) == 0) { gsh_free(pres->res_symlink3.SYMLINK3res_u.resok.obj. post_op_fh3_u.handle.data.data_val); pres->res_symlink3.status = NFS3ERR_BADHANDLE; rc = NFS_REQ_OK; goto out; } /* The the parent pentry attributes for building Wcc Data */ if(cache_inode_getattr(parent_pentry, &attr_parent_after, pcontext, &cache_status_parent) != CACHE_INODE_SUCCESS) { gsh_free(pres->res_symlink3.SYMLINK3res_u.resok.obj. post_op_fh3_u.handle.data.data_val); pres->res_symlink3.status = NFS3ERR_BADHANDLE; rc = NFS_REQ_OK; goto out; } /* Set Post Op Fh3 structure */ pres->res_symlink3.SYMLINK3res_u.resok.obj.handle_follows = TRUE; /* Build entry attributes */ nfs_SetPostOpAttr(pexport, &attr_symlink, &(pres->res_symlink3.SYMLINK3res_u .resok.obj_attributes)); /* Build Weak Cache Coherency data */ nfs_SetWccData(pexport, ppre_attr, &attr_parent_after, &(pres->res_symlink3.SYMLINK3res_u.resok.dir_wcc)); pres->res_symlink3.status = NFS3_OK; break; } /* switch */ rc = NFS_REQ_OK; goto out; } } out_error: rc = nfs_SetFailedStatus(pexport, preq->rq_vers, cache_status, &pres->res_stat2, &pres->res_symlink3.status, NULL, ppre_attr, &(pres->res_symlink3.SYMLINK3res_u.resfail.dir_wcc), NULL, NULL); out: /* return references */ if (parent_pentry) cache_inode_put(parent_pentry); if (symlink_pentry) cache_inode_put(symlink_pentry); return (rc); } /* nfs_Symlink */
/** * FSAL_readlink: * Read the content of a symbolic link. * * \param linkhandle (input): * Handle of the link to be read. * \param cred (input): * Authentication context for the operation (user,...). * \param p_link_content (output): * Pointer to an fsal path structure where * the link content is to be stored.. * \param link_attributes (optionnal input/output): * The post operation attributes of the symlink link. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * May be NULL. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - Another error code if an error occured. */ fsal_status_t LUSTREFSAL_readlink(fsal_handle_t * p_linkhandle, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_path_t * p_link_content, /* OUT */ fsal_attrib_list_t * p_link_attributes /* [ IN/OUT ] */ ) { int rc, errsv; fsal_status_t status; char link_content_out[FSAL_MAX_PATH_LEN]; fsal_path_t fsalpath; /* sanity checks. * note : link_attributes is optional. */ if(!p_linkhandle || !p_context || !p_link_content) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink); status = fsal_internal_Handle2FidPath(p_context, p_linkhandle, &fsalpath); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_readlink); memset(link_content_out, 0, FSAL_MAX_PATH_LEN); /* Read the link on the filesystem */ TakeTokenFSCall(); rc = readlink(fsalpath.path, link_content_out, FSAL_MAX_PATH_LEN); errsv = errno; ReleaseTokenFSCall(); /* rc is the length for the symlink content or -1 on error !!! */ if(rc < 0) Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_readlink); /* convert char * to fsal_path_t */ status = FSAL_str2path(link_content_out, FSAL_MAX_PATH_LEN, p_link_content); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_readlink); /* retrieves object attributes, if asked */ if(p_link_attributes) { status = LUSTREFSAL_getattrs(p_linkhandle, p_context, p_link_attributes); /* On error, we set a flag in the returned attributes */ if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(p_link_attributes->asked_attributes); FSAL_SET_MASK(p_link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink); }
/** * Get a valid path associated to an handle. * The function selects many paths from the DB and return the first valid one. If is_dir is set, then only 1 path will be constructed from the database. */ fsal_status_t fsal_internal_getPathFromHandle(posixfsal_op_context_t * p_context, /* IN */ posixfsal_handle_t * p_handle, /* IN */ int is_dir, /* IN */ fsal_path_t * p_fsalpath, /* OUT */ struct stat *p_buffstat /* OUT */ ) { fsal_status_t status; fsal_posixdb_status_t statusdb; int rc, errsv, count, i; fsal_posixdb_fileinfo_t infofs; fsal_path_t paths[global_fs_info.maxlink]; if(!p_context || !p_handle || !p_fsalpath) ReturnCode(ERR_FSAL_FAULT, 0); /* if there is a path in the posixfsal_handle_t variable, then try to use it instead of querying the database for it */ /* Read the path from the Handle. If it's valid & coherent, then no need to query the database ! */ /* if !p_buffstat, we don't need to check the path */ statusdb = fsal_posixdb_getInfoFromHandle(p_context->p_conn, p_handle, paths, (is_dir ? 1 : global_fs_info.maxlink), &count); if(FSAL_POSIXDB_IS_ERROR(statusdb) && FSAL_IS_ERROR(status = posixdb2fsal_error(statusdb))) return status; /* if !p_buffstat, then we do not stat the path to test if file is valid */ if(p_buffstat) { for(i = 0; i < count; i++) { TakeTokenFSCall(); rc = lstat(paths[i].path, p_buffstat); errsv = errno; ReleaseTokenFSCall(); if(rc) { /* error : delete the bad path from the database */ char dirc[FSAL_MAX_PATH_LEN]; char basec[FSAL_MAX_PATH_LEN]; fsal_path_t parentdir; fsal_name_t filename; posixfsal_handle_t parenthdl; char *dname, *bname; /* split /path/to/filename in /path/to & filename */ strncpy(dirc, paths[i].path, FSAL_MAX_PATH_LEN); strncpy(basec, paths[i].path, FSAL_MAX_PATH_LEN); dname = dirname(dirc); bname = basename(basec); status = FSAL_str2path(dname, FSAL_MAX_PATH_LEN, &parentdir); status = FSAL_str2name(bname, FSAL_MAX_NAME_LEN, &filename); /* get the handle of /path/to */ status = POSIXFSAL_lookupPath(&parentdir, p_context, &parenthdl, NULL); if(!FSAL_IS_ERROR(status)) { statusdb = fsal_posixdb_delete(p_context->p_conn, &parenthdl, &filename, NULL); /* no need to check if there was an error, because it doesn't change the behavior of the function */ } } else { /* no error */ FSAL_pathcpy(p_fsalpath, &(paths[0])); break; } } if(i == count) ReturnCode(ERR_FSAL_STALE, 0); /* check consistency */ status = fsal_internal_posix2posixdb_fileinfo(p_buffstat, &infofs); if(FSAL_IS_ERROR(status)) return status; if(fsal_posixdb_consistency_check(&(p_handle->data.info), &infofs)) { /* not consistent !! */ /* delete the stale handle */ statusdb = fsal_posixdb_deleteHandle(p_context->p_conn, p_handle); if(FSAL_POSIXDB_IS_ERROR(statusdb) && FSAL_IS_ERROR(status = posixdb2fsal_error(statusdb))) return status; ReturnCode(ERR_FSAL_STALE, 0); } } else { /* @TODO : check that there si at liste 1 path */ FSAL_pathcpy(p_fsalpath, &(paths[0])); } ReturnCode(ERR_FSAL_NO_ERROR, 0); }
/** * * cache_content_flush: Flushes the content of a file in the local cache to the FSAL data. * * Flushes the content of a file in the local cache to the FSAL data. * This routine should be called only from the cache_inode layer. * * No lock management is done in this layer: the related pentry in the cache inode layer is * locked and will prevent from concurent accesses. * * @param pentry [IN] entry in file content layer whose content is to be flushed. * @param flushhow [IN] should we delete the cached entry in local or not ? * @param pclient [IN] ressource allocated by the client for the nfs management. * @pstatus [OUT] returned status. * * @return CACHE_CONTENT_SUCCESS is successful . * */ cache_content_status_t cache_content_flush(cache_content_entry_t * pentry, cache_content_flush_behaviour_t flushhow, cache_content_client_t * pclient, fsal_op_context_t * pcontext, cache_content_status_t * pstatus) { fsal_handle_t *pfsal_handle = NULL; fsal_status_t fsal_status; fsal_path_t local_path; *pstatus = CACHE_CONTENT_SUCCESS; /* stat */ pclient->stat.func_stats.nb_call[CACHE_CONTENT_FLUSH] += 1; /* Get the fsal handle */ pfsal_handle = &pentry->pentry_inode->handle; /* Lock related Cache Inode pentry to avoid concurrency while read/write operation */ pthread_rwlock_wrlock(&pentry->pentry_inode->content_lock); /* Convert the path to FSAL path */ fsal_status = FSAL_str2path(pentry->local_fs_entry.cache_path_data, MAXPATHLEN, &local_path); if(FSAL_IS_ERROR(fsal_status)) { *pstatus = CACHE_CONTENT_FSAL_ERROR; /* Unlock related Cache Inode pentry */ pthread_rwlock_unlock(&pentry->pentry_inode->content_lock); /* stat */ pclient->stat.func_stats.nb_err_unrecover[CACHE_CONTENT_FLUSH] += 1; return *pstatus; } /* Write the data from the local data file to the fs file */ fsal_status = FSAL_rcp(pfsal_handle, pcontext, &local_path, FSAL_RCP_LOCAL_TO_FS); if(FSAL_IS_ERROR(fsal_status)) { LogMajor(COMPONENT_CACHE_CONTENT, "Error %d,%d from FSAL_rcp when flushing file", fsal_status.major, fsal_status.minor); /* Unlock related Cache Inode pentry */ pthread_rwlock_unlock(&pentry->pentry_inode->content_lock); *pstatus = CACHE_CONTENT_FSAL_ERROR; /* stat */ pclient->stat.func_stats.nb_err_unrecover[CACHE_CONTENT_FLUSH] += 1; return *pstatus; } /* To delete or not to delete ? That is the question ... */ if(flushhow == CACHE_CONTENT_FLUSH_AND_DELETE) { /* Remove the index file from the data cache */ if(unlink(pentry->local_fs_entry.cache_path_index)) { /* Unlock related Cache Inode pentry */ pthread_rwlock_unlock(&pentry->pentry_inode->content_lock); LogCrit(COMPONENT_CACHE_CONTENT, "Can't unlink flushed index %s, errno=%u(%s)", pentry->local_fs_entry.cache_path_index, errno, strerror(errno)); *pstatus = CACHE_CONTENT_LOCAL_CACHE_ERROR; return *pstatus; } /* Remove the data file from the data cache */ if(unlink(pentry->local_fs_entry.cache_path_data)) { /* Unlock related Cache Inode pentry */ pthread_rwlock_unlock(&pentry->pentry_inode->content_lock); LogCrit(COMPONENT_CACHE_CONTENT, "Can't unlink flushed index %s, errno=%u(%s)", pentry->local_fs_entry.cache_path_data, errno, strerror(errno)); *pstatus = CACHE_CONTENT_LOCAL_CACHE_ERROR; return *pstatus; } } /* Unlock related Cache Inode pentry */ pthread_rwlock_unlock(&pentry->pentry_inode->content_lock); /* Exit the function with no error */ pclient->stat.func_stats.nb_success[CACHE_CONTENT_FLUSH] += 1; /* Update the internal metadata */ pentry->internal_md.last_flush_time = time(NULL); pentry->local_fs_entry.sync_state = SYNC_OK; return *pstatus; } /* cache_content_flush */
/** * * cache_content_refresh: Refreshes the whole content of a file in the local cache to the FSAL data. * * Refreshes the whole content of a file in the local cache to the FSAL data. * This routine should be called only from the cache_inode layer. * * No lock management is done in this layer: the related pentry in the cache inode layer is * locked and will prevent from concurent accesses. * * @param pentry [IN] entry in file content layer whose content is to be flushed. * @param pclient [IN] ressource allocated by the client for the nfs management. * @pstatus [OUT] returned status. * * @return CACHE_CONTENT_SUCCESS is successful . * * @todo: BUGAZOMEU: gestion de coherence de date a mettre en place */ cache_content_status_t cache_content_refresh(cache_content_entry_t * pentry, cache_content_client_t * pclient, fsal_op_context_t * pcontext, cache_content_refresh_how_t how, cache_content_status_t * pstatus) { fsal_handle_t *pfsal_handle = NULL; fsal_status_t fsal_status; cache_entry_t *pentry_inode = NULL; fsal_path_t local_path; struct stat buffstat; *pstatus = CACHE_CONTENT_SUCCESS; /* stat */ pclient->stat.func_stats.nb_call[CACHE_CONTENT_REFRESH] += 1; /* Get the related cache inode entry */ pentry_inode = (cache_entry_t *) pentry->pentry_inode; /* Get the fsal handle */ pfsal_handle = &pentry_inode->handle; /* Convert the path to FSAL path */ fsal_status = FSAL_str2path(pentry->local_fs_entry.cache_path_data, MAXPATHLEN, &local_path); if(FSAL_IS_ERROR(fsal_status)) { *pstatus = CACHE_CONTENT_FSAL_ERROR; /* stat */ pclient->stat.func_stats.nb_err_unrecover[CACHE_CONTENT_FLUSH] += 1; return *pstatus; } /* Stat the data file to check for incoherency (this can occur in a crash recovery context) */ if(stat(pentry->local_fs_entry.cache_path_data, &buffstat) == -1) { *pstatus = CACHE_CONTENT_FSAL_ERROR; LogMajor(COMPONENT_CACHE_CONTENT, "cache_content_refresh: could'nt stat on %s, errno=%u(%s)", pentry->local_fs_entry.cache_path_data, errno, strerror(errno)); /* stat */ pclient->stat.func_stats.nb_err_unrecover[CACHE_CONTENT_FLUSH] += 1; return *pstatus; } if(how == FORCE_FROM_FSAL) LogFullDebug(COMPONENT_FSAL,"FORCE FROM FSAL"); else LogFullDebug(COMPONENT_FSAL,"FORCE FROM FSAL INACTIVE"); if((how != FORCE_FROM_FSAL) && (buffstat.st_mtime > (time_t) pentry_inode->attributes.mtime.seconds)) { *pstatus = CACHE_CONTENT_SUCCESS; LogDebug(COMPONENT_CACHE_CONTENT, "Entry %p is more recent in data cache, keeping it", pentry); pentry_inode->attributes.mtime.seconds = buffstat.st_mtime; pentry_inode->attributes.mtime.nseconds = 0; pentry_inode->attributes.atime.seconds = buffstat.st_atime; pentry_inode->attributes.atime.nseconds = 0; pentry_inode->attributes.ctime.seconds = buffstat.st_ctime; pentry_inode->attributes.ctime.nseconds = 0; } else { /* Write the data from the local data file to the fs file */ fsal_status = FSAL_rcp(pfsal_handle, pcontext, &local_path, FSAL_RCP_FS_TO_LOCAL); if(FSAL_IS_ERROR(fsal_status)) { *pstatus = CACHE_CONTENT_FSAL_ERROR; LogMajor(COMPONENT_CACHE_CONTENT, "FSAL_rcp failed for %s: fsal_status.major=%u fsal_status.minor=%u", pentry->local_fs_entry.cache_path_data, fsal_status.major, fsal_status.minor); /* stat */ pclient->stat.func_stats.nb_err_unrecover[CACHE_CONTENT_REFRESH] += 1; return *pstatus; } /* Exit the function with no error */ pclient->stat.func_stats.nb_success[CACHE_CONTENT_REFRESH] += 1; /* Update the internal metadata */ pentry->internal_md.last_refresh_time = time(NULL); pentry->local_fs_entry.sync_state = SYNC_OK; } return *pstatus; } /* cache_content_refresh */
main(int argc, char *argv[]) { char localmachine[256]; cache_inode_client_t client; LRU_parameter_t lru_param; LRU_status_t lru_status; cache_inode_fsal_data_t fsdata; fsal_status_t status; fsal_parameter_t init_param; fsal_name_t name; fsal_path_t path; fsal_attrib_mask_t mask; fsal_path_t pathroot; fsal_attrib_list_t attribs; fsal_handle_t root_handle; cache_inode_endofdir_t eod_met; cache_inode_dir_entry_t dirent_array[100]; cache_inode_dir_entry_t dirent_array_loop[5]; unsigned int nbfound; unsigned int begin_cookie = 0; hash_buffer_t key, value; uid_t uid; fsal_cred_t cred; cache_inode_status_t cache_status; cache_inode_parameter_t cache_param; cache_inode_client_parameter_t cache_client_param; hash_table_t *ht = NULL; fsal_attrib_list_t attrlookup; cache_entry_t *cache_entry_root = NULL; cache_entry_t *cache_entry_lookup = NULL; cache_entry_t *cache_entry_lookup2 = NULL; cache_entry_t *cache_entry_lookup3 = NULL; cache_entry_t *cache_entry_lookup4 = NULL; cache_entry_t *cache_entry_dircont = NULL; cache_inode_gc_policy_t gcpol; char *configfile = argv[1]; int i = 0; int rc = 0; /* Init the Buddy System allocation */ if((rc = BuddyInit(NULL)) != BUDDY_SUCCESS) { LogTest("Error initializing memory allocator"); exit(1); } /* init debug */ SetDefaultLogging("TEST"); SetNamePgm("test_cache_inode"); SetNameFunction("main"); InitLogging(); #if defined( _USE_GHOSTFS ) if(argc != 2) { LogTest("Please set the configuration file as parameter"); exit(1); } #endif /* Obtention du nom de la machine */ if(gethostname(localmachine, sizeof(localmachine)) != 0) { LogError(COMPONENT_STDOUT,ERR_SYS, ERR_GETHOSTNAME, errno); exit(1); } else SetNameHost(localmachine); AddFamilyError(ERR_FSAL, "FSAL related Errors", tab_errstatus_FSAL); AddFamilyError(ERR_CACHE_INODE, "FSAL related Errors", tab_errstatus_cache_inode); /* creating log */ LogTest( "Starting the test"); LogTest( "-----------------"); #if defined( _USE_GHOSTFS ) if(FSAL_IS_ERROR(status = FSAL_str2path(configfile, strlen(configfile) + 1, &(init_param.fs_specific_info. definition_file)))) { LogError(COMPONENT_STDOUT,ERR_FSAL, status.major, status.minor); } #elif defined( _USE_HPSS ) FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, Flags); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, DebugValue); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, TransferType); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, NumRetries); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, BusyDelay); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, BusyRetries); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, TotalDelay); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, GKTotalDelay); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, LimitedRetries); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, MaxConnections); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, ReuseDataConnections); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, UsePortRange); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, RetryStageInp); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, DMAPWriteUpdates); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, ServerName); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, DescName); init_param.fs_specific_info.behaviors.PrincipalName = FSAL_INIT_FORCE_VALUE; strncpy(init_param.fs_specific_info.hpss_config.PrincipalName, HPSS_SSM, HPSS_MAX_PRINCIPAL_NAME); init_param.fs_specific_info.behaviors.KeytabPath = FSAL_INIT_FORCE_VALUE; strncpy(init_param.fs_specific_info.hpss_config.KeytabPath, HPSS_KEYTAB, HPSS_MAX_PATH_NAME); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, DebugPath); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, HostName); FSAL_SET_INIT_DEFAULT(init_param.fs_specific_info, RegistrySiteName); #endif /* 2-common info (default) */ FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxfilesize); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxlink); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxnamelen); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxpathlen); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, no_trunc); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, chown_restricted); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, case_insensitive); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, case_preserving); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, fh_expire_type); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, link_support); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, symlink_support); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, named_attr); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, unique_handles); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, lease_time); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, acl_support); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, cansettime); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, homogenous); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxread); FSAL_SET_INIT_DEFAULT(init_param.fs_common_info, maxwrite); /* Init */ if(FSAL_IS_ERROR(status = FSAL_Init(&init_param))) { LogError(COMPONENT_STDOUT,ERR_FSAL, status.major, status.minor); } /* getting creds */ uid = getuid(); if(FSAL_IS_ERROR(status = FSAL_GetUserCred(uid, NULL, &cred))) { LogError(COMPONENT_STDOUT,ERR_FSAL, status.major, status.minor); } /* Init of the cache inode module */ cache_param.hparam.index_size = 31; cache_param.hparam.alphabet_length = 10; /* Buffer seen as a decimal polynom */ cache_param.hparam.nb_node_prealloc = 100; cache_param.hparam.hash_func_key = cache_inode_fsal_hash_func; cache_param.hparam.hash_func_rbt = cache_inode_fsal_rbt_func; cache_param.hparam.hash_func_both = NULL ; /* BUGAZOMEU */ cache_param.hparam.compare_key = cache_inode_compare_key_fsal; cache_param.hparam.key_to_str = display_key; cache_param.hparam.val_to_str = display_value; if((ht = cache_inode_init(cache_param, &cache_status)) == NULL) { LogTest( "Error %d while init hash ", cache_status); } else LogTest( "Hash Table address = %p", ht); /* We need a cache_client to acces the cache */ cache_client_param.attrmask = FSAL_ATTRS_MANDATORY | FSAL_ATTR_MTIME | FSAL_ATTR_CTIME | FSAL_ATTR_ATIME; cache_client_param.nb_prealloc_entry = 1000; cache_client_param.nb_pre_dir_data = 200; cache_client_param.nb_pre_parent = 1200; cache_client_param.nb_pre_state_v4 = 100; cache_client_param.lru_param.nb_entry_prealloc = 1000; cache_client_param.lru_param.entry_to_str = lru_entry_to_str; cache_client_param.lru_param.clean_entry = lru_clean_entry; cache_client_param.grace_period_attr = 0; cache_client_param.grace_period_link = 0; cache_client_param.grace_period_dirent = 0; cache_client_param.expire_type_attr = CACHE_INODE_EXPIRE_NEVER; cache_client_param.expire_type_link = CACHE_INODE_EXPIRE_NEVER; cache_client_param.expire_type_dirent = CACHE_INODE_EXPIRE_NEVER; /* Init the cache_inode client */ if(cache_inode_client_init(&client, cache_client_param, 0, NULL) != 0) exit(1); /* Init the gc */ gcpol.file_expiration_delay = 3; gcpol.directory_expiration_delay = 4; gcpol.hwmark_nb_entries = 6; gcpol.lwmark_nb_entries = 3; gcpol.run_interval = 4; cache_inode_set_gc_policy(gcpol); /* Getting the root of the FS */ if((FSAL_IS_ERROR(status = FSAL_str2path("/", 2, &pathroot)))) { LogError(COMPONENT_STDOUT,ERR_FSAL, status.major, status.minor); exit(1); } if((FSAL_IS_ERROR(status = FSAL_lookupPath(&pathroot, &cred, &root_handle, &attribs)))) { LogError(COMPONENT_STDOUT,ERR_FSAL, status.major, status.minor); exit(1); } fsdata.cookie = 0; fsdata.handle = root_handle; /* Cache the root of the FS */ if((cache_entry_root = cache_inode_make_root(&fsdata, 1, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't init fs's root"); exit(1); } /* A lookup in the root fsal */ if((FSAL_IS_ERROR(status = FSAL_str2name("cea", 10, &name)))) { LogError(COMPONENT_STDOUT,ERR_FSAL, status.major, status.minor); exit(1); } if((cache_entry_lookup = cache_inode_lookup(cache_entry_root, &name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } /* Lookup a second time (entry should now be cached) */ if((cache_entry_lookup2 = cache_inode_lookup(cache_entry_root, &name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } if(cache_entry_lookup2 != cache_entry_lookup) { LogTest("Error: lookup results should be the same"); exit(1); } /* A lookup in the root fsal */ if((FSAL_IS_ERROR(status = FSAL_str2name("log", 10, &name)))) { LogError(COMPONENT_STDOUT,ERR_FSAL, status.major, status.minor); exit(1); } if((cache_entry_lookup3 = cache_inode_lookup(cache_entry_root, &name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } if((cache_entry_lookup4 = cache_inode_lookup(cache_entry_root, &name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } if(cache_entry_lookup3 != cache_entry_lookup4) { LogTest("Error: lookup results should be the same"); exit(1); } /* A lookup in the root fsal */ if((FSAL_IS_ERROR(status = FSAL_str2name("SunOS_5", 10, &name)))) { LogError(COMPONENT_STDOUT,ERR_FSAL, status.major, status.minor); exit(1); } cache_inode_print_dir(cache_entry_root); /* Test readdir */ if(cache_inode_readdir(cache_entry_root, 0, 100, &nbfound, &eod_met, dirent_array, ht, &client, &cred, &cache_status) != CACHE_INODE_SUCCESS) { LogTest( "Error: cache_inode_readdir failed"); exit(1); } LogTest( "Readdir nbfound=%d, eod_met=%d", nbfound, eod_met); for(i = 0; i < nbfound; i++) LogTest( "dirent_array[%d] ==> %s | %p", i, dirent_array[i].name.name, dirent_array[i].pentry); cache_inode_print_dir(cache_entry_root); /* looping on readir */ LogTest( "Loop directory in several pass"); eod_met = TO_BE_CONTINUED; begin_cookie = 0; do { if(cache_inode_readdir(cache_entry_root, begin_cookie, 2, &nbfound, &eod_met, dirent_array_loop, ht, &client, &cred, &cache_status) != CACHE_INODE_SUCCESS) { LogTest("Error: cache_inode_readdir failed: %d", cache_status); exit(1); } for(i = 0; i < nbfound; i++) LogTest( " ==> %s | %p", dirent_array_loop[i].name.name, dirent_array_loop[i].pentry); begin_cookie += nbfound; } while(eod_met == TO_BE_CONTINUED); LogTest( "---------------------------------"); /* A lookup in the root fsal */ if((FSAL_IS_ERROR(status = FSAL_str2name("cea", 10, &name)))) { LogError(COMPONENT_STDOUT,ERR_FSAL, status.major, status.minor); exit(1); } if((cache_entry_lookup = cache_inode_lookup(cache_entry_root, &name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } /* A lookup in the root fsal */ if((FSAL_IS_ERROR(status = FSAL_str2name("log", 10, &name)))) { LogError(COMPONENT_STDOUT,ERR_FSAL, status.major, status.minor); exit(1); } if((cache_entry_lookup = cache_inode_lookup(cache_entry_root, &name, &attrlookup, ht, &client, &cred, &cache_status)) == NULL) { LogTest( "Error: can't lookup"); exit(1); } /* Print the Hash Table */ HashTable_Log(COMPONENT_STDOUT, ht); #ifdef _ADDITIONAL_TEST /* Trying to lookup from a DIR_CONTINUE */ fsdata.handle = cache_entry_root->object.dir_begin.handle; fsdata.cookie = 3 * CHILDREN_ARRAY_SIZE; LogTest("Input key: (Handle=%p, Cookie=%d)", fsdata.handle, fsdata.cookie); /* Turn the input to a hash key */ if(cache_inode_fsaldata_2_key(&key, &fsdata, NULL)) { LogTest( "Impossible to allocate a key to that value"); exit(1); } if(HashTable_Get(ht, &key, &value) != HASHTABLE_SUCCESS) { LogTest( "Key could not be found"); exit(1); } /* pentry for the dir cont */ cache_entry_dircont = (cache_entry_t *) value.pdata; /* Test readdir */ if(cache_inode_readdir(cache_entry_dircont, fsdata.cookie, 100, &nbfound, &eod_met, dirent_array, ht, &client, &cred, &cache_status) != CACHE_INODE_SUCCESS) { LogTest( "Error: cache_inode_readdir failed"); exit(1); } #endif LogTest( "Readdir nbfound=%d, eod_met=%d", nbfound, eod_met); for(i = 0; i < nbfound; i++) LogTest( "dirent_array[%d] ==> %s | %p ", i, dirent_array[i].name.name, dirent_array[i].pentry); /* Call the GC */ LogTest( "Sleeping %d second before gc (for gc invalidation)", gcpol.file_expiration_delay + 2); sleep(gcpol.file_expiration_delay + 2); if(cache_inode_gc(ht, &client, &cache_status) != CACHE_INODE_SUCCESS) { LogTest( "Error: cache_inode_gc failed"); exit(1); } LogTest( "GC performed successfully"); /* Print the Hash Table */ HashTable_Log(COMPONENT_STDOUT, ht); /* Another readdir, after gc is made */ eod_met = TO_BE_CONTINUED; begin_cookie = 0; LogTest( "ANOTHER READDIR AFTER GC"); do { if(cache_inode_readdir(cache_entry_root, begin_cookie, 2, &nbfound, &eod_met, dirent_array_loop, ht, &client, &cred, &cache_status) != CACHE_INODE_SUCCESS) { LogTest("Error: cache_inode_readdir failed: %d", cache_status); exit(1); } for(i = 0; i < nbfound; i++) LogTest( " ==> %s | %p", dirent_array_loop[i].name.name, dirent_array_loop[i].pentry); begin_cookie += nbfound; } while(eod_met == TO_BE_CONTINUED); LogTest( "---------------------------------"); /* Print the Hash Table */ HashTable_Log(COMPONENT_STDOUT, ht); LogTest( "---------------------------------"); /* The end of all the tests */ LogTest( "All tests exited successfully"); exit(0); } /* main */
/** * @brief The Rquota getquota function, for all versions. * * The RQUOTA getquota function, for all versions. * * @param[in] parg Ignored * @param[in] pexport Ignored * @param[in] pcontext Ignored * @param[in] pworker Ignored * @param[in] preq Ignored * @param[out] pres Ignored * */ int rquota_getquota(nfs_arg_t *parg, exportlist_t *pexport, fsal_op_context_t *pcontext, nfs_worker_data_t *pworker, struct svc_req *preq, nfs_res_t * pres) { fsal_status_t fsal_status; fsal_quota_t fsal_quota; fsal_path_t fsal_path; int quota_type = USRQUOTA; int quota_id; char work[MAXPATHLEN]; LogFullDebug(COMPONENT_NFSPROTO, "REQUEST PROCESSING: Calling rquota_getquota"); if(preq->rq_vers == EXT_RQUOTAVERS) { quota_type = parg->arg_ext_rquota_getquota.gqa_type; quota_id = parg->arg_ext_rquota_getquota.gqa_id; } else { quota_type = USRQUOTA; quota_id = parg->arg_rquota_getquota.gqa_uid; } if(parg->arg_rquota_getquota.gqa_pathp[0] == '/') strncpy(work, parg->arg_rquota_getquota.gqa_pathp, MAXPATHLEN); else { if(nfs_export_tag2path(nfs_param.pexportlist, parg->arg_rquota_getquota.gqa_pathp, strnlen(parg->arg_rquota_getquota.gqa_pathp, MAXPATHLEN), work, MAXPATHLEN) == -1) { pres->res_rquota_getquota.status = Q_EPERM; return NFS_REQ_OK; } } if(FSAL_IS_ERROR((fsal_status = FSAL_str2path(work, MAXPATHLEN, &fsal_path)))) { pres->res_rquota_getquota.status = Q_EPERM; return NFS_REQ_OK; } fsal_status = FSAL_get_quota(&fsal_path, quota_type, quota_id, &fsal_quota); if(FSAL_IS_ERROR(fsal_status)) { if(fsal_status.major == ERR_FSAL_NO_QUOTA) pres->res_rquota_getquota.status = Q_NOQUOTA; else pres->res_rquota_getquota.status = Q_EPERM; return NFS_REQ_OK; } /* success */ pres->res_rquota_getquota.status = Q_OK; pres->res_rquota_getquota.getquota_rslt_u.gqr_rquota.rq_active = TRUE; pres->res_rquota_getquota.getquota_rslt_u.gqr_rquota.rq_bsize = fsal_quota.bsize; pres->res_rquota_getquota.getquota_rslt_u.gqr_rquota.rq_bhardlimit = fsal_quota.bhardlimit; pres->res_rquota_getquota.getquota_rslt_u.gqr_rquota.rq_bsoftlimit = fsal_quota.bsoftlimit; pres->res_rquota_getquota.getquota_rslt_u.gqr_rquota.rq_curblocks = fsal_quota.curblocks; pres->res_rquota_getquota.getquota_rslt_u.gqr_rquota.rq_curfiles = fsal_quota.curfiles; pres->res_rquota_getquota.getquota_rslt_u.gqr_rquota.rq_fhardlimit = fsal_quota.fhardlimit; pres->res_rquota_getquota.getquota_rslt_u.gqr_rquota.rq_fsoftlimit = fsal_quota.fsoftlimit; pres->res_rquota_getquota.getquota_rslt_u.gqr_rquota.rq_btimeleft = fsal_quota.btimeleft; pres->res_rquota_getquota.getquota_rslt_u.gqr_rquota.rq_ftimeleft = fsal_quota.ftimeleft; return NFS_REQ_OK; } /* rquota_getquota */
/** * * cache_content_rdwr: Reads/Writes through the cache layer. * * Reads/Writes through the cache layer. * This routine should be called only from the cache_inode layer. * * No lock management is done in this layer: the related pentry in the cache inode layer is * locked and will prevent from concurent accesses. * * @param pentry [IN] entry in file content layer whose content is to be accessed. * @param read_or_write [IN] a flag of type cache_content_io_direction_t to tell if a read or write is to be done. * @param seek_descriptor [IN] absolute position (in the FSAL file) where the IO will be done. * @param pio_size_in [IN] requested io size * @param pio_size_out [OUT] the size of the io that was successfully made. * @param pbuffstat [OUT] the 'stat' of entry in the data cache after the operation * @param buffer write:[IN] read:[OUT] the buffer for the data. * @param pclient [IN] ressource allocated by the client for the nfs management. * @param pcontext [IN] fsal credentials for the operation. * @pstatus [OUT] returned status. * * @return CACHE_CONTENT_SUCCESS is successful . * */ cache_content_status_t cache_content_rdwr(cache_content_entry_t * pentry, cache_content_io_direction_t read_or_write, fsal_seek_t * seek_descriptor, fsal_size_t * pio_size_in, fsal_size_t * pio_size_out, caddr_t buffer, fsal_boolean_t * p_fsal_eof, struct stat * pbuffstat, cache_content_client_t * pclient, fsal_op_context_t * pcontext, cache_content_status_t * pstatus) { fsal_handle_t *pfsal_handle = NULL; fsal_status_t fsal_status; cache_inode_status_t cache_inode_status; cache_content_status_t cache_content_status; fsal_path_t local_path; int statindex; off_t offset; size_t iosize_before; ssize_t iosize_after; struct stat buffstat; int rc; char c; *pstatus = CACHE_CONTENT_SUCCESS; LogFullDebug(COMPONENT_CACHE_CONTENT, "---> DATA : IO Size IN = %llu fdsize=%zu seeksize=%zu", *pio_size_in, sizeof(fsal_file_t), sizeof(fsal_seek_t)); /* For now, only FSAL_SEEK_SET is supported */ if(seek_descriptor->whence != FSAL_SEEK_SET) { LogDebug(COMPONENT_CACHE_CONTENT, "Implementation trouble: seek_descriptor was not a 'FSAL_SEEK_SET' cursor"); *pstatus = CACHE_INODE_INVALID_ARGUMENT; return *pstatus; } /* Set the statindex variable */ switch (read_or_write) { case CACHE_CONTENT_READ: statindex = CACHE_CONTENT_READ_ENTRY; break; case CACHE_CONTENT_WRITE: statindex = CACHE_CONTENT_WRITE_ENTRY; break; default: *pstatus = CACHE_CONTENT_INVALID_ARGUMENT; return *pstatus; break; } /* stat */ pclient->stat.func_stats.nb_call[statindex] += 1; /* Get the fsal handle */ if((pfsal_handle = cache_inode_get_fsal_handle(pentry->pentry_inode, &cache_inode_status)) == NULL) { *pstatus = CACHE_CONTENT_BAD_CACHE_INODE_ENTRY; LogMajor(COMPONENT_CACHE_CONTENT, "cache_content_rdwr: cannot get handle"); /* stat */ pclient->stat.func_stats.nb_err_unrecover[statindex] += 1; return *pstatus; } /* Convert the path to FSAL path */ fsal_status = FSAL_str2path(pentry->local_fs_entry.cache_path_data, MAXPATHLEN, &local_path); if(FSAL_IS_ERROR(fsal_status)) { *pstatus = CACHE_CONTENT_FSAL_ERROR; /* stat */ pclient->stat.func_stats.nb_err_unrecover[statindex] += 1; return *pstatus; } /* Parameters conversion */ offset = cache_content_fsal_seek_convert(*seek_descriptor, pstatus); if(*pstatus != CACHE_CONTENT_SUCCESS) { /* stat */ pclient->stat.func_stats.nb_err_unrecover[statindex] += 1; return *pstatus; } iosize_before = cache_content_fsal_size_convert(*pio_size_in, pstatus); if(*pstatus != CACHE_CONTENT_SUCCESS) { /* stat */ pclient->stat.func_stats.nb_err_unrecover[statindex] += 1; return *pstatus; } /* Open the local fd for reading */ if(cache_content_open(pentry, pclient, pstatus) != CACHE_CONTENT_SUCCESS) { return *pstatus; } /* Perform the IO through the cache */ if(read_or_write == CACHE_CONTENT_READ) { /* The file content was completely read before the IO. The read operation is fully done locally */ if((iosize_after = pread(pentry->local_fs_entry.opened_file.local_fd, buffer, iosize_before, offset)) == -1) { /* stat */ pclient->stat.func_stats.nb_err_unrecover[statindex] += 1; *pstatus = CACHE_CONTENT_LOCAL_CACHE_ERROR; return *pstatus; } if((cache_content_status = cache_content_valid(pentry, CACHE_CONTENT_OP_GET, pclient)) != CACHE_CONTENT_SUCCESS) { *pstatus = cache_content_status; return *pstatus; } /* Get the eof */ if(iosize_after == 0) *p_fsal_eof = TRUE; else { rc = pread(pentry->local_fs_entry.opened_file.local_fd, &c, 1, offset + iosize_before); if(rc == 0) *p_fsal_eof = TRUE; else *p_fsal_eof = FALSE; } } else { /* The io is done on the cache before being flushed to the FSAL */ if((iosize_after = pwrite(pentry->local_fs_entry.opened_file.local_fd, buffer, iosize_before, offset)) == -1) { /* stat */ pclient->stat.func_stats.nb_err_unrecover[statindex] += 1; *pstatus = CACHE_CONTENT_LOCAL_CACHE_ERROR; return *pstatus; } if((cache_content_status = cache_content_valid(pentry, CACHE_CONTENT_OP_SET, pclient)) != CACHE_CONTENT_SUCCESS) { *pstatus = cache_content_status; return *pstatus; } /* p_fsal_eof has no meaning here, it is unused */ } /* close the local fd */ if(cache_content_close(pentry, pclient, pstatus) != CACHE_CONTENT_SUCCESS) return *pstatus; *pio_size_out = (fsal_size_t) iosize_after; /* Return the 'stat' as seen in the cache */ if(stat(pentry->local_fs_entry.cache_path_data, &buffstat) == -1) { *pstatus = CACHE_CONTENT_LOCAL_CACHE_ERROR; } else { if(pbuffstat != NULL) *pbuffstat = buffstat; } return *pstatus; } /* cache_content_rdwr */