fsal_status_t MFSL_readdir(fsal_dir_t * dir_descriptor, /* IN */ fsal_cookie_t start_position, /* IN */ fsal_attrib_mask_t get_attr_mask, /* IN */ fsal_mdsize_t buffersize, /* IN */ fsal_dirent_t * pdirent, /* OUT */ fsal_cookie_t * end_position, /* OUT */ fsal_count_t * nb_entries, /* OUT */ fsal_boolean_t * end_of_dir, /* OUT */ mfsl_context_t * p_mfsl_context, /* IN */ void * pextra ) { struct timeval start, stop, delta ; fsal_status_t fsal_status = { ERR_FSAL_NO_ERROR, 0 } ; gettimeofday( &start, 0 ) ; fsal_status = FSAL_readdir(dir_descriptor, start_position, get_attr_mask, buffersize, pdirent, end_position, nb_entries, end_of_dir); gettimeofday( &stop, 0 ) ; delta = mfsl_timer_diff( &stop, &start ) ; LogFullDebug( COMPONENT_MFSL, "%s: duration=%ld.%06ld", __FUNCTION__, delta.tv_sec, delta.tv_usec ) ; return fsal_status ; } /* MFSL_readdir */
fsal_status_t MFSL_readdir(fsal_dir_t * dir_descriptor, /* IN */ fsal_cookie_t start_position, /* IN */ fsal_attrib_mask_t get_attr_mask, /* IN */ fsal_mdsize_t buffersize, /* IN */ fsal_dirent_t * pdirent, /* OUT */ fsal_cookie_t * end_position, /* OUT */ fsal_count_t * nb_entries, /* OUT */ fsal_boolean_t * end_of_dir, /* OUT */ mfsl_context_t * p_mfsl_context, /* IN */ void * pextra ) { return FSAL_readdir(dir_descriptor, start_position, get_attr_mask, buffersize, pdirent, end_position, nb_entries, end_of_dir); } /* MFSL_readdir */
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; }
/** * * cache_inode_readdir_populate: fully reads a directory in FSAL and caches * the related entries. * * fully reads a directory in FSAL and caches the related entries. No MT * safety managed here !! * * @param pentry [IN] entry for the parent directory to be read. This must be * a DIRECTORY * @param ht [IN] hash table used for the cache, unused in this call. * @param pclient [INOUT] ressource allocated by the client for the nfs * management. * @param pcontext [IN] FSAL credentials * @param pstatus [OUT] returned status. * */ cache_inode_status_t cache_inode_readdir_populate( cache_entry_t * pentry_dir, cache_inode_policy_t policy, hash_table_t * ht, cache_inode_client_t * pclient, fsal_op_context_t * pcontext, cache_inode_status_t * pstatus) { fsal_dir_t fsal_dirhandle; fsal_status_t fsal_status; fsal_attrib_list_t dir_attributes; fsal_cookie_t begin_cookie; fsal_cookie_t end_cookie; fsal_count_t nbfound; fsal_count_t iter; fsal_boolean_t fsal_eod; cache_entry_t *pentry = NULL; cache_entry_t *pentry_parent = pentry_dir; fsal_attrib_list_t object_attributes; cache_inode_create_arg_t create_arg; cache_inode_file_type_t type; cache_inode_status_t cache_status; fsal_dirent_t array_dirent[FSAL_READDIR_SIZE + 20]; cache_inode_fsal_data_t new_entry_fsdata; cache_inode_dir_entry_t *new_dir_entry = NULL; uint64_t i = 0; /* Set the return default to CACHE_INODE_SUCCESS */ *pstatus = CACHE_INODE_SUCCESS; /* Only DIRECTORY entries are concerned */ if(pentry_dir->internal_md.type != DIRECTORY) { *pstatus = CACHE_INODE_BAD_TYPE; return *pstatus; } #ifdef _USE_MFSL_ASYNC /* If entry is asynchronous (via MFSL), it should not be repopulated until it is synced */ if(MFSL_ASYNC_is_synced(&pentry_dir->mobject) == FALSE) { /* Directory is asynchronous, do not repopulate it and let it * in the state 'has_been_readdir == FALSE' */ *pstatus = CACHE_INODE_SUCCESS; return *pstatus; } #endif /* If directory is already populated , there is no job to do */ if(pentry_dir->object.dir.has_been_readdir == CACHE_INODE_YES) { *pstatus = CACHE_INODE_SUCCESS; return *pstatus; } /* Invalidate all the dirents */ if(cache_inode_invalidate_all_cached_dirent(pentry_dir, ht, pclient, pstatus) != CACHE_INODE_SUCCESS) return *pstatus; /* Open the directory */ dir_attributes.asked_attributes = pclient->attrmask; #ifdef _USE_MFSL fsal_status = MFSL_opendir(&pentry_dir->mobject, pcontext, &pclient->mfsl_context, &fsal_dirhandle, &dir_attributes, NULL); #else fsal_status = FSAL_opendir(&pentry_dir->object.dir.handle, pcontext, &fsal_dirhandle, &dir_attributes); #endif if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); if(fsal_status.major == ERR_FSAL_STALE) { cache_inode_status_t kill_status; LogEvent(COMPONENT_CACHE_INODE, "cache_inode_readdir: Stale FSAL File Handle detected for pentry = %p, fsal_status=(%u,%u)", pentry_dir, fsal_status.major, fsal_status.minor); if(cache_inode_kill_entry(pentry_dir, WT_LOCK, ht, pclient, &kill_status) != CACHE_INODE_SUCCESS) LogCrit(COMPONENT_CACHE_INODE, "cache_inode_readdir: Could not kill entry %p, status = %u", pentry_dir, kill_status); *pstatus = CACHE_INODE_FSAL_ESTALE; } return *pstatus; } /* Loop for readding the directory */ FSAL_SET_COOKIE_BEGINNING(begin_cookie); FSAL_SET_COOKIE_BEGINNING(end_cookie); fsal_eod = FALSE; do { #ifdef _USE_MFSL fsal_status = MFSL_readdir(&fsal_dirhandle, begin_cookie, pclient->attrmask, FSAL_READDIR_SIZE * sizeof(fsal_dirent_t), array_dirent, &end_cookie, &nbfound, &fsal_eod, &pclient->mfsl_context, NULL); #else fsal_status = FSAL_readdir(&fsal_dirhandle, begin_cookie, pclient->attrmask, FSAL_READDIR_SIZE * sizeof(fsal_dirent_t), array_dirent, &end_cookie, &nbfound, &fsal_eod); #endif if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); return *pstatus; } for(iter = 0; iter < nbfound; iter++) { LogFullDebug(COMPONENT_NFS_READDIR, "cache readdir populate found entry %s", array_dirent[iter].name.name); /* It is not needed to cache '.' and '..' */ if(!FSAL_namecmp(&(array_dirent[iter].name), (fsal_name_t *) & FSAL_DOT) || !FSAL_namecmp(&(array_dirent[iter].name), (fsal_name_t *) & FSAL_DOT_DOT)) { LogFullDebug(COMPONENT_NFS_READDIR, "cache readdir populate : do not cache . and .."); continue; } /* If dir entry is a symbolic link, its content has to be read */ if((type = cache_inode_fsal_type_convert(array_dirent[iter].attributes.type)) == SYMBOLIC_LINK) { #ifdef _USE_MFSL mfsl_object_t tmp_mfsl; #endif /* Let's read the link for caching its value */ object_attributes.asked_attributes = pclient->attrmask; if( CACHE_INODE_KEEP_CONTENT( pentry_dir->policy ) ) { #ifdef _USE_MFSL tmp_mfsl.handle = array_dirent[iter].handle; fsal_status = MFSL_readlink(&tmp_mfsl, pcontext, &pclient->mfsl_context, &create_arg.link_content, &object_attributes, NULL); #else fsal_status = FSAL_readlink(&array_dirent[iter].handle, pcontext, &create_arg.link_content, &object_attributes); #endif } else { fsal_status.major = ERR_FSAL_NO_ERROR ; fsal_status.minor = 0 ; } if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); if(fsal_status.major == ERR_FSAL_STALE) { cache_inode_status_t kill_status; LogEvent(COMPONENT_CACHE_INODE, "cache_inode_readdir: Stale FSAL File Handle detected for pentry = %p, fsal_status=(%u,%u)", pentry_dir, fsal_status.major, fsal_status.minor ); if(cache_inode_kill_entry(pentry_dir, WT_LOCK, ht, pclient, &kill_status) != CACHE_INODE_SUCCESS) LogCrit(COMPONENT_CACHE_INODE, "cache_inode_readdir: Could not kill entry %p, status = %u", pentry_dir, kill_status); *pstatus = CACHE_INODE_FSAL_ESTALE; } return *pstatus; } } /* Try adding the entry, if it exists then this existing entry is returned */ new_entry_fsdata.handle = array_dirent[iter].handle; new_entry_fsdata.cookie = 0; /* XXX needed? */ if((pentry = cache_inode_new_entry( &new_entry_fsdata, &array_dirent[iter].attributes, type, policy, &create_arg, NULL, ht, pclient, pcontext, FALSE, /* This is population and no creation */ pstatus)) == NULL) return *pstatus; cache_status = cache_inode_add_cached_dirent( pentry_parent, &(array_dirent[iter].name), pentry, ht, &new_dir_entry, pclient, pcontext, pstatus); if(cache_status != CACHE_INODE_SUCCESS && cache_status != CACHE_INODE_ENTRY_EXISTS) return *pstatus; /* * Remember the FSAL readdir cookie associated with this dirent. This * is needed for partial directory reads. * * to_uint64 should be a lightweight operation--it is in the current * default implementation. We think the right thing -should- happen * therefore with if _USE_MFSL. * * I'm ignoring the status because the default operation is a memcmp-- * we lready -have- the cookie. */ if (cache_status != CACHE_INODE_ENTRY_EXISTS) { (void) FSAL_cookie_to_uint64(&array_dirent[iter].handle, pcontext, &array_dirent[iter].cookie, &new_dir_entry->fsal_cookie); /* we are filling in all entries, and the cookie avl was * cleared before adding dirents */ new_dir_entry->cookie = i; /* still an offset */ (void) avltree_insert(&new_dir_entry->node_c, &pentry_parent->object.dir.cookies); } /* !exist */ } /* iter */ /* Get prepared for next step */ begin_cookie = end_cookie; /* next offset */ i++; } while(fsal_eod != TRUE); /* Close the directory */ #ifdef _USE_MFSL fsal_status = MFSL_closedir(&fsal_dirhandle, &pclient->mfsl_context, NULL); #else fsal_status = FSAL_closedir(&fsal_dirhandle); #endif if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); return *pstatus; } /* End of work */ pentry_dir->object.dir.has_been_readdir = CACHE_INODE_YES; *pstatus = CACHE_INODE_SUCCESS; return *pstatus; } /* cache_inode_readdir_populate */
/** * * cache_inode_readdir_nonamecache: Reads a directory without populating the name cache (no dirents created). * * Reads a directory without populating the name cache (no dirents created). * * @param pentry [IN] entry for the parent directory to be read. * @param cookie [IN] cookie for the readdir operation (basically the offset). * @param nbwanted [IN] Maximum number of directory entries wanted. * @param peod_met [OUT] A flag to know if end of directory was met during this call. * @param dirent_array [OUT] the resulting array of found directory entries. * @param ht [IN] hash table used for the cache, unused in this call. * @param unlock [OUT] the caller shall release read-lock on pentry when done * @param pclient [INOUT] ressource allocated by the client for the nfs management. * @param pcontext [IN] FSAL credentials * @param pstatus [OUT] returned status. * * @return CACHE_INODE_SUCCESS if operation is a success \n * */ static cache_inode_status_t cache_inode_readdir_nonamecache( cache_entry_t * pentry_dir, cache_inode_policy_t policy, uint64_t cookie, unsigned int nbwanted, unsigned int *pnbfound, uint64_t *pend_cookie, cache_inode_endofdir_t *peod_met, cache_inode_dir_entry_t **dirent_array, hash_table_t *ht, int *unlock, cache_inode_client_t *pclient, fsal_op_context_t *pcontext, cache_inode_status_t *pstatus) { fsal_dir_t fsal_dirhandle; fsal_status_t fsal_status; fsal_attrib_list_t dir_attributes; fsal_cookie_t begin_cookie; fsal_cookie_t end_cookie; fsal_count_t iter; fsal_boolean_t fsal_eod; fsal_dirent_t fsal_dirent_array[FSAL_READDIR_SIZE + 20]; cache_inode_fsal_data_t entry_fsdata; /* Set the return default to CACHE_INODE_SUCCESS */ *pstatus = CACHE_INODE_SUCCESS; /* Only DIRECTORY entries are concerned */ if(pentry_dir->internal_md.type != DIRECTORY) { *pstatus = CACHE_INODE_BAD_TYPE; return *pstatus; } LogFullDebug(COMPONENT_NFS_READDIR, "About to readdir in cache_inode_readdir_nonamecache: pentry=%p " "cookie=%"PRIu64, pentry_dir, cookie ) ; /* Open the directory */ dir_attributes.asked_attributes = pclient->attrmask; #ifdef _USE_MFSL fsal_status = MFSL_opendir(&pentry_dir->mobject, pcontext, &pclient->mfsl_context, &fsal_dirhandle, &dir_attributes, NULL); #else fsal_status = FSAL_opendir(&pentry_dir->object.dir.handle, pcontext, &fsal_dirhandle, &dir_attributes); #endif if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); if(fsal_status.major == ERR_FSAL_STALE) { cache_inode_status_t kill_status; LogEvent(COMPONENT_CACHE_INODE, "cache_inode_readdir: Stale FSAL File Handle detected for pentry = %p, fsal_status=(%u,%u)", pentry_dir, fsal_status.major, fsal_status.minor); if(cache_inode_kill_entry(pentry_dir, WT_LOCK, ht, pclient, &kill_status) != CACHE_INODE_SUCCESS) LogCrit(COMPONENT_CACHE_INODE, "cache_inode_readdir: Could not kill entry %p, status = %u", pentry_dir, kill_status); *pstatus = CACHE_INODE_FSAL_ESTALE; } return *pstatus; } /* Loop for readding the directory */ // memcpy( &(begin_cookie.data), &cookie, sizeof( uint64_t ) ) ; FSAL_SET_COOKIE_BY_OFFSET( begin_cookie, cookie ) ; fsal_eod = FALSE; #ifdef _USE_MFSL fsal_status = MFSL_readdir( &fsal_dirhandle, begin_cookie, pclient->attrmask, nbwanted * sizeof(fsal_dirent_t), fsal_dirent_array, &end_cookie, (fsal_count_t *)pnbfound, &fsal_eod, &pclient->mfsl_context, NULL); #else fsal_status = FSAL_readdir( &fsal_dirhandle, begin_cookie, pclient->attrmask, nbwanted * sizeof(fsal_dirent_t), fsal_dirent_array, &end_cookie, (fsal_count_t *)pnbfound, &fsal_eod); #endif if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); return *pstatus; } for( iter = 0 ; iter < *pnbfound ; iter ++ ) { /* cache_inode_readdir does not return . or .. */ if(!FSAL_namecmp(&(fsal_dirent_array[iter].name), (fsal_name_t *) & FSAL_DOT) || !FSAL_namecmp(&(fsal_dirent_array[iter].name), (fsal_name_t *) & FSAL_DOT_DOT)) continue; /* Get the related pentry without populating the name cache (but eventually populating the attrs cache */ entry_fsdata.handle = fsal_dirent_array[iter].handle; entry_fsdata.cookie = 0; /* XXX needed? */ /* Allocate a dirent to be returned to the client */ /** @todo Make sure this piece of memory once the data are used */ GetFromPool( dirent_array[iter], &pclient->pool_dir_entry, cache_inode_dir_entry_t); if( dirent_array[iter] == NULL ) { *pstatus = CACHE_INODE_MALLOC_ERROR; return *pstatus; } /* fills in the dirent_array */ if( ( dirent_array[iter]->pentry= cache_inode_get( &entry_fsdata, policy, &fsal_dirent_array[iter].attributes, ht, pclient, pcontext, pstatus ) ) == NULL ) return *pstatus ; fsal_status = FSAL_namecpy( &dirent_array[iter]->name, &fsal_dirent_array[iter].name ) ; if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); return *pstatus; } (void) FSAL_cookie_to_uint64( &fsal_dirent_array[iter].handle, pcontext, &fsal_dirent_array[iter].cookie, &dirent_array[iter]->fsal_cookie); dirent_array[iter]->cookie = dirent_array[iter]->fsal_cookie ; } /* for( iter = 0 ; iter < nbfound ; iter ++ ) */ if( fsal_eod == TRUE ) *peod_met = END_OF_DIR ; else *peod_met = TO_BE_CONTINUED ; /* Do not forget to set returned end cookie */ //memcpy( pend_cookie, &(end_cookie.data), sizeof( uint64_t ) ) ; FSAL_SET_POFFSET_BY_COOKIE( end_cookie, pend_cookie ) ; LogFullDebug(COMPONENT_NFS_READDIR, "End of readdir in cache_inode_readdir_nonamecache: pentry=%p " "cookie=%"PRIu64, pentry_dir, *pend_cookie ) ; /* Close the directory */ #ifdef _USE_MFSL fsal_status = MFSL_closedir(&fsal_dirhandle, &pclient->mfsl_context, NULL); #else fsal_status = FSAL_closedir(&fsal_dirhandle); #endif if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); return *pstatus; } return CACHE_INODE_SUCCESS ; } /* cache_inode_readdir_nomanecache */