示例#1
0
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);
}
示例#2
0
/**
 * 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);
}