static long cephwrap_telldir(struct vfs_handle_struct *handle, DIR *dirp) { long ret; DBG_DEBUG("[CEPH] telldir(%p, %p)\n", handle, dirp); ret = ceph_telldir(handle->data, (struct ceph_dir_result *) dirp); DBG_DEBUG("[CEPH] telldir(...) = %ld\n", ret); WRAP_RETURN(ret); }
/** * FSAL_readdir : * Read the entries of an opened directory. * * \param 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 dirents (output) * Adress of the buffer where the direntries are to be stored. * \param end_position (output) * Cookie that indicates the current position in the directory. * \param count (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 CEPHFSAL_readdir(fsal_dir_t *extdescriptor, fsal_op_context_t * p_context, /* IN */ fsal_cookie_t extstart, fsal_attrib_mask_t attrmask, fsal_mdsize_t buffersize, fsal_dirent_t *dirents, fsal_cookie_t *extend, fsal_count_t *count, fsal_boolean_t *end_of_dir) { int rc = 0; fsal_status_t status; struct dirent de; cephfsal_dir_t* descriptor = (cephfsal_dir_t*) extdescriptor; struct ceph_mount_info *cmount = descriptor->ctx.export_context->cmount; loff_t start = ((cephfsal_cookie_t*) extstart.data)->cookie; loff_t* end = &((cephfsal_cookie_t*) extend->data)->cookie; unsigned int max_entries = buffersize / sizeof(fsal_dirent_t); /* sanity checks */ if(!descriptor || !dirents || !end || !count || !end_of_dir) Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readdir); *end_of_dir = FALSE; *count = 0; TakeTokenFSCall(); (void) ceph_seekdir(cmount, DH(descriptor), start); while ((*count <= max_entries) && !(*end_of_dir)) { struct stat st; memset(&dirents[*count], sizeof(fsal_dirent_t), 0); memset(&de, sizeof(struct dirent), 0); memset(&st, sizeof(struct stat), 0); int stmask = 0; TakeTokenFSCall(); rc = ceph_readdirplus_r(cmount, DH(descriptor), &de, &st, &stmask); if (rc < 0) /* Error */ Return(posix2fsal_error(rc), 0, INDEX_FSAL_readdir); else if (rc == 1) { /* Got a dirent */ cephfsal_handle_t* entryhandle = (cephfsal_handle_t*) &(dirents[*count].handle.data); cephfsal_cookie_t* entrycookie = (cephfsal_cookie_t*) &(dirents[*count].cookie); /* skip . and .. */ if(!strcmp(de.d_name, ".") || !strcmp(de.d_name, "..")) continue; entryhandle->data.vi.ino.val = st.st_ino; entryhandle->data.vi.snapid.val = st.st_dev; status = FSAL_str2name(de.d_name, FSAL_MAX_NAME_LEN, &(dirents[*count].name)); if(FSAL_IS_ERROR(status)) ReturnStatus(status, INDEX_FSAL_readdir); entrycookie->data.cookie = ceph_telldir(cmount, DH(descriptor)); dirents[*count].attributes.asked_attributes = attrmask; status = posix2fsal_attributes(&st, &(dirents[*count].attributes)); if(FSAL_IS_ERROR(status)) { FSAL_CLEAR_MASK(dirents[*count].attributes .asked_attributes); FSAL_SET_MASK(dirents[*count].attributes.asked_attributes, FSAL_ATTR_RDATTR_ERR); } if (*count != 0) { dirents[(*count)-1].nextentry = &(dirents[*count]); } (*count)++; } else if (rc == 0) /* EOF */ *end_of_dir = TRUE; else{ /* Can't happen */ abort(); } } /* while */ (*end) = ceph_telldir(cmount, DH(descriptor)); Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readdir); }