/** * * MFSL_create_async_op: Callback for asynchronous link. * * Callback for asynchronous create. * * @param popasyncdes [INOUT] asynchronous operation descriptor * * @return the status of the performed FSAL_create. */ fsal_status_t MFSL_create_async_op(mfsl_async_op_desc_t * popasyncdesc) { fsal_status_t fsal_status; fsal_attrib_list_t attrsrc, attrdest, chown_attr; fsal_handle_t handle; attrsrc = attrdest = popasyncdesc->op_res.mkdir.attr; LogDebug(COMPONENT_MFSL, "Renaming file to complete asynchronous FSAL_create for async op %p", popasyncdesc); P(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock); fsal_status = FSAL_rename(&dir_handle_precreate, &popasyncdesc->op_args.create.precreate_name, &(popasyncdesc->op_args.create.pmfsl_obj_dirdest->handle), &popasyncdesc->op_args.create.filename, &popasyncdesc->fsal_op_context, &attrsrc, &attrdest); if(FSAL_IS_ERROR(fsal_status)) { V(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock); return fsal_status; } /* Lookup to get the right attributes for the object */ fsal_status = FSAL_lookup(&(popasyncdesc->op_args.create.pmfsl_obj_dirdest->handle), &popasyncdesc->op_args.create.filename, &popasyncdesc->fsal_op_context, &handle, &popasyncdesc->op_res.create.attr); if(FSAL_IS_ERROR(fsal_status)) { V(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock); return fsal_status; } /* If user is not root, setattr to chown the entry */ if(popasyncdesc->op_args.create.owner != 0) { chown_attr.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP; chown_attr.mode = popasyncdesc->op_args.create.mode; chown_attr.owner = popasyncdesc->op_args.create.owner; chown_attr.group = popasyncdesc->op_args.create.group; fsal_status = FSAL_setattrs(&handle, &popasyncdesc->fsal_op_context, &chown_attr, &popasyncdesc->op_res.create.attr); } V(popasyncdesc->op_args.create.pmfsl_obj_dirdest->lock); return fsal_status; } /* MFSL_create_async_op */
fsal_status_t MFSL_lookup(mfsl_object_t * parent_directory_handle, /* IN */ fsal_name_t * p_filename, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ mfsl_object_t * object_handle, /* OUT */ fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ ) { return FSAL_lookup(&parent_directory_handle->handle, p_filename, p_context, &object_handle->handle, object_attributes); } /* MFSL_lookup */
fsal_status_t GPFSFSAL_open_by_name(fsal_handle_t * dirhandle, /* IN */ fsal_name_t * filename, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_openflags_t openflags, /* IN */ fsal_file_t * file_descriptor, /* OUT */ fsal_attrib_list_t * file_attributes /* [ IN/OUT ] */ ) { fsal_status_t fsal_status; fsal_handle_t filehandle; if(!dirhandle || !filename || !p_context || !file_descriptor) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open_by_name); fsal_status = FSAL_lookup(dirhandle, filename, p_context, &filehandle, file_attributes); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; return FSAL_open(&filehandle, p_context, openflags, file_descriptor, file_attributes); }
fsal_status_t MFSL_lookup(mfsl_object_t * parent_directory_handle, /* IN */ fsal_name_t * p_filename, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ mfsl_object_t * object_handle, /* OUT */ fsal_attrib_list_t * object_attributes, /* [ IN/OUT ] */ void * pextra ) { struct timeval start, stop, delta ; fsal_status_t fsal_status = { ERR_FSAL_NO_ERROR, 0 } ; gettimeofday( &start, 0 ) ; fsal_status = FSAL_lookup(&parent_directory_handle->handle, p_filename, p_context, &object_handle->handle, object_attributes); 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_lookup */
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_lookupp_sw: looks up (and caches) the parent directory for a directory. A switches tells is mutex are use. * * Looks up (and caches) the parent directory for a directory. * * @param pentry [IN] entry whose parent is to be obtained. * @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. * @param use_mutex [IN] if TRUE mutex are use, not otherwise. * * @return CACHE_INODE_SUCCESS if operation is a success \n * @return CACHE_INODE_LRU_ERROR if allocation error occured when validating the entry * */ cache_entry_t *cache_inode_lookupp_sw(cache_entry_t * pentry, hash_table_t * ht, cache_inode_client_t * pclient, fsal_op_context_t * pcontext, cache_inode_status_t * pstatus, int use_mutex) { cache_entry_t *pentry_parent = NULL; fsal_status_t fsal_status; fsal_attrib_list_t object_attributes; cache_inode_fsal_data_t fsdata; /* Set the return default to CACHE_INODE_SUCCESS */ *pstatus = CACHE_INODE_SUCCESS; /* stats */ pclient->stat.nb_call_total += 1; pclient->stat.func_stats.nb_call[CACHE_INODE_LOOKUP] += 1; /* The entry should be a directory */ if(use_mutex) P_r(&pentry->lock); if(pentry->internal_md.type != DIR_BEGINNING) { if(use_mutex) V_r(&pentry->lock); *pstatus = CACHE_INODE_BAD_TYPE; /* stats */ pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUPP] += 1; return NULL; } /* Renew the entry (to avoid having it being garbagged */ if(cache_inode_renew_entry(pentry, NULL, ht, pclient, pcontext, pstatus) != CACHE_INODE_SUCCESS) { pclient->stat.func_stats.nb_err_retryable[CACHE_INODE_GETATTR] += 1; return NULL; } /* Does the parent belongs to the cache ? */ if(pentry->parent_list && pentry->parent_list->parent) { /* YES, the parent is cached, use the pentry that we have found */ pentry_parent = pentry->parent_list->parent; } else { /* NO, the parent is not cached, query FSAL to get it and cache the result */ object_attributes.asked_attributes = pclient->attrmask; fsal_status = FSAL_lookup(&pentry->object.dir_begin.handle, (fsal_name_t *) & FSAL_DOT_DOT, pcontext, &fsdata.handle, &object_attributes); if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); if(use_mutex) V_r(&pentry->lock); /* Stale File Handle to be detected and managed */ if(fsal_status.major == ERR_FSAL_STALE) { cache_inode_status_t kill_status; LogEvent(COMPONENT_CACHE_INODE,"cache_inode_lookupp: Stale FSAL FH detected for pentry %p", pentry); if(cache_inode_kill_entry(pentry, ht, pclient, &kill_status) != CACHE_INODE_SUCCESS) LogCrit(COMPONENT_CACHE_INODE,"cache_inode_remove: Could not kill entry %p, status = %u", pentry, kill_status); *pstatus = CACHE_INODE_FSAL_ESTALE; } /* stats */ pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUPP] += 1; return NULL; } /* Call cache_inode_get to populate the cache with the parent entry */ fsdata.cookie = 0; if((pentry_parent = cache_inode_get(&fsdata, &object_attributes, ht, pclient, pcontext, pstatus)) == NULL) { if(use_mutex) V_r(&pentry->lock); /* stats */ pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUPP] += 1; return NULL; } } *pstatus = cache_inode_valid(pentry_parent, CACHE_INODE_OP_GET, pclient); if(use_mutex) V_r(&pentry->lock); /* stat */ if(*pstatus != CACHE_INODE_SUCCESS) pclient->stat.func_stats.nb_err_retryable[CACHE_INODE_LOOKUPP] += 1; else pclient->stat.func_stats.nb_success[CACHE_INODE_LOOKUPP] += 1; return pentry_parent; } /* cache_inode_lookupp_sw */
/** * * cache_inode_lookup_sw: looks up for a name in a directory indicated by a * cached entry. * * Looks up for a name in a directory indicated by a cached entry. The directory * should have been cached before. * * @param pentry_parent [IN] entry for the parent directory to be managed. * @param name [IN] name of the entry that we are looking for in the * cache. * @param pattr [OUT] attributes for the entry that we have found. * @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. * @param use_mutex [IN] if TRUE, mutex management is done, not if equal * to FALSE. * * @return CACHE_INODE_SUCCESS if operation is a success \n * @return CACHE_INODE_LRU_ERROR if allocation error occured when validating the * entry * */ cache_entry_t *cache_inode_lookup_sw(cache_entry_t * pentry_parent, fsal_name_t * pname, cache_inode_policy_t policy, fsal_attrib_list_t * pattr, hash_table_t * ht, cache_inode_client_t * pclient, fsal_op_context_t * pcontext, cache_inode_status_t * pstatus, int use_mutex) { cache_inode_dir_entry_t dirent_key[1], *dirent; struct avltree_node *dirent_node; cache_inode_dir_entry_t *new_dir_entry; cache_entry_t *pentry = NULL; fsal_status_t fsal_status; #ifdef _USE_MFSL mfsl_object_t object_handle; #else fsal_handle_t object_handle; #endif fsal_handle_t dir_handle; 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; cache_inode_fsal_data_t new_entry_fsdata; fsal_accessflags_t access_mask = 0; memset(&create_arg, 0, sizeof(create_arg)); memset( (char *)&new_entry_fsdata, 0, sizeof( new_entry_fsdata ) ) ; /* Set the return default to CACHE_INODE_SUCCESS */ *pstatus = CACHE_INODE_SUCCESS; /* stats */ (pclient->stat.nb_call_total)++; (pclient->stat.func_stats.nb_call[CACHE_INODE_LOOKUP])++; /* We should not renew entries when !use_mutex (because unless we * make the flag explicit (shared vs. exclusive), we don't know * whether a mutating operation is safe--and, the caller should have * already renewed the entry */ if(use_mutex == TRUE) { P_w(&pentry_parent->lock); cache_status = cache_inode_renew_entry(pentry_parent, pattr, ht, pclient, pcontext, pstatus); if(cache_status != CACHE_INODE_SUCCESS) { V_w(&pentry_parent->lock); inc_func_err_retryable(pclient, CACHE_INODE_GETATTR); LogDebug(COMPONENT_CACHE_INODE, "cache_inode_lookup: returning %d(%s) from cache_inode_renew_entry", *pstatus, cache_inode_err_str(*pstatus)); return NULL; } /* RW Lock goes for writer to reader */ rw_lock_downgrade(&pentry_parent->lock); } if(pentry_parent->internal_md.type != DIRECTORY) { /* Parent is no directory base, return NULL */ *pstatus = CACHE_INODE_NOT_A_DIRECTORY; /* stats */ (pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUP])++; if(use_mutex == TRUE) V_r(&pentry_parent->lock); return NULL; } /* if name is ".", use the input value */ if(!FSAL_namecmp(pname, (fsal_name_t *) & FSAL_DOT)) { pentry = pentry_parent; } else if(!FSAL_namecmp(pname, (fsal_name_t *) & FSAL_DOT_DOT)) { /* Directory do only have exactly one parent. This a limitation in all FS, * which implies that hard link are forbidden on directories (so that * they exists only in one dir). Because of this, the parent list is * always limited to one element for a dir. Clients SHOULD never * 'lookup( .. )' in something that is no dir. */ pentry = cache_inode_lookupp_no_mutex(pentry_parent, ht, pclient, pcontext, pstatus); } else { /* This is a "regular lookup" (not on "." or "..") */ /* Check is user (as specified by the credentials) is authorized to * lookup the directory or not */ access_mask = FSAL_MODE_MASK_SET(FSAL_X_OK) | FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_LIST_DIR); if(cache_inode_access_no_mutex(pentry_parent, access_mask, ht, pclient, pcontext, pstatus) != CACHE_INODE_SUCCESS) { if(use_mutex == TRUE) V_r(&pentry_parent->lock); (pclient->stat.func_stats.nb_err_retryable[CACHE_INODE_GETATTR])++; return NULL; } /* We first try avltree_lookup by name. If that fails, we dispatch to * the fsal. */ FSAL_namecpy(&dirent_key->name, pname); dirent_node = avltree_lookup(&dirent_key->node_n, &pentry_parent->object.dir.dentries); if (dirent_node) { dirent = avltree_container_of(dirent_node, cache_inode_dir_entry_t, node_n); pentry = dirent->pentry; } if(pentry == NULL) { LogDebug(COMPONENT_CACHE_INODE, "Cache Miss detected"); dir_handle = pentry_parent->handle; object_attributes.asked_attributes = pclient->attrmask; #ifdef _USE_MFSL #ifdef _USE_MFSL_ASYNC if(!mfsl_async_is_object_asynchronous(&pentry_parent->mobject)) { /* If the parent is asynchronous, rely on the content of the cache * inode parent entry. * * /!\ If the fs behind the FSAL is touched in a non-nfs way, * there will be huge incoherencies. */ #endif /* _USE_MFSL_ASYNC */ fsal_status = MFSL_lookup(&pentry_parent->mobject, pname, pcontext, &pclient->mfsl_context, &object_handle, &object_attributes, NULL); #ifdef _USE_MFSL_ASYNC } else { LogMidDebug(COMPONENT_CACHE_INODE, "cache_inode_lookup chose to bypass FSAL and trusted his cache for name=%s", pname->name); fsal_status.major = ERR_FSAL_NOENT; fsal_status.minor = ENOENT; } #endif /* _USE_MFSL_ASYNC */ #else fsal_status = FSAL_lookup(&dir_handle, pname, pcontext, &object_handle, &object_attributes); #endif /* _USE_MFSL */ if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); if(use_mutex == TRUE) V_r(&pentry_parent->lock); /* Stale File Handle to be detected and managed */ if(fsal_status.major == ERR_FSAL_STALE) { cache_inode_status_t kill_status; LogEvent(COMPONENT_CACHE_INODE, "cache_inode_lookup: Stale FSAL File Handle detected for pentry = %p, fsal_status=(%u,%u)", pentry_parent, fsal_status.major, fsal_status.minor); if(cache_inode_kill_entry(pentry_parent, NO_LOCK, ht, pclient, &kill_status) != CACHE_INODE_SUCCESS) LogCrit(COMPONENT_CACHE_INODE, "cache_inode_pentry_parent: Could not kill entry %p, status = %u", pentry_parent, kill_status); *pstatus = CACHE_INODE_FSAL_ESTALE; } /* stats */ (pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUP])++; return NULL; } type = cache_inode_fsal_type_convert(object_attributes.type); /* If entry is a symlink, this value for be cached */ if(type == SYMBOLIC_LINK) { if( CACHE_INODE_KEEP_CONTENT( policy ) ) #ifdef _USE_MFSL { fsal_status = MFSL_readlink(&object_handle, pcontext, &pclient->mfsl_context, &create_arg.link_content, &object_attributes, NULL); } #else { fsal_status = FSAL_readlink(&object_handle, pcontext, &create_arg.link_content, &object_attributes); } else { fsal_status.major = ERR_FSAL_NO_ERROR ; fsal_status.minor = 0 ; } #endif if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); if(use_mutex == TRUE) V_r(&pentry_parent->lock); /* Stale File Handle to be detected and managed */ if(fsal_status.major == ERR_FSAL_STALE) { cache_inode_status_t kill_status; LogEvent(COMPONENT_CACHE_INODE, "cache_inode_lookup: Stale FSAL File Handle detected for pentry = %p, fsal_status=(%u,%u)", pentry_parent, fsal_status.major, fsal_status.minor); if(cache_inode_kill_entry(pentry_parent, NO_LOCK, ht, pclient, &kill_status) != CACHE_INODE_SUCCESS) LogCrit(COMPONENT_CACHE_INODE, "cache_inode_pentry_parent: Could not kill entry %p, status = %u", pentry_parent, kill_status); *pstatus = CACHE_INODE_FSAL_ESTALE; } /* stats */ (pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUP])++; return NULL; } } /* Allocation of a new entry in the cache */ #ifdef _USE_MFSL new_entry_fsdata.handle = object_handle.handle; #else new_entry_fsdata.handle = object_handle; #endif new_entry_fsdata.cookie = 0; if((pentry = cache_inode_new_entry( &new_entry_fsdata, &object_attributes, type, policy, &create_arg, NULL, ht, pclient, pcontext, FALSE, /* This is a population and not a creation */ pstatus ) ) == NULL ) { if(use_mutex == TRUE) V_r(&pentry_parent->lock); /* stats */ (pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUP])++; return NULL; } /* Entry was found in the FSAL, add this entry to the parent * directory */ cache_status = cache_inode_add_cached_dirent(pentry_parent, pname, pentry, ht, &new_dir_entry, pclient, pcontext, pstatus); if(cache_status != CACHE_INODE_SUCCESS && cache_status != CACHE_INODE_ENTRY_EXISTS) { if(use_mutex == TRUE) V_r(&pentry_parent->lock); /* stats */ (pclient->stat.func_stats.nb_err_unrecover[CACHE_INODE_LOOKUP])++; return NULL; } } /* cached lookup fail (try fsal) */
fsal_status_t MFSL_open_by_name(mfsl_object_t * dirhandle, /* IN */ fsal_name_t * filename, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_openflags_t openflags, /* IN */ mfsl_file_t * file_descriptor, /* OUT */ fsal_attrib_list_t * file_attributes, /* [ IN/OUT ] */ void * pextra ) { fsal_status_t fsal_status ; int pnfs_status; pnfs_fileloc_t pnfs_location ; fsal_handle_t objhandle ; fsal_status = FSAL_open_by_name(&dirhandle->handle, filename, p_context, openflags, &file_descriptor->fsal_file, file_attributes); if( FSAL_IS_ERROR( fsal_status ) ) return fsal_status ; fsal_status = FSAL_lookup( &dirhandle->handle, filename, p_context, &objhandle, &file_attributes ) ; if( FSAL_IS_ERROR( fsal_status ) ) return fsal_status ; if(! pnfs_get_location( &p_mfsl_context->pnfsclient, &objhandle, NULL, &pnfs_location ) ) { LogDebug(COMPONENT_MFSL, "LOOKUP PNFS support : can't build pnfs_location" ) ; fsal_status.major = ERR_FSAL_IO ; fsal_status.minor = 0 ; return fsal_status ; } if((pnfs_status = pnfs_lookup_file( &p_mfsl_context->pnfsclient, &pnfs_location, &file_descriptor->pnfs_file ) ) != NFS4_OK ) { LogDebug(COMPONENT_CACHE_INODE, "OPEN PNFS LOOKUP DS FILE : Error %u", pnfs_status); if(pnfs_status == NFS4ERR_NOENT) { if((pnfs_status = pnfs_create_file(&p_mfsl_context->pnfsclient, &pnfs_location, &file_descriptor->pnfs_file ) ) != NFS4_OK ) { LogDebug(COMPONENT_CACHE_INODE, "OPEN PNFS CREATE DS FILE : Error %u", pnfs_status ) ; fsal_status.major = ERR_FSAL_IO ; fsal_status.minor = 0 ; return fsal_status ; } } else { fsal_status.major = ERR_FSAL_IO ; fsal_status.minor = 0 ; return fsal_status ; } } if( pextra != NULL ) memcpy( (char *)pextra, (char *)&file_descriptor->pnfs_file, sizeof( pnfs_file_t ) ) ; /* SUCCES */ fsal_status.major = ERR_FSAL_NO_ERROR ; fsal_status.minor = 0 ; return fsal_status ; } /* MFSL_open_by_name */