static int hpss_get_bfid(struct fsal_obj_handle *fsal_obj_hdl, caddr_t buffer_addr, size_t buffer_size, size_t *p_output_size, void *arg) { struct hpss_fsal_obj_handle *obj_hdl; sec_cred_t *p_ucreds = arg; hpss_vattr_t hpss_vattr; char *tmp_str_uuid; int rc; /* sanity checks. */ if (!fsal_obj_hdl || !p_output_size || !buffer_addr || !p_ucreds) return ERR_FSAL_FAULT; obj_hdl = container_of(fsal_obj_hdl, struct hpss_fsal_obj_handle, obj_handle); rc = hpss_GetAttrHandle(&(obj_hdl->handle->ns_handle), NULL, p_ucreds, NULL, &hpss_vattr); /** * /!\ WARNING : When the directory handle is stale, HPSS returns ENOTDIR. * Thus, in this case, we must double check * by checking the directory handle. */ if (rc == HPSS_ENOTDIR) if (HPSSFSAL_IsStaleHandle(&obj_hdl->handle->ns_handle, p_ucreds)) return ERR_FSAL_STALE; if (rc) return hpss2fsal_error(rc); uuid_to_string(&(hpss_vattr.va_soid.ObjectID), (char **)&tmp_str_uuid, &rc); if (rc != 0) return hpss2fsal_error(rc); *p_output_size = snprintf(buffer_addr, buffer_size, "%s", tmp_str_uuid); /* HPSS returns a string that it has just allocated. * Free it to avoid memory leak. */ free(tmp_str_uuid); return 0; }
fsal_status_t hpss_setextattr_value(struct fsal_obj_handle *fsal_obj_hdl, const char *xattr_name, caddr_t buffer_addr, size_t buffer_size, int create) { struct hpss_fsal_obj_handle *obj_hdl; int rc, index; sec_cred_t ucreds; hpss_userattr_list_t attr; char attrpath[MAXNAMLEN]; if (!fsal_obj_hdl || !xattr_name || !buffer_addr) return fsalstat(ERR_FSAL_FAULT, 0); if (((char *)buffer_addr)[0] == '\0') return fsalstat(ERR_FSAL_NO_ERROR, 0); /* check if this is an indexed fake xattr */ for (index = 0; index < XATTR_COUNT; index++) if (do_match_type(xattr_list[index].flags, fsal_obj_hdl->type) && !strcmp(xattr_list[index].xattr_name, xattr_name)) return hpss_setextattr_value_by_id(fsal_obj_hdl, index, buffer_addr, buffer_size); obj_hdl = container_of(fsal_obj_hdl, struct hpss_fsal_obj_handle, obj_handle); HPSSFSAL_ucreds_from_opctx(op_ctx, &ucreds); /* convert FSAL xattr name to HPSS attr path. * returns error if it is not a UDA name. */ if (fsal_xattr_name_2_uda(xattr_name, attrpath) == 0) { attr.len = 1; /* use malloc because HPSS may free it */ attr.Pair = malloc(sizeof(hpss_userattr_t)); if (attr.Pair == NULL) return fsalstat(ERR_FSAL_NOMEM, errno); attr.Pair[0].Key = attrpath; attr.Pair[0].Value = buffer_addr; rc = hpss_UserAttrSetAttrHandle(&(obj_hdl->handle->ns_handle), NULL, &ucreds, &attr, UDA_API_VALUE); free(attr.Pair); if (rc) return fsalstat(hpss2fsal_error(rc), rc); else return fsalstat(ERR_FSAL_INVAL, 0); } return fsalstat(ERR_FSAL_NO_ERROR, 0); }
static int hpss_get_file_cos(struct fsal_obj_handle *fsal_obj_hdl, caddr_t buffer_addr, size_t buffer_size, size_t *p_output_size, void *arg) { struct hpss_fsal_obj_handle *obj_hdl; sec_cred_t *p_ucreds = arg; hpss_vattr_t hpss_vattr; int rc; /* sanity checks. */ if (!fsal_obj_hdl || !p_output_size || !buffer_addr || !p_ucreds) return ERR_FSAL_FAULT; obj_hdl = container_of(fsal_obj_hdl, struct hpss_fsal_obj_handle, obj_handle); rc = hpss_GetAttrHandle(&(obj_hdl->handle->ns_handle), NULL, p_ucreds, NULL, &hpss_vattr); /** * /!\ WARNING : When the directory handle is stale, * HPSS returns ENOTDIR. * Thus, in this case, we must double check * by checking the directory handle. */ if (rc == HPSS_ENOTDIR) if (HPSSFSAL_IsStaleHandle(&obj_hdl->handle->ns_handle, p_ucreds)) return ERR_FSAL_STALE; if (rc) return hpss2fsal_error(rc); *p_output_size = snprintf(buffer_addr, buffer_size, "%i", hpss_vattr.va_cos); return 0; }
static int hpss_get_ns_handle(struct fsal_obj_handle *fsal_obj_hdl, caddr_t buffer_addr, size_t buffer_size, size_t *p_output_size, void *arg) { struct hpss_fsal_obj_handle *obj_hdl; struct ns_ObjHandle *ns_hdl; char *tmp_str_uuid; int rc; /* sanity checks. */ if (!fsal_obj_hdl || !p_output_size || !buffer_addr) return ERR_FSAL_FAULT; obj_hdl = container_of(fsal_obj_hdl, struct hpss_fsal_obj_handle, obj_handle); ns_hdl = &obj_hdl->handle->ns_handle; uuid_to_string(&(ns_hdl->CoreServerUUID), (char **)&tmp_str_uuid, &rc); if (rc != 0) return hpss2fsal_error(rc); *p_output_size = snprintf(buffer_addr, buffer_size, "ObjId: %#"PRIx64"\nFileId: %#"PRIx64 "\nType: %hu\nFlags: %hu\nGeneration: %#x\n" "CoreServerUUID: %s\n", ns_hdl->ObjId, ns_hdl->FileId, ns_hdl->Type, ns_hdl->Flags, ns_hdl->Generation, tmp_str_uuid); /* HPSS returns a string that it has just allocated. * Free it to avoid memory leak. */ free(tmp_str_uuid); return 0; }
fsal_status_t hpss_setextattr_value_by_id(struct fsal_obj_handle *fsal_obj_hdl, unsigned int xattr_id, caddr_t buffer_addr, size_t buffer_size) { struct hpss_fsal_obj_handle *obj_hdl; int rc, index, listlen; sec_cred_t ucreds; hpss_userattr_list_t attr_list; if (!fsal_obj_hdl || !buffer_addr) return fsalstat(ERR_FSAL_FAULT, 0); if (attr_is_read_only(xattr_id)) return fsalstat(ERR_FSAL_PERM, 0); if (((char *)buffer_addr)[0] == '\0') return fsalstat(ERR_FSAL_NO_ERROR, 0); obj_hdl = container_of(fsal_obj_hdl, struct hpss_fsal_obj_handle, obj_handle); HPSSFSAL_ucreds_from_opctx(op_ctx, &ucreds); if (xattr_id < XATTR_COUNT) rc = xattr_list[xattr_id].set_func(fsal_obj_hdl, buffer_addr, buffer_size, 0, &ucreds); else { memset(&attr_list, 0, sizeof(hpss_userattr_list_t)); LogFullDebug(COMPONENT_FSAL, "Setting value for UDA #%u", xattr_id - XATTR_COUNT); /* get list of UDAs for this entry, and return the good value */ rc = hpss_UserAttrListAttrHandle(&(obj_hdl->handle->ns_handle), NULL, &ucreds, &attr_list, XML_ATTR); if (rc != 0) return fsalstat(hpss2fsal_error(rc), rc); else if (xattr_id - XATTR_COUNT >= attr_list.len) return fsalstat(ERR_FSAL_STALE, 0); listlen = attr_list.len; attr_list.Pair[0].Key = attr_list.Pair[xattr_id - XATTR_COUNT].Key; attr_list.Pair[0].Value = buffer_addr; attr_list.len = 1; rc = hpss_UserAttrSetAttrHandle(&(obj_hdl->handle->ns_handle), NULL, &ucreds, &attr_list, UDA_API_VALUE); /* Allocated by hpss - use free */ for (index = 0; index < listlen; index++) { free(attr_list.Pair[index].Key); free(attr_list.Pair[index].Value); } free(attr_list.Pair); if (rc) rc = hpss2fsal_error(rc); } return fsalstat(rc, 0); }
fsal_status_t hpss_getextattr_value_by_name( struct fsal_obj_handle *fsal_obj_hdl, const char *xattr_name, caddr_t buffer_addr, size_t buffer_size, size_t *p_output_size) { struct hpss_fsal_obj_handle *obj_hdl; int rc, index; sec_cred_t ucreds; hpss_userattr_list_t attr; char attrpath[MAXNAMLEN]; char attrval[MAXPATHLEN]; if (!fsal_obj_hdl || !p_output_size) return fsalstat(ERR_FSAL_FAULT, 0); /* check if this is an indexed fake xattr */ for (index = 0; index < XATTR_COUNT; index++) if (do_match_type(xattr_list[index].flags, fsal_obj_hdl->type) && !strcmp(xattr_list[index].xattr_name, xattr_name)) return hpss_getextattr_value_by_id(fsal_obj_hdl, index, buffer_addr, buffer_size, p_output_size); obj_hdl = container_of(fsal_obj_hdl, struct hpss_fsal_obj_handle, obj_handle); HPSSFSAL_ucreds_from_opctx(op_ctx, &ucreds); if (fsal_xattr_name_2_uda(xattr_name, attrpath) == 0) { attr.len = 1; /* use malloc because HPSS may free it */ attr.Pair = malloc(sizeof(hpss_userattr_t)); if (attr.Pair == NULL) return fsalstat(ERR_FSAL_NOMEM, errno); attr.Pair[0].Key = attrpath; attr.Pair[0].Value = attrval; rc = hpss_UserAttrGetAttrHandle(&(obj_hdl->handle->ns_handle), NULL, &ucreds, &attr, UDA_API_VALUE); if (rc) { free(attr.Pair); return fsalstat(hpss2fsal_error(rc), rc); } if (attr.len > 0) { if (attr.Pair[0].Value != NULL) { char *noxml = hpss_ChompXMLHeader( attr.Pair[0].Value, NULL); strcpy(attrval, noxml); free(noxml); strncpy((char *)buffer_addr, attrval, buffer_size); *p_output_size = strlen(attrval) + 1; } else { strcpy((char *)buffer_addr, ""); *p_output_size = 1; } free(attr.Pair); rc = 0; } else { free(attr.Pair); rc = ERR_FSAL_NOENT; } } return fsalstat(rc, 0); }
fsal_status_t hpss_getextattr_value_by_id(struct fsal_obj_handle *fsal_obj_hdl, unsigned int xattr_id, caddr_t buffer_addr, size_t buffer_size, size_t *p_output_size) { struct hpss_fsal_obj_handle *obj_hdl; int rc, i; sec_cred_t ucreds; hpss_userattr_list_t attr_list; if (!fsal_obj_hdl || !p_output_size) return fsalstat(ERR_FSAL_FAULT, 0); obj_hdl = container_of(fsal_obj_hdl, struct hpss_fsal_obj_handle, obj_handle); HPSSFSAL_ucreds_from_opctx(op_ctx, &ucreds); /* check that this index match the type of entry */ if (xattr_id < XATTR_COUNT) { if (!do_match_type(xattr_list[xattr_id].flags, fsal_obj_hdl->type)) return fsalstat(ERR_FSAL_INVAL, 0); rc = xattr_list[xattr_id].get_func(fsal_obj_hdl, buffer_addr, buffer_size, p_output_size, &ucreds); } else if (xattr_id >= XATTR_COUNT) { memset(&attr_list, 0, sizeof(hpss_userattr_list_t)); LogFullDebug(COMPONENT_FSAL, "Getting value for UDA #%u", xattr_id - XATTR_COUNT); /* get list of UDAs for this entry, and * return the good value */ rc = hpss_UserAttrListAttrHandle(&(obj_hdl->handle->ns_handle), NULL, &ucreds, &attr_list, XML_ATTR); if (rc != 0) return fsalstat(hpss2fsal_error(rc), rc); else if (xattr_id - XATTR_COUNT >= attr_list.len) return fsalstat(ERR_FSAL_STALE, 0); if ((attr_list.Pair[xattr_id - XATTR_COUNT].Value != NULL) && (attr_list.Pair[xattr_id - XATTR_COUNT].Value[0] != '\0')) *p_output_size = snprintf((char *)buffer_addr, buffer_size, "%s\n", attr_list.Pair[xattr_id - XATTR_COUNT].Value); else { ((char *)buffer_addr)[0] = '\0'; *p_output_size = 0; } /* Allocated by hpss - use free */ for (i = 0; i < attr_list.len; i++) { free(attr_list.Pair[i].Key); free(attr_list.Pair[i].Value); } free(attr_list.Pair); return fsalstat(ERR_FSAL_NO_ERROR, 0); } return fsalstat(rc, 0); }
fsal_status_t hpss_list_ext_attrs(struct fsal_obj_handle *fsal_obj_hdl, unsigned int cookie, fsal_xattrent_t *xattrs_tab, unsigned int xattrs_tabsize, unsigned int *p_nb_returned, int *end_of_list) { struct hpss_fsal_obj_handle *obj_hdl; int index, out_index, rc; sec_cred_t ucreds; hpss_userattr_list_t attr_list; if (!fsal_obj_hdl || !xattrs_tab || !p_nb_returned || !end_of_list) return fsalstat(ERR_FSAL_FAULT, 0); obj_hdl = container_of(fsal_obj_hdl, struct hpss_fsal_obj_handle, obj_handle); HPSSFSAL_ucreds_from_opctx(op_ctx, &ucreds); for (index = cookie, out_index = 0; index < XATTR_COUNT && out_index < xattrs_tabsize; index++) { if (do_match_type(xattr_list[index].flags, fsal_obj_hdl->type)) { /* fills an xattr entry */ xattrs_tab[out_index].xattr_id = index; memcpy(xattrs_tab[out_index].xattr_name, xattr_list[index].xattr_name, strlen(xattr_list[index].xattr_name)+1); xattrs_tab[out_index].xattr_cookie = index + 1; /* set asked attributes */ file_attributes_to_xattr_attrs( &obj_hdl->attributes, &xattrs_tab[out_index].attributes, index); /* next output slot */ out_index++; } } /* save a call if output array is full */ if (out_index == xattrs_tabsize) { *end_of_list = FALSE; *p_nb_returned = out_index; return fsalstat(ERR_FSAL_NO_ERROR, 0); } /* get list of UDAs for this entry */ memset(&attr_list, 0, sizeof(hpss_userattr_list_t)); rc = hpss_UserAttrListAttrHandle(&(obj_hdl->handle->ns_handle), NULL, &ucreds, &attr_list, XML_ATTR); if (rc == -ENOENT) attr_list.len = 0; else if (rc) return fsalstat(hpss2fsal_error(rc), -rc); unsigned int i; for (i = 0; (i < attr_list.len) && (out_index < xattrs_tabsize); i++) { char attr_name[MAXNAMLEN]; /* the id is XATTR_COUNT + index of HPSS UDA */ index = XATTR_COUNT + i; /* continue while index < cookie */ if (index < cookie) continue; xattrs_tab[out_index].xattr_id = index; if (strlen(attr_list.Pair[i].Key) >= MAXNAMLEN) return fsalstat(ERR_FSAL_NAMETOOLONG, 0); /* HPSS UDAs namespace is slash-separated. * we convert '/' to '.' */ rc = hpss_uda_name_2_fsal(attr_list.Pair[i].Key, attr_name); if (rc != ERR_FSAL_NO_ERROR) return fsalstat(rc, 0); memcpy(xattrs_tab[out_index].xattr_name, attr_name, strlen(attr_name)+1); xattrs_tab[out_index].xattr_cookie = index + 1; /* set asked attributes */ file_attributes_to_xattr_attrs( &obj_hdl->attributes, &xattrs_tab[out_index].attributes, index); /* we know the size here (+2 for \n\0) */ if (attr_list.Pair[i].Value != NULL) xattrs_tab[out_index].attributes.filesize = strlen(attr_list.Pair[i].Value) + 2; /* next output slot */ out_index++; } /* Allocated by hpss - use free */ for (index = 0; index < attr_list.len; index++) { free(attr_list.Pair[index].Key); free(attr_list.Pair[index].Value); } free(attr_list.Pair); /* not end of list if there is more UDAs */ if (i < attr_list.len) *end_of_list = FALSE; else *end_of_list = TRUE; *p_nb_returned = out_index; return fsalstat(ERR_FSAL_NO_ERROR, 0); }
static int hpss_get_file_slevel(struct fsal_obj_handle *fsal_obj_hdl, caddr_t buffer_addr, size_t buffer_size, size_t *p_output_size, void *arg) { struct hpss_fsal_obj_handle *obj_hdl; sec_cred_t *p_ucreds = arg; hpss_xfileattr_t hpss_xattr; char tmpstr[1024]; char *outbuff; int rc, i, j; /* sanity checks. */ if (!fsal_obj_hdl || !p_output_size || !buffer_addr || !p_ucreds) return ERR_FSAL_FAULT; obj_hdl = container_of(fsal_obj_hdl, struct hpss_fsal_obj_handle, obj_handle); rc = hpss_FileGetXAttributesHandle(&(obj_hdl->handle->ns_handle), NULL, p_ucreds, API_GET_STATS_FOR_ALL_LEVELS, 0, &hpss_xattr); if (rc == HPSS_ENOENT) return ERR_FSAL_STALE; if (rc) return hpss2fsal_error(rc); /* now write info to buffer */ outbuff = (char *)buffer_addr; outbuff[0] = '\0'; for (i = 0; i < HPSS_MAX_STORAGE_LEVELS; i++) { if (hpss_xattr.SCAttrib[i].Flags == 0) continue; if (hpss_xattr.SCAttrib[i].Flags & BFS_BFATTRS_LEVEL_IS_DISK) snprintf(tmpstr, 1024, "Level %u (disk): %"PRIu64" bytes\n", i, hpss2fsal_64(hpss_xattr.SCAttrib[i]. BytesAtLevel)); else if (hpss_xattr.SCAttrib[i].Flags & BFS_BFATTRS_LEVEL_IS_TAPE) snprintf(tmpstr, 1024, "Level %u (tape): %"PRIu64" bytes\n", i, hpss2fsal_64(hpss_xattr.SCAttrib[i]. BytesAtLevel)); else snprintf(tmpstr, 1024, "Level %u: %"PRIu64" bytes\n", i, hpss2fsal_64(hpss_xattr.SCAttrib[i]. BytesAtLevel)); if (strlen(tmpstr) + strlen(outbuff) < buffer_size) strcat(outbuff, tmpstr); else break; } /* free the returned structure (Cf. HPSS ClAPI documentation) */ for (i = 0; i < HPSS_MAX_STORAGE_LEVELS; i++) for (j = 0; j < hpss_xattr.SCAttrib[i].NumberOfVVs; j++) if (hpss_xattr.SCAttrib[i].VVAttrib[j].PVList != NULL) free(hpss_xattr.SCAttrib[i].VVAttrib[j]. PVList); *p_output_size = strlen(outbuff); return 0; }
/** * FSAL_access : * Tests whether the user or entity identified by the p_context structure * can access the object identified by object_handle, * as indicated by the access_type parameter. * * \param object_handle (input): * The handle of the object to test permissions on. * \param p_context (input): * Authentication context for the operation (export entry, user,...). * \param access_type (input): * Indicates the permissions to be tested. * This is an inclusive OR of the permissions * to be checked for the user specified by p_context. * Permissions constants are : * - FSAL_R_OK : test for read permission * - FSAL_W_OK : test for write permission * - FSAL_X_OK : test for exec permission * - FSAL_F_OK : test for file existence * \param object_attributes (optional input/output): * The post operation attributes for the object. * As input, it defines the attributes that the caller * wants to retrieve (by positioning flags into this structure) * and the output is built considering this input * (it fills the structure according to the flags it contains). * Can be NULL. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error, asked permission is granted) * - ERR_FSAL_ACCESS (object permissions doesn't fit asked access type) * - ERR_FSAL_STALE (object_handle does not address an existing object) * - ERR_FSAL_FAULT (a NULL pointer was passed as mandatory argument) * - Other error codes when something anormal occurs. */ fsal_status_t HPSSFSAL_access(hpssfsal_handle_t * object_handle, /* IN */ hpssfsal_op_context_t * p_context, /* IN */ fsal_accessflags_t access_type, /* IN */ fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ ) { int hpss_test_mode = 0; int rc; fsal_status_t st; /* sanity checks. * note : object_attributes is optionnal in FSAL_getattrs. */ if(!object_handle || !p_context) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_access); /* converts fsal access type to hpss access type */ hpss_test_mode = fsal2hpss_testperm(access_type); /* call to HPSS access */ TakeTokenFSCall(); rc = hpss_AccessHandle(&(object_handle->data.ns_handle), /* IN - parent object handle */ NULL, /* IN - path of file to check access rights */ hpss_test_mode, /* IN - Type of access to be checked */ &p_context->credential.hpss_usercred /* IN - user credentials */ #if HPSS_MAJOR_VERSION < 7 , NULL /* OUT - authorization ticket */ #endif ); ReleaseTokenFSCall(); /* convert returned code */ /* The HPSS_ENOENT error actually means that handle is STALE */ if(rc == HPSS_ENOENT) Return(ERR_FSAL_STALE, -rc, INDEX_FSAL_access); else if(rc) Return(hpss2fsal_error(rc), -rc, INDEX_FSAL_access); /* get attributes if object_attributes is not null. * If an error occures during getattr operation, * it is returned, even though the access operation succeeded. */ if(object_attributes) { fsal_status_t status; status = FSAL_getattrs(object_handle, p_context, object_attributes); /* on error, we set a special bit in the mask. */ if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(object_attributes->asked_attributes); FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); } } Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_access); }
fsal_status_t HPSSFSAL_readdir(hpssfsal_dir_t * dir_descriptor, /* IN */ fsal_op_context_t * p_context, /* IN */ hpssfsal_cookie_t start_position, /* IN */ fsal_attrib_mask_t get_attr_mask, /* IN */ fsal_mdsize_t buffersize, /* IN */ fsal_dirent_t * pdirent, /* OUT */ hpssfsal_cookie_t * end_position, /* OUT */ fsal_count_t * nb_entries, /* OUT */ fsal_boolean_t * end_of_dir /* OUT */ ) { int rc, returned, i; fsal_status_t st; fsal_attrib_mask_t handle_attr_mask; fsal_count_t current_nb_entries, missing_entries, max_dir_entries; /* hpss_ReadRawAttrsHandle arguments. */ u_signed64 curr_start_position; unsigned32 buff_size_in; unsigned32 bool_getattr_in; unsigned32 bool_eod_out; u_signed64 last_offset_out; //ns_DirEntry_t outbuff[FSAL_READDIR_SIZE]; ns_DirEntry_t * outbuff = NULL ; /* sanity checks */ if(!dir_descriptor || !pdirent || !end_position || !nb_entries || !end_of_dir) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); if((outbuff = gsh_calloc(FSAL_READDIR_SIZE, sizeof(ns_DirEntry_t))) == NULL) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); /* handle provides : suppattr, type, fileid */ /** @todo : does handle provide mounted_on_fileid ? */ handle_attr_mask = FSAL_ATTR_SUPPATTR | FSAL_ATTR_TYPE | FSAL_ATTR_FILEID; /* if the handle cannot provide the requested attributes, * we have to retrieve file attributes. */ if(get_attr_mask & (~handle_attr_mask)) bool_getattr_in = TRUE; else bool_getattr_in = FALSE; /* init values */ curr_start_position = start_position.data; bool_eod_out = 0; current_nb_entries = 0; max_dir_entries = (buffersize / sizeof(fsal_dirent_t)); /* while we haven't filled the output buffer * and the end of dir has not been reached : */ while((current_nb_entries < max_dir_entries) && (!bool_eod_out)) { missing_entries = max_dir_entries - current_nb_entries; /* If the requested count is smaller than the default FSAL_READDIR_SIZE, * we use a smaller output buffer. */ if(missing_entries < FSAL_READDIR_SIZE) buff_size_in = missing_entries * sizeof(ns_DirEntry_t); else buff_size_in = FSAL_READDIR_SIZE * sizeof(ns_DirEntry_t); /* call to hpss clapi */ TakeTokenFSCall(); rc = HPSSFSAL_ReadRawAttrsHandle(&(dir_descriptor->dir_handle.data.ns_handle), curr_start_position, &dir_descriptor->context.credential.hpss_usercred, buff_size_in, bool_getattr_in, ReturnInconsistentDirent, &bool_eod_out, &last_offset_out, outbuff); ReleaseTokenFSCall(); if(rc < 0) { gsh_free( outbuff ) ; Return(hpss2fsal_error(rc), -rc, INDEX_FSAL_readdir); } else returned = rc; /* Fills the fsal dirent list. */ for(i = 0; i < returned; i++) { memset( (char *)&(pdirent[current_nb_entries].handle), 0, sizeof( hpssfsal_handle_t ) ) ; pdirent[current_nb_entries].handle.data.ns_handle = outbuff[i].ObjHandle; pdirent[current_nb_entries].handle.data.obj_type = hpss2fsal_type(outbuff[i].ObjHandle.Type); st = FSAL_str2name((char *)outbuff[i].Name, HPSS_MAX_FILE_NAME, &pdirent[current_nb_entries].name); /** @todo : test returned status */ pdirent[current_nb_entries].cookie.data = outbuff[i].ObjOffset; /* set asked attributes */ pdirent[current_nb_entries].attributes.asked_attributes = get_attr_mask; if(bool_getattr_in) { /* convert HPSS attributes to fsal attributes */ st = hpss2fsal_attributes(&outbuff[i].ObjHandle, &outbuff[i].Attrs, &pdirent[current_nb_entries].attributes); /* on error, we set a special bit in the mask. */ if(FSAL_IS_ERROR(st)) { FSAL_CLEAR_MASK(pdirent[current_nb_entries].attributes. asked_attributes); FSAL_SET_MASK(pdirent[current_nb_entries].attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR); } } else if(get_attr_mask) { /* extract asked attributes from file handle */ st = hpssHandle2fsalAttributes(&outbuff[i].ObjHandle, &pdirent[current_nb_entries].attributes); /* on error, we set a special bit in the mask. */ if(FSAL_IS_ERROR(st)) { FSAL_CLEAR_MASK(pdirent[current_nb_entries].attributes. asked_attributes); FSAL_SET_MASK(pdirent[current_nb_entries].attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR); } } /* set the previous' next */ if(current_nb_entries) pdirent[current_nb_entries - 1].nextentry = &(pdirent[current_nb_entries]); /* current's next */ pdirent[current_nb_entries].nextentry = NULL; /* increment entries count */ current_nb_entries++; curr_start_position = last_offset_out; } } /* At this point, 2 cases : * - the requested count is reached * - the end of dir is reached. * However, the treatment is the same. */ /* setting output vars. */ /* if no item was read, the offset keeps the same. */ end_position->data = (current_nb_entries == 0 ? start_position.data : last_offset_out); *nb_entries = current_nb_entries; *end_of_dir = (bool_eod_out ? TRUE : FALSE); LogDebug(COMPONENT_FSAL, "%s() returned %u entries, end_of_dir=%d", __func__, *nb_entries, *end_of_dir); gsh_free( outbuff ) ; Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir); /* @todo badly set fsal_log ? */ }