Exemple #1
0
int get_path(posixfsal_handle_t * p_objecthandle,       /* IN */
             posixfsal_op_context_t * p_context,        /* IN */
             caddr_t buffer_addr,       /* IN/OUT */
             size_t buffer_size,        /* IN */
             size_t * p_output_size)    /* OUT */
{
  fsal_status_t status;
  fsal_path_t fsalpath;
  struct stat buffstat;

  if(!p_objecthandle || !p_context || !p_output_size)
    return ERR_FSAL_FAULT;

  status =
      fsal_internal_getPathFromHandle(p_context, p_objecthandle, 0, &fsalpath, &buffstat);

  if(FSAL_IS_ERROR(status))
    return status.major;

  strncpy(buffer_addr, fsalpath.path, buffer_size);
  *p_output_size = strlen((char *)buffer_addr) + 1;

  return 0;

}
Exemple #2
0
int get_inode(posixfsal_handle_t * p_objecthandle,      /* IN */
              posixfsal_op_context_t * p_context,       /* IN */
              caddr_t buffer_addr,      /* IN/OUT */
              size_t buffer_size,       /* IN */
              size_t * p_output_size)   /* OUT */
{
  fsal_status_t status;
  fsal_path_t fsalpath;
  struct stat buffstat;

  if(!p_objecthandle || !p_context || !p_output_size)
    return ERR_FSAL_FAULT;

  /* this retrieves device and inode from database */

  status =
      fsal_internal_getPathFromHandle(p_context, p_objecthandle, 0, &fsalpath, &buffstat);

  if(FSAL_IS_ERROR(status))
    return status.major;

  /* assuming buffer size is large enough for an int ! */

  memcpy(buffer_addr, &p_objecthandle->data.info.inode, sizeof(ino_t));
  *p_output_size = sizeof(ino_t);

  return 0;
}
Exemple #3
0
/**
 * FSAL_create:
 * Create a regular file.
 *
 * \param parent_directory_handle (input):
 *        Handle of the parent directory where the file is to be created.
 * \param p_filename (input):
 *        Pointer to the name of the file to be created.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param accessmode (input):
 *        Mode for the file to be created.
 *        (the umask defined into the FSAL configuration file
 *        will be applied on it).
 * \param object_handle (output):
 *        Pointer to the handle of the created file.
 * \param object_attributes (optional input/output): 
 *        The attributes of the created file.
 *        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).
 *        May be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occurred.
 */
fsal_status_t POSIXFSAL_create(fsal_handle_t * parent_directory_handle,  /* IN */
                               fsal_name_t * p_filename,        /* IN */
                               fsal_op_context_t * context,      /* IN */
                               fsal_accessmode_t accessmode,    /* IN */
                               fsal_handle_t * object_handle,    /* OUT */
                               fsal_attrib_list_t * p_object_attributes /* [ IN/OUT ] */
    )
{

  posixfsal_handle_t * p_parent_directory_handle
    = (posixfsal_handle_t *) parent_directory_handle;
  posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
  posixfsal_handle_t * p_object_handle = (posixfsal_handle_t *) p_object_handle;
  int rc, fd, errsv;
  int setgid_bit = 0;
  fsal_status_t status;

  fsal_path_t fsalpath;
  struct stat buffstat;
  fsal_posixdb_fileinfo_t info;
  mode_t unix_mode;

  /* sanity checks.
   * note : object_attributes is optional.
   */
  if(!p_parent_directory_handle || !p_context || !p_object_handle || !p_filename)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_create);

  /* convert fsal mode to unix mode. */
  unix_mode = fsal2unix_mode(accessmode);

  /* Apply umask */
  unix_mode = unix_mode & ~global_fs_info.umask;

  LogFullDebug(COMPONENT_FSAL, "Creation mode: 0%o", accessmode);

  /* build the destination path */
  status =
      fsal_internal_getPathFromHandle(p_context, p_parent_directory_handle, 1, &fsalpath,
                                      &buffstat);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_create);

  /* Check the user can write in the directory, and check the setgid bit on the directory */
  if(buffstat.st_mode & S_ISGID)
    setgid_bit = 1;

  status = fsal_internal_testAccess(p_context, FSAL_W_OK | FSAL_X_OK, &buffstat, NULL);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_create);

  status = fsal_internal_appendFSALNameToFSALPath(&fsalpath, p_filename);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_create);

  /* call to API */

  TakeTokenFSCall();
  /* create the file */
  fd = open(fsalpath.path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, unix_mode);   /* error if the file already exists */
  errsv = errno;
  if(fd == -1)
    goto releaseToken;
  /* close the file descriptor */
  rc = close(fd);
  errsv = errno;
  if(rc)
    goto releaseToken;
  /* stat the new file */
  rc = lstat(fsalpath.path, &buffstat);
  errsv = errno;

 releaseToken:
  ReleaseTokenFSCall();

  if(fd == -1 || rc)
    Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_create);

  /* add the file to the database */
  if(FSAL_IS_ERROR(status = fsal_internal_posix2posixdb_fileinfo(&buffstat, &info)))
    Return(status.major, status.minor, INDEX_FSAL_create);
  if(FSAL_IS_ERROR
     (status =
      fsal_internal_posixdb_add_entry(p_context->p_conn, p_filename, &info,
                                      p_parent_directory_handle, p_object_handle)))
    Return(status.major, status.minor, INDEX_FSAL_create);

  /* the file has been created */
  /* chown the file to the current user */

  if(p_context->credential.user != geteuid())
    {
      TakeTokenFSCall();
      /* if the setgid_bit was set on the parent directory,
       * do not change the group of the created file,
       * because it's already the parentdir's group */
      rc = lchown(fsalpath.path, p_context->credential.user,
                  setgid_bit ? -1 : (int)p_context->credential.group);
      errsv = errno;
      ReleaseTokenFSCall();
      if(rc)
        Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_create);

      buffstat.st_uid = p_context->credential.user;
      buffstat.st_gid = p_context->credential.group;
    }

  /* add the file to the database */

  if(p_object_attributes)
    {

      /* convert POSIX attributes to fsal attributes */
      status = posix2fsal_attributes(&buffstat, p_object_attributes);
      /* on error, we set a special bit in the mask. */
      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
          FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }

    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_create);

}
Exemple #4
0
/**
 * FSAL_mknode:
 * Create a special object in the filesystem.
 * Not supported upon HPSS.
 *
 * \return ERR_FSAL_NOTSUPP.
 */
