fsal_status_t MFSL_mkdir(mfsl_object_t * parent_directory_handle, /* IN */ fsal_name_t * p_dirname, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_accessmode_t accessmode, /* IN */ mfsl_object_t * object_handle, /* OUT */ fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ ) { return FSAL_mkdir(&parent_directory_handle->handle, p_dirname, p_context, accessmode, &object_handle->handle, object_attributes); } /* MFSL_mkdir */
fsal_status_t MFSL_mkdir(mfsl_object_t * parent_directory_handle, /* IN */ fsal_name_t * p_dirname, /* IN */ fsal_op_context_t * p_context, /* IN */ mfsl_context_t * p_mfsl_context, /* IN */ fsal_accessmode_t accessmode, /* IN */ mfsl_object_t * object_handle, /* OUT */ fsal_attrib_list_t * object_attributes, /* [ IN/OUT ] */ fsal_attrib_list_t * parent_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_mkdir(&parent_directory_handle->handle, p_dirname, p_context, accessmode, &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_mkdir */
/** * * cache_inode_create: creates an entry through the cache. * * Creates an entry through the cache. * * @param pentry_parent [IN] pointer to the pentry parent * @param pname [IN] pointer to the name of the object in the destination directory. * @param type [IN] type of the object to be created. * @param mode [IN] mode to be used at file creation * @param pcreate_arg [IN] additional argument for object creation * @param pattr [OUT] attributes for the new object. * @param ht [INOUT] hash table used for the cache. * @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 * @return CACHE_INODE_LRU_ERROR if allocation error occured when validating the entry\n * @return CACHE_INODE_BAD_TYPE either source or destination have incorrect type\n * @return CACHE_INODE_ENTRY_EXISTS entry of that name already exists in destination. * */ cache_entry_t * cache_inode_create(cache_entry_t * pentry_parent, fsal_name_t * pname, cache_inode_file_type_t type, fsal_accessmode_t mode, cache_inode_create_arg_t * pcreate_arg, fsal_attrib_list_t * pattr, hash_table_t * ht, cache_inode_client_t * pclient, fsal_op_context_t * pcontext, cache_inode_status_t * pstatus) { 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_attrib_list_t parent_attributes; fsal_attrib_list_t object_attributes; fsal_handle_t dir_handle; cache_inode_fsal_data_t fsal_data; cache_inode_status_t status; struct cache_inode_dir_begin__ *dir_begin; int pnfs_status; /* Set the return default to CACHE_INODE_SUCCESS */ *pstatus = CACHE_INODE_SUCCESS; /* stats */ pclient->stat.nb_call_total += 1; inc_func_call(pclient, CACHE_INODE_CREATE); /* * Check if the required type is correct, with this * function, we manage file, dir and symlink */ if(type != REGULAR_FILE && type != DIR_BEGINNING && type != SYMBOLIC_LINK && type != SOCKET_FILE && type != FIFO_FILE && type != CHARACTER_FILE && type != BLOCK_FILE) { *pstatus = CACHE_INODE_BAD_TYPE; /* stats */ inc_func_err_unrecover(pclient, CACHE_INODE_CREATE); return NULL; } /* * Check if caller is allowed to perform the operation */ status = cache_inode_access(pentry_parent, FSAL_W_OK, ht, pclient, pcontext, &status); if (status != CACHE_INODE_SUCCESS) { *pstatus = status; /* stats */ inc_func_err_unrecover(pclient, CACHE_INODE_CREATE); /* pentry is a directory */ return NULL; } /* * Check if an entry of the same name exists */ pentry = cache_inode_lookup(pentry_parent, pname, &object_attributes, ht, pclient, pcontext, pstatus); if (pentry != NULL) { *pstatus = CACHE_INODE_ENTRY_EXISTS; if(pentry->internal_md.type != type) { /* * Incompatible types, returns NULL */ /* stats */ inc_func_err_unrecover(pclient, CACHE_INODE_CREATE); return NULL; } else { /* stats */ inc_func_success(pclient, CACHE_INODE_CREATE); /* * redondant creation, returned the * previously created entry */ return pentry; } } /* * At this point, the entry was not found, this means * that is doesn't exist is FSAL, we can create it */ /* Get the lock for the parent */ P_w(&pentry_parent->lock); if(pentry_parent->internal_md.type == DIR_BEGINNING) dir_handle = pentry_parent->object.dir_begin.handle; if(pentry_parent->internal_md.type == DIR_CONTINUE) { P_r(&pentry_parent->object.dir_cont.pdir_begin->lock); dir_handle = pentry_parent->object.dir_cont.pdir_begin->object.dir_begin.handle; V_r(&pentry_parent->object.dir_cont.pdir_begin->lock); } object_attributes.asked_attributes = pclient->attrmask; switch (type) { case REGULAR_FILE: #ifdef _USE_MFSL cache_inode_get_attributes(pentry_parent, &parent_attributes); fsal_status = MFSL_create(&pentry_parent->mobject, pname, pcontext, &pclient->mfsl_context, mode, &object_handle, &object_attributes, &parent_attributes); #else fsal_status = FSAL_create(&dir_handle, pname, pcontext, mode, &object_handle, &object_attributes); #endif break; case DIR_BEGINNING: #ifdef _USE_MFSL cache_inode_get_attributes(pentry_parent, &parent_attributes); fsal_status = MFSL_mkdir(&pentry_parent->mobject, pname, pcontext, &pclient->mfsl_context, mode, &object_handle, &object_attributes, &parent_attributes); #else fsal_status = FSAL_mkdir(&dir_handle, pname, pcontext, mode, &object_handle, &object_attributes); #endif break; case SYMBOLIC_LINK: #ifdef _USE_MFSL cache_inode_get_attributes(pentry_parent, &object_attributes); fsal_status = MFSL_symlink(&pentry_parent->mobject, pname, &pcreate_arg->link_content, pcontext, &pclient->mfsl_context, mode, &object_handle, &object_attributes); #else fsal_status = FSAL_symlink(&dir_handle, pname, &pcreate_arg->link_content, pcontext, mode, &object_handle, &object_attributes); #endif break; case SOCKET_FILE: #ifdef _USE_MFSL fsal_status = MFSL_mknode(&pentry_parent->mobject, pname, pcontext, &pclient->mfsl_context, mode, FSAL_TYPE_SOCK, NULL, /* no dev_t needed for socket file */ &object_handle, &object_attributes); #else fsal_status = FSAL_mknode(&dir_handle, pname, pcontext, mode, FSAL_TYPE_SOCK, NULL, /* no dev_t needed for socket file */ &object_handle, &object_attributes); #endif break; case FIFO_FILE: #ifdef _USE_MFSL fsal_status = MFSL_mknode(&pentry_parent->mobject, pname, pcontext, &pclient->mfsl_context, mode, FSAL_TYPE_FIFO, NULL, /* no dev_t needed for FIFO file */ &object_handle, &object_attributes); #else fsal_status = FSAL_mknode(&dir_handle, pname, pcontext, mode, FSAL_TYPE_FIFO, NULL, /* no dev_t needed for FIFO file */ &object_handle, &object_attributes); #endif break; case BLOCK_FILE: #ifdef _USE_MFSL fsal_status = MFSL_mknode(&pentry_parent->mobject, pname, pcontext, &pclient->mfsl_context, mode, FSAL_TYPE_BLK, &pcreate_arg->dev_spec, &object_handle, &object_attributes); #else fsal_status = FSAL_mknode(&dir_handle, pname, pcontext, mode, FSAL_TYPE_BLK, &pcreate_arg->dev_spec, &object_handle, &object_attributes); #endif break; case CHARACTER_FILE: #ifdef _USE_MFSL fsal_status = MFSL_mknode(&pentry_parent->mobject, pname, pcontext, &pclient->mfsl_context, mode, FSAL_TYPE_CHR, &pcreate_arg->dev_spec, &object_handle, &object_attributes); #else fsal_status = FSAL_mknode(&dir_handle, pname, pcontext, mode, FSAL_TYPE_CHR, &pcreate_arg->dev_spec, &object_handle, &object_attributes); #endif break; default: /* we should never go there */ *pstatus = CACHE_INODE_INCONSISTENT_ENTRY; V_w(&pentry_parent->lock); /* stats */ inc_func_err_unrecover(pclient, CACHE_INODE_CREATE); return NULL; break; } /* Check for the result */ if(FSAL_IS_ERROR(fsal_status)) { *pstatus = cache_inode_error_convert(fsal_status); V_w(&pentry_parent->lock); if(fsal_status.major == ERR_FSAL_STALE) { cache_inode_status_t kill_status; LogEvent(COMPONENT_CACHE_INODE, "cache_inode_create: Stale FSAL File Handle " "detected for pentry = %p", pentry_parent); cache_inode_kill_entry(pentry_parent, ht, pclient, &kill_status); if(kill_status != CACHE_INODE_SUCCESS) LogCrit(COMPONENT_CACHE_INODE, "cache_inode_create: " "Could not kill entry %p, status = %u", pentry_parent, kill_status); *pstatus = CACHE_INODE_FSAL_ESTALE; } /* stats */ inc_func_err_unrecover(pclient, CACHE_INODE_CREATE); return NULL; } else { #ifdef _USE_MFSL fsal_data.handle = object_handle.handle; #else fsal_data.handle = object_handle; #endif fsal_data.cookie = DIR_START; pentry = cache_inode_new_entry(&fsal_data, &object_attributes, type, pcreate_arg, NULL, ht, pclient, pcontext, TRUE, /* This is a creation and not a population */ pstatus); if (pentry == NULL) { *pstatus = CACHE_INODE_INSERT_ERROR; V_w(&pentry_parent->lock); /* stats */ inc_func_err_unrecover(pclient, CACHE_INODE_CREATE); return NULL; } #ifdef _USE_MFSL /* Copy the MFSL object to the cache */ memcpy((char *)&(pentry->mobject), (char *)&object_handle, sizeof(mfsl_object_t)); #endif /* Add this entry to the directory */ status = cache_inode_add_cached_dirent(pentry_parent, pname, pentry, NULL, ht, pclient, pcontext, pstatus); if (status != CACHE_INODE_SUCCESS) { V_w(&pentry_parent->lock); /* stats */ inc_func_err_unrecover(pclient, CACHE_INODE_CREATE); return NULL; } } #ifdef _USE_PNFS if((type == REGULAR_FILE) && (pcreate_arg != NULL) && (pcreate_arg->use_pnfs == TRUE)) { pnfs_status = pnfs_create_ds_file(&pclient->pnfsclient, pentry->object.file.attributes.fileid, &pentry->object.file.pnfs_file.ds_file); if (pnfs_status != NFS4_OK) { V_w(&pentry_parent->lock); LogDebug(COMPONENT_CACHE_INODE, "OPEN PNFS CREATE DS FILE : Error %u", pnfs_status); *pstatus = CACHE_INODE_IO_ERROR; return NULL; } } #endif /* Update the parent cached attributes */ if(pentry_parent->internal_md.type == DIR_BEGINNING) dir_begin = &pentry_parent->object.dir_begin; else dir_begin = &pentry_parent->object.dir_cont.pdir_begin->object.dir_begin; dir_begin->attributes.mtime.seconds = time(NULL); dir_begin->attributes.mtime.nseconds = 0; dir_begin->attributes.ctime = dir_begin->attributes.mtime; /* * if the created object is a directory, it contains a link * to its parent : '..'. Thus the numlink attr must be increased. */ if(type == DIR_BEGINNING) { dir_begin->attributes.numlinks++; } /* Get the attributes in return */ *pattr = object_attributes; /* valid the parent */ *pstatus = cache_inode_valid(pentry_parent, CACHE_INODE_OP_SET, pclient); /* release the lock for the parent */ V_w(&pentry_parent->lock); /* stat */ if(*pstatus != CACHE_INODE_SUCCESS) inc_func_err_retryable(pclient, CACHE_INODE_CREATE); else inc_func_success(pclient, CACHE_INODE_CREATE); return pentry; }
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_entry_t * cache_inode_create(cache_entry_t *parent, fsal_name_t *name, cache_inode_file_type_t type, fsal_accessmode_t mode, cache_inode_create_arg_t *create_arg, fsal_attrib_list_t *attr, fsal_op_context_t *context, cache_inode_status_t *status) { cache_entry_t *entry = NULL; fsal_status_t fsal_status = {0, 0}; fsal_handle_t object_handle; fsal_attrib_list_t object_attributes; cache_inode_fsal_data_t fsal_data; cache_inode_create_arg_t zero_create_arg; memset(&zero_create_arg, 0, sizeof(zero_create_arg)); memset(&fsal_data, 0, sizeof(fsal_data)); memset(&object_handle, 0, sizeof(object_handle)); if (create_arg == NULL) { create_arg = &zero_create_arg; } /* Set the return default to CACHE_INODE_SUCCESS */ *status = CACHE_INODE_SUCCESS; if ((type != REGULAR_FILE) && (type != DIRECTORY) && (type != SYMBOLIC_LINK) && (type != SOCKET_FILE) && (type != FIFO_FILE) && (type != CHARACTER_FILE) && (type != BLOCK_FILE)) { *status = CACHE_INODE_BAD_TYPE; entry = NULL; goto out; } /* Check if an entry of the same name exists */ entry = cache_inode_lookup(parent, name, attr, context, status); if (entry != NULL) { *status = CACHE_INODE_ENTRY_EXISTS; if (entry->type != type) { /* Incompatible types, returns NULL */ cache_inode_lru_unref(entry, LRU_FLAG_NONE); entry = NULL; goto out; } else { goto out; } } /* The entry doesn't exist, so we can create it. */ object_attributes.asked_attributes = cache_inode_params.attrmask; switch (type) { case REGULAR_FILE: fsal_status = FSAL_create(&parent->handle, name, context, mode, &object_handle, &object_attributes); break; case DIRECTORY: fsal_status = FSAL_mkdir(&parent->handle, name, context, mode, &object_handle, &object_attributes); break; case SYMBOLIC_LINK: fsal_status = FSAL_symlink(&parent->handle, name, &create_arg->link_content, context, mode, &object_handle, &object_attributes); break; case SOCKET_FILE: fsal_status = FSAL_mknode(&parent->handle, name, context, mode, FSAL_TYPE_SOCK, NULL, &object_handle, &object_attributes); break; case FIFO_FILE: fsal_status = FSAL_mknode(&parent->handle, name, context, mode, FSAL_TYPE_FIFO, NULL, &object_handle, &object_attributes); break; case BLOCK_FILE: fsal_status = FSAL_mknode(&parent->handle, name, context, mode, FSAL_TYPE_BLK, &create_arg->dev_spec, &object_handle, &object_attributes); break; case CHARACTER_FILE: fsal_status = FSAL_mknode(&parent->handle, name, context, mode, FSAL_TYPE_CHR, &create_arg->dev_spec, &object_handle, &object_attributes); break; default: /* we should never go there */ *status = CACHE_INODE_INCONSISTENT_ENTRY; entry = NULL; goto out; break; } /* Check for the result */ if (FSAL_IS_ERROR(fsal_status)) { if (fsal_status.major == ERR_FSAL_STALE) { LogEvent(COMPONENT_CACHE_INODE, "FSAL returned STALE on create type %d", type); cache_inode_kill_entry(parent); } *status = cache_inode_error_convert(fsal_status); entry = NULL; goto out; } fsal_data.fh_desc.start = (caddr_t) &object_handle; fsal_data.fh_desc.len = 0; FSAL_ExpandHandle(context->export_context, FSAL_DIGEST_SIZEOF, &fsal_data.fh_desc); entry = cache_inode_new_entry(&fsal_data, &object_attributes, type, create_arg, status); if (entry == NULL) { *status = CACHE_INODE_INSERT_ERROR; return NULL; } PTHREAD_RWLOCK_WRLOCK(&parent->content_lock); /* Add this entry to the directory (also takes an internal ref) */ cache_inode_add_cached_dirent(parent, name, entry, NULL, status); PTHREAD_RWLOCK_UNLOCK(&parent->content_lock); if (*status != CACHE_INODE_SUCCESS) { cache_inode_lru_unref(entry, LRU_FLAG_NONE); entry = NULL; goto out; } PTHREAD_RWLOCK_WRLOCK(&parent->attr_lock); /* Update the parent cached attributes */ cache_inode_set_time_current(&parent->attributes.mtime); parent->attributes.ctime = parent->attributes.mtime; /* if the created object is a directory, it contains a link to its parent : '..'. Thus the numlink attr must be increased. */ if (type == DIRECTORY) { ++(parent->attributes.numlinks); } PTHREAD_RWLOCK_UNLOCK(&parent->attr_lock); /* Copy up the child attributes */ *attr = object_attributes; *status = CACHE_INODE_SUCCESS; out: return entry; }