fsal_status_t WRAP_FUSEFSAL_lookup(fsal_handle_t * p_parent_directory_handle, /* IN */ fsal_name_t * p_filename, /* IN */ fsal_op_context_t * p_context, /* IN */ fsal_handle_t * p_object_handle, /* OUT */ fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */ ) { return FUSEFSAL_lookup((fusefsal_handle_t *) p_parent_directory_handle, p_filename, (fusefsal_op_context_t *) p_context, (fusefsal_handle_t *) p_object_handle, p_object_attributes); }
fsal_status_t FUSEFSAL_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 = FUSEFSAL_lookup(dirhandle, filename, p_context, &filehandle, file_attributes); if(FSAL_IS_ERROR(fsal_status)) return fsal_status; return FUSEFSAL_open(&filehandle, p_context, openflags, file_descriptor, file_attributes); }
/** * FSAL_readdir : * Read the entries of an opened directory. * * \param dir_descriptor (input): * Pointer to the directory descriptor filled by FSAL_opendir. * \param start_position (input): * Cookie that indicates the first object to be read during * this readdir operation. * This should be : * - FSAL_READDIR_FROM_BEGINNING for reading the content * of the directory from the beginning. * - The end_position parameter returned by the previous * call to FSAL_readdir. * \param get_attr_mask (input) * Specify the set of attributes to be retrieved for directory entries. * \param buffersize (input) * The size (in bytes) of the buffer where * the direntries are to be stored. * \param pdirent (output) * Adresse of the buffer where the direntries are to be stored. * \param end_position (output) * Cookie that indicates the current position in the directory. * \param nb_entries (output) * Pointer to the number of entries read during the call. * \param end_of_dir (output) * Pointer to a boolean that indicates if the end of dir * has been reached during the call. * * \return Major error codes : * - ERR_FSAL_NO_ERROR (no error) * - ERR_FSAL_FAULT (a NULL pointer was passed as mandatory argument) * - Other error codes can be returned : * ERR_FSAL_IO, ... */ fsal_status_t FUSEFSAL_readdir(fsal_dir_t * dir_desc, /* IN */ fsal_cookie_t start_position, /* IN */ fsal_attrib_mask_t get_attr_mask, /* IN */ fsal_mdsize_t buffersize, /* IN */ fsal_dirent_t * pdirent, /* OUT */ fsal_cookie_t * end_position, /* OUT */ fsal_count_t * nb_entries, /* OUT */ fsal_boolean_t * end_of_dir /* OUT */ ) { int rc; char dir_path[FSAL_MAX_PATH_LEN]; fsal_dirbuff_t reqbuff; unsigned int i; fsal_status_t st; fusefsal_dir_t * dir_descriptor = (fusefsal_dir_t *)dir_desc; /* sanity checks */ if(!dir_descriptor || !pdirent || !end_position || !nb_entries || !end_of_dir) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); /* get the full path for dir inode */ rc = NamespacePath(dir_descriptor->dir_handle.data.inode, dir_descriptor->dir_handle.data.device, dir_descriptor->dir_handle.data.validator, dir_path); if(rc) Return(ERR_FSAL_STALE, rc, INDEX_FSAL_readdir); if(!p_fs_ops->readdir && !p_fs_ops->getdir) Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_readdir); /* set context so it can be retrieved by FS */ fsal_set_thread_context((fsal_op_context_t *) &dir_descriptor->context); /* prepare reaadir structure */ reqbuff.getattr_mask = get_attr_mask; reqbuff.nb_entries = 0; reqbuff.max_entries = (buffersize / sizeof(fsal_dirent_t)); reqbuff.p_entries = pdirent; reqbuff.status.major = 0; reqbuff.status.minor = 0; memcpy( (char *)&reqbuff.begin_off, (char *)&start_position.data, sizeof( off_t ) ) ; reqbuff.curr_off = 0 ; TakeTokenFSCall(); if(p_fs_ops->readdir) rc = p_fs_ops->readdir(dir_path, (void *)&reqbuff, ganefuse_fill_dir, (off_t)start_position.data, &dir_descriptor->dir_info); else rc = p_fs_ops->getdir(dir_path, (ganefuse_dirh_t) & reqbuff, ganefuse_dirfil_old); ReleaseTokenFSCall(); if(rc) Return(fuse2fsal_error(rc, TRUE), rc, INDEX_FSAL_readdir); else if(FSAL_IS_ERROR(reqbuff.status)) Return(reqbuff.status.major, reqbuff.status.minor, INDEX_FSAL_readdir); /* if no entry found */ if(reqbuff.nb_entries == 0) { *end_position = start_position; *end_of_dir = TRUE; *nb_entries = 0; LogFullDebug(COMPONENT_FSAL, "No entries found"); Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir); } /* at least 1 entry found */ /* we must do some operations on the final dirent array: * - chaining entries together * - if the filesystem did not provide stat buffers, * we must do lookup operations. * - adding dir entries to namespace */ for(i = 0; i < reqbuff.nb_entries; i++) { /* 1) chaining entries together */ if(i == reqbuff.nb_entries - 1) { /* last entry */ pdirent[i].nextentry = NULL; *end_position = pdirent[i].cookie; } else pdirent[i].nextentry = &(pdirent[i + 1]); /* 2) check weither the filesystem provided stat buff */ if(((fusefsal_handle_t *) &pdirent[i].handle)->data.inode == INODE_TO_BE_COMPLETED) { /* If not, make a lookup operation for this entry. * (this with automatically add it to namespace) */ pdirent[i].attributes.asked_attributes = get_attr_mask; LogFullDebug(COMPONENT_FSAL, "Inode to be completed"); st = FUSEFSAL_lookup((fsal_handle_t *) &dir_descriptor->dir_handle, &pdirent[i].name, (fsal_op_context_t *) &dir_descriptor->context, &pdirent[i].handle, &pdirent[i].attributes); if(FSAL_IS_ERROR(st)) Return(st.major, st.minor, INDEX_FSAL_readdir); } else { /* 3) just add entry to namespace except for '.' and '..' * Also set a validator for this entry. */ if(strcmp(pdirent[i].name.name, ".") && strcmp(pdirent[i].name.name, "..")) { LogFullDebug(COMPONENT_FSAL, "adding entry to namespace: %lX.%ld %s", ((fusefsal_handle_t *) &pdirent[i].handle)->data.device, ((fusefsal_handle_t *) &pdirent[i].handle)->data.inode, pdirent[i].name.name); ((fusefsal_handle_t *) &pdirent[i].handle)->data.validator = pdirent[i].attributes.ctime.seconds; NamespaceAdd(dir_descriptor->dir_handle.data.inode, dir_descriptor->dir_handle.data.device, dir_descriptor->dir_handle.data.validator, pdirent[i].name.name, ((fusefsal_handle_t *) &pdirent[i].handle)->data.inode, ((fusefsal_handle_t *) &pdirent[i].handle)->data.device, &(((fusefsal_handle_t *) &pdirent[i].handle)->data.validator)); } } } /* end of dir was reached if not enough entries were provided */ *end_of_dir = (reqbuff.nb_entries < reqbuff.max_entries); *nb_entries = reqbuff.nb_entries; LogFullDebug(COMPONENT_FSAL, "EOD = %d", *end_of_dir); Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir); }