fsal_status_t POSIXFSAL_mknode(fsal_handle_t * parentdir_hdl,   /* IN */
                               fsal_name_t * p_node_name,       /* IN */
                               fsal_op_context_t * context,      /* IN */
                               fsal_accessmode_t accessmode,    /* IN */
                               fsal_nodetype_t nodetype,        /* IN */
                               fsal_dev_t * dev,        /* IN */
                               fsal_handle_t * object_handle,    /* OUT (handle to the created node) */
                               fsal_attrib_list_t * node_attributes     /* [ IN/OUT ] */
    )
{
  posixfsal_handle_t * parentdir_handle = (posixfsal_handle_t *) parentdir_hdl;
  posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
  posixfsal_handle_t * p_object_handle = (posixfsal_handle_t *) object_handle;
  int rc, errsv;
  int setgid_bit = 0;
  struct stat buffstat;
  fsal_status_t status;
  fsal_path_t fsalpath;
  fsal_posixdb_fileinfo_t info;

  mode_t unix_mode = 0;
  dev_t unix_dev = 0;

  /* sanity checks.
   * note : link_attributes is optional.
   */
  if(!parentdir_handle || !p_context || !p_node_name)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mknode);

  unix_mode = fsal2unix_mode(accessmode);

  /* Apply umask */
  unix_mode = unix_mode & ~global_fs_info.umask;

  switch (nodetype)
    {
    case FSAL_TYPE_BLK:
      if(!dev)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mknode);
      unix_mode |= S_IFBLK;
      unix_dev = (dev->major << 8) | (dev->minor & 0xFF);
      break;

    case FSAL_TYPE_CHR:
      if(!dev)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mknode);
      unix_mode |= S_IFCHR;
      unix_dev = (dev->major << 8) | (dev->minor & 0xFF);
      break;

    case FSAL_TYPE_SOCK:
      unix_mode |= S_IFSOCK;
      break;

    case FSAL_TYPE_FIFO:
      unix_mode |= S_IFIFO;
      break;

    default:
      LogMajor(COMPONENT_FSAL, "Invalid node type in FSAL_mknode: %d", nodetype);
      Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_mknode);
    }

  /* build the destination path */
  status =
      fsal_internal_getPathFromHandle(p_context, parentdir_handle, 1, &fsalpath,
                                      &buffstat);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mknode);

  /* Check the user can write in the directory, and check weither the setgid bit on the directory */
  if(buffstat.st_mode & S_ISGID)
    setgid_bit = 1;

  status = fsal_internal_testAccess(p_context, FSAL_W_OK | FSAL_X_OK, &buffstat, NULL);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mknode);

  status = fsal_internal_appendFSALNameToFSALPath(&fsalpath, p_node_name);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mknode);

  /* creates the node, then stats it */
  TakeTokenFSCall();

  rc = mknod(fsalpath.path, unix_mode, unix_dev);
  if(!rc)
    rc = lstat(fsalpath.path, &buffstat);
  errsv = errno;

  ReleaseTokenFSCall();

  if(rc)
    Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_mknode);

  /* add the object to the database */
  if(FSAL_IS_ERROR(status = fsal_internal_posix2posixdb_fileinfo(&buffstat, &info)))
    Return(status.major, status.minor, INDEX_FSAL_mknode);

  if(FSAL_IS_ERROR
     (status =
      fsal_internal_posixdb_add_entry(p_context->p_conn, p_node_name, &info,
                                      parentdir_handle, p_object_handle)))
    Return(status.major, status.minor, INDEX_FSAL_mknode);

  /* the node has been created */
  /* chown the file to the current user/group */

  if(p_context->credential.user != geteuid())
    {
      TakeTokenFSCall();

      /* if the setgid_bit was set on the parent directory, do not change the group of the created file, because it's already the parentdir's group */
      rc = lchown(fsalpath.path, p_context->credential.user,
                  setgid_bit ? -1 : (int)p_context->credential.group);
      errsv = errno;

      ReleaseTokenFSCall();

      if(rc)
        Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_mknode);

      buffstat.st_uid = p_context->credential.user;
      buffstat.st_gid = p_context->credential.group;
    }

  /* Fills the attributes if needed */
  if(node_attributes)
    {

      status = posix2fsal_attributes(&buffstat, node_attributes);

      /* on error, we set a special bit in the mask. */

      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(node_attributes->asked_attributes);
          FSAL_SET_MASK(node_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }

    }

  /* Finished */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_mknode);

}
Exemple #5
0
/**
 * FSAL_link:
 * Create a hardlink.
 *
 * \param target_handle (input):
 *        Handle of the target object.
 * \param dir_handle (input):
 *        Pointer to the directory handle where
 *        the hardlink is to be created.
 * \param p_link_name (input):
 *        Pointer to the name of the hardlink to be created.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param accessmode (input):
 *        Mode for the directory to be created.
 *        (the umask defined into the FSAL configuration file
 *        will be applied on it).
 * \param attributes (optionnal input/output): 
 *        The post_operation attributes of the linked 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).
 *        May be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t POSIXFSAL_link(fsal_handle_t * target_handle,      /* IN */
                             fsal_handle_t * dir_handle, /* IN */
                             fsal_name_t * p_link_name, /* IN */
                             fsal_op_context_t * context,        /* IN */
                             fsal_attrib_list_t * p_attributes  /* [ IN/OUT ] */
    )
{

  posixfsal_handle_t * p_target_handle = (posixfsal_handle_t *) target_handle;
  posixfsal_handle_t * p_dir_handle = (posixfsal_handle_t *) dir_handle;
  posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
  int rc, errsv;
  fsal_status_t status;
  fsal_path_t fsalpath_old, fsalpath_new;
  fsal_posixdb_fileinfo_t info;
  posixfsal_handle_t newhandle;
  struct stat buffstat, buffstat_dir;

  /* sanity checks.
   * note : attributes is optional.
   */
  if(!p_target_handle || !p_dir_handle || !p_context || !p_link_name)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);

  /* Tests if hardlinking is allowed by configuration. */

  if(!global_fs_info.link_support)
    Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_link);

  LogFullDebug(COMPONENT_FSAL, "linking %llu/%i to %llu.%i/%s \n", p_target_handle->data.id,
               p_target_handle->data.ts, p_dir_handle->data.id, p_dir_handle->data.ts, p_link_name->name);

  /* get the old path */
  status =
      fsal_internal_getPathFromHandle(p_context, p_target_handle, 0, &fsalpath_old,
                                      &buffstat);
  if(FSAL_IS_ERROR(status))
    {
      Return(status.major, status.minor, INDEX_FSAL_link);
    }

  /* build the destination path and check permissions on the directory */
  status =
      fsal_internal_getPathFromHandle(p_context, p_dir_handle, 1, &fsalpath_new,
                                      &buffstat_dir);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_link);

  status =
      fsal_internal_testAccess(p_context, FSAL_W_OK | FSAL_X_OK, &buffstat_dir, NULL);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_link);

  status = fsal_internal_appendFSALNameToFSALPath(&fsalpath_new, p_link_name);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_link);

  /* Create the link on the filesystem */

  TakeTokenFSCall();
  rc = link(fsalpath_old.path, fsalpath_new.path);
  errsv = errno;
  ReleaseTokenFSCall();
  if(rc)
    Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_link);

  /* add the link in the database */
  buffstat.st_nlink++;          /* avoid to stat the new file */
  status = fsal_internal_posix2posixdb_fileinfo(&buffstat, &info);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_link);

  if(FSAL_IS_ERROR
     (status =
      fsal_internal_posixdb_add_entry(p_context->p_conn, p_link_name, &info,
                                      p_dir_handle, &newhandle)))
    Return(status.major, status.minor, INDEX_FSAL_link);

  /* optionnaly get attributes */

  if(p_attributes)
    {
      TakeTokenFSCall();
      rc = lstat(fsalpath_old.path, &buffstat);
      errsv = errno;
      ReleaseTokenFSCall();
      if(rc)
        {
          status.major = posix2fsal_error(errsv);
          status.minor = errsv;
        }
      else
        {
          status = posix2fsal_attributes(&buffstat, p_attributes);
        }

      /* on error, we set a special bit in the mask. */
      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(p_attributes->asked_attributes);
          FSAL_SET_MASK(p_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }

    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_link);

}
Exemple #6
0
/**
 * FSAL_mkdir:
 * Create a directory.
 *
 * \param parent_directory_handle (input):
 *        Handle of the parent directory where
 *        the subdirectory is to be created.
 * \param p_dirname (input):
 *        Pointer to the name of the directory to be created.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param accessmode (input):
 *        Mode for the directory to be created.
 *        (the umask defined into the FSAL configuration file
 *        will be applied on it).
 * \param object_handle (output):
 *        Pointer to the handle of the created directory.
 * \param object_attributes (optionnal input/output): 
 *        The attributes of the created directory.
 *        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).
 *        May be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t POSIXFSAL_mkdir(fsal_handle_t * parent_directory_handle,   /* IN */
                              fsal_name_t * p_dirname,  /* IN */
                              fsal_op_context_t * context,       /* IN */
                              fsal_accessmode_t accessmode,     /* IN */
                              fsal_handle_t * object_handle,     /* OUT */
                              fsal_attrib_list_t * p_object_attributes  /* [ IN/OUT ] */
    )
{

  posixfsal_handle_t * p_parent_directory_handle
    = (posixfsal_handle_t *) parent_directory_handle;
  posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
  posixfsal_handle_t * p_object_handle = (posixfsal_handle_t *) object_handle;
  int rc, errsv;
  int setgid_bit = 0;
  struct stat buffstat;
  mode_t unix_mode;
  fsal_status_t status;
  fsal_path_t fsalpath;
  fsal_posixdb_fileinfo_t info;

  /* sanity checks.
   * note : object_attributes is optional.
   */
  if(!p_parent_directory_handle || !p_context || !p_object_handle || !p_dirname)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_mkdir);

  /* convert FSAL mode to HPSS mode. */
  unix_mode = fsal2unix_mode(accessmode);

  /* Apply umask */
  unix_mode = unix_mode & ~global_fs_info.umask;

  /* build the destination path */
  status =
      fsal_internal_getPathFromHandle(p_context, p_parent_directory_handle, 1, &fsalpath,
                                      &buffstat);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mkdir);

  /* Check the user can write in the directory, and check the setgid bit on the directory */
  if(buffstat.st_mode & S_ISGID)
    setgid_bit = 1;

  status = fsal_internal_testAccess(p_context, FSAL_W_OK | FSAL_X_OK, &buffstat, NULL);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mkdir);

  status = fsal_internal_appendFSALNameToFSALPath(&fsalpath, p_dirname);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_mkdir);

  /* creates the directory and stats it */
  TakeTokenFSCall();

  rc = mkdir(fsalpath.path, unix_mode);
  if(!rc)
    rc = lstat(fsalpath.path, &buffstat);
  errsv = errno;

  ReleaseTokenFSCall();

  if(rc)
    Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_mkdir);

  /* add the directory to the database */
  if(FSAL_IS_ERROR(status = fsal_internal_posix2posixdb_fileinfo(&buffstat, &info)))
    Return(status.major, status.minor, INDEX_FSAL_mkdir);
  if(FSAL_IS_ERROR
     (status =
      fsal_internal_posixdb_add_entry(p_context->p_conn, p_dirname, &info,
                                      p_parent_directory_handle, p_object_handle)))
    Return(status.major, status.minor, INDEX_FSAL_mkdir);

  /* the directory has been created */
  /* chown the file to the current user/group */

  if(p_context->credential.user != geteuid())
    {
      TakeTokenFSCall();
      /* if the setgid_bit was set on the parent directory, do not change the group of the created file, because it's already the parentdir's group */
      rc = lchown(fsalpath.path, p_context->credential.user,
                  setgid_bit ? -1 : (int)p_context->credential.group);
      errsv = errno;
      ReleaseTokenFSCall();
      if(rc)
        Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_mkdir);

      buffstat.st_uid = p_context->credential.user;
      buffstat.st_gid = p_context->credential.group;
    }

  /* Fills the attributes if needed */
  if(p_object_attributes)
    {

      status = posix2fsal_attributes(&buffstat, p_object_attributes);

      /* on error, we set a special bit in the mask. */

      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
          FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }

    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_mkdir);

}
Exemple #7
0
/**
 * FSAL_opendir :
 *     Opens a directory for reading its content.
 *     
 * \param dir_handle (input)
 *         the handle of the directory to be opened.
 * \param cred (input)
 *         Permission context for the operation (user,...).
 * \param dir_descriptor (output)
 *         pointer to an allocated structure that will receive
 *         directory stream informations, on successfull completion.
 * \param dir_attributes (optional output)
 *         On successfull completion,the structure pointed
 *         by dir_attributes receives the new directory attributes.
 *         May be NULL.
 * 
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t POSIXFSAL_opendir(fsal_handle_t * dir_handle,      /* IN */
                                fsal_op_context_t * context,     /* IN */
                                fsal_dir_t * dir_descriptor,     /* OUT */
                                fsal_attrib_list_t * p_dir_attributes   /* [ IN/OUT ] */
    )
{
  posixfsal_handle_t * p_dir_handle = (posixfsal_handle_t *) dir_handle;
  posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
  posixfsal_dir_t * p_dir_descriptor = (posixfsal_dir_t *) dir_descriptor;
  int rc, errsv;
  fsal_status_t status;

  fsal_path_t fsalpath;
  struct stat buffstat;

  /* sanity checks
   * note : dir_attributes is optionnal.
   */
  if(!p_dir_handle || !p_context || !p_dir_descriptor)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_opendir);

  /* get the path of the directory */
  status =
      fsal_internal_getPathFromHandle(p_context, p_dir_handle, 1, &fsalpath, &buffstat);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_opendir);

  /* Test access rights for this directory */

  status = fsal_internal_testAccess(p_context, FSAL_R_OK, &buffstat, NULL);
  if(FSAL_IS_ERROR(status))
    Return(status.major, status.minor, INDEX_FSAL_opendir);

  /* if everything is OK, fills the dir_desc structure : */

  TakeTokenFSCall();
  p_dir_descriptor->p_dir = opendir(fsalpath.path);
  ReleaseTokenFSCall();
  if(!p_dir_descriptor->p_dir)
    Return(posix2fsal_error(errno), errno, INDEX_FSAL_opendir);

  memcpy(&(p_dir_descriptor->context), p_context, sizeof(posixfsal_op_context_t));
  memcpy(&(p_dir_descriptor->path), &fsalpath, sizeof(fsal_path_t));
  memcpy(&(p_dir_descriptor->handle), p_dir_handle, sizeof(posixfsal_handle_t));

