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

}