#ifdef _USE_POSIXDB_READDIR_BLOCK
  p_dir_descriptor->p_dbentries = NULL;
  p_dir_descriptor->dbentries_count = 0;
  /* fill the p_dbentries list */
  statusdb = fsal_posixdb_getChildren(p_dir_descriptor->context.p_conn,
                                      &(p_dir_descriptor->handle),
                                      FSAL_POSIXDB_MAXREADDIRBLOCKSIZE,
                                      &(p_dir_descriptor->p_dbentries),
                                      &(p_dir_descriptor->dbentries_count));
  if(FSAL_POSIXDB_IS_ERROR(statusdb))   /* too many entries in the directory, or another error */
    p_dir_descriptor->dbentries_count = -1;

#endif
  if(p_dir_attributes)
    {

      TakeTokenFSCall();
      rc = lstat(fsalpath.path, &buffstat);
      errsv = errno;
      ReleaseTokenFSCall();
      if(rc)                    /* lstat failed */
        goto attr_err;

      status = posix2fsal_attributes(&buffstat, p_dir_attributes);
      if(FSAL_IS_ERROR(status))
        {
 attr_err:
          FSAL_CLEAR_MASK(p_dir_attributes->asked_attributes);
          FSAL_SET_MASK(p_dir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }
    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_opendir);

}
Exemple #8
0
/**
 * FSAL_open:
 * Open a regular file for reading/writing its data content.
 *
 * \param filehandle (input):
 *        Handle of the file to be read/modified.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param openflags (input):
 *        Flags that indicates behavior for file opening and access.
 *        This is an inclusive OR of the following values
 *        ( such of them are not compatible) :
 *        - FSAL_O_RDONLY: opening file for reading only.
 *        - FSAL_O_RDWR: opening file for reading and writing.
 *        - FSAL_O_WRONLY: opening file for writting only.
 *        - FSAL_O_APPEND: always write at the end of the file.
 *        - FSAL_O_TRUNC: truncate the file to 0 on opening.
 * \param file_descriptor (output):
 *        The file descriptor to be used for FSAL_read/write operations.
 * \param file_attributes (optionnal input/output):
 *        Post operation attributes.
 *        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).
 *
 * \return Major error codes:
 *      - ERR_FSAL_NO_ERROR: no error.
 *      - Another error code if an error occured during this call.
 */
fsal_status_t POSIXFSAL_open(fsal_handle_t * filehandle, /* IN */
                             fsal_op_context_t * context,        /* IN */
                             fsal_openflags_t openflags,        /* IN */
                             fsal_file_t * file_descriptor,      /* OUT */
                             fsal_attrib_list_t * p_file_attributes     /* [ IN/OUT ] */
                            )
{
    posixfsal_handle_t * p_filehandle = (posixfsal_handle_t *) filehandle;
    posixfsal_op_context_t * p_context = (posixfsal_op_context_t *) context;
    posixfsal_file_t * p_file_descriptor = (posixfsal_file_t *) file_descriptor;
    int rc, errsv;
    fsal_status_t status;

    fsal_path_t fsalpath;
    struct stat buffstat;
#ifdef _FSAL_POSIX_USE_STREAM
    char posix_flags[4];          /* stores r, r+, w, w+, a, or a+ */
#else
    int posix_flags;
#endif

    /* sanity checks.
     * note : file_attributes is optional.
     */
    if(!p_filehandle || !p_context || !p_file_descriptor)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_open);

    status =
        fsal_internal_getPathFromHandle(p_context, p_filehandle, 0, &fsalpath, &buffstat);
    if(FSAL_IS_ERROR(status))
        Return(status.major, status.minor, INDEX_FSAL_open);

    status =
        fsal_internal_testAccess(p_context,
                                 (openflags & FSAL_O_RDONLY ? FSAL_R_OK : FSAL_W_OK) |
                                 FSAL_OWNER_OK, &buffstat, NULL);
    if(FSAL_IS_ERROR(status))
        Return(status.major, status.minor, INDEX_FSAL_open);

    /* convert fsal open flags to posix open flags */
    rc = fsal2posix_openflags(openflags, &posix_flags);

    /* flags conflicts. */
    if(rc)
    {
        LogEvent(COMPONENT_FSAL, "Invalid/conflicting flags : %#X", openflags);
        Return(rc, 0, INDEX_FSAL_open);
    }

    TakeTokenFSCall();
#ifdef _FSAL_POSIX_USE_STREAM
    p_file_descriptor->p_file = fopen(fsalpath.path, posix_flags);
    errsv = errno;
    ReleaseTokenFSCall();

    if(!(p_file_descriptor->p_file))
        Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_open);
#else
    p_file_descriptor->filefd = open(fsalpath.path, posix_flags);
    errsv = errno;
    ReleaseTokenFSCall();
#endif

    /* set the read-only flag of the file descriptor */
    p_file_descriptor->ro = openflags & FSAL_O_RDONLY;

    /* output attributes */
    if(p_file_attributes)
    {

        status = posix2fsal_attributes(&buffstat, p_file_attributes);

        if(FSAL_IS_ERROR(status))
        {
            FSAL_CLEAR_MASK(p_file_attributes->asked_attributes);
            FSAL_SET_MASK(p_file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }
    }

    Return(ERR_FSAL_NO_ERROR, errsv, INDEX_FSAL_open); /* use the error... */

}