コード例 #1
0
ファイル: fsal_create.c プロジェクト: nfs-ganesha/nfs-ganesha
/**
 *  @brief Create a hardlink.
 *
 *  @param dir_hdl Handle of the target object.
 *  @param gpfs_fh Pointer to the directory handle where hardlink is to be created.
 *  @param linkname Pointer to the name of the hardlink to be created.
 *  @param op_ctx Authentication context for the operation (user,...).
 *  @return ERR_FSAL_NO_ERROR on success, error otherwise
 *
 */
fsal_status_t
GPFSFSAL_link(struct fsal_obj_handle *dir_hdl, struct gpfs_file_handle *gpfs_fh,
              const char *linkname, const struct req_op_context *op_ctx)
{
    struct gpfs_filesystem *gpfs_fs;
    fsal_status_t status;
    struct gpfs_fsal_obj_handle *dest_dir;

    /* note : fsal_attr is optional.
     */
    if (!dir_hdl || !gpfs_fh || !op_ctx || !linkname)
        return fsalstat(ERR_FSAL_FAULT, 0);

    dest_dir =
        container_of(dir_hdl, struct gpfs_fsal_obj_handle, obj_handle);
    gpfs_fs = dir_hdl->fs->private_data;

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

    if (!op_ctx->fsal_export->exp_ops.
            fs_supports(op_ctx->fsal_export,
                        fso_link_support))
        return fsalstat(ERR_FSAL_NOTSUPP, 0);

    /* Create the link on the filesystem */

    fsal_set_credentials(op_ctx->creds);
    status = fsal_internal_link_fh(gpfs_fs->root_fd, gpfs_fh,
                                   dest_dir->handle, linkname);

    fsal_restore_ganesha_credentials();

    return status;
}
コード例 #2
0
ファイル: fsal_create.c プロジェクト: bongiojp/nfs-ganesha
/**
 * 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 GPFSFSAL_link(fsal_handle_t * p_target_handle,        /* IN */
                        fsal_handle_t * p_dir_handle,   /* IN */
                        fsal_name_t * p_link_name,      /* IN */
                        fsal_op_context_t * p_context,  /* IN */
                        fsal_attrib_list_t * p_attributes       /* [ IN/OUT ] */
    )
{
  fsal_status_t status;
  fsal_accessflags_t access_mask = 0;
  fsal_attrib_list_t parent_dir_attrs;

  /* sanity checks.
   * note : attributes is optional.
   */
  if(!p_target_handle || !p_dir_handle || !p_context || !p_context->export_context
     || !p_link_name || !p_link_name->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);

  /* retrieve target directory metadata */
  parent_dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES;
  status = GPFSFSAL_getattrs(p_dir_handle, p_context, &parent_dir_attrs);
  if(FSAL_IS_ERROR(status))
      goto out_status_fsal_err;

  /* check permission on target directory */

  /* Set both mode and ace4 mask */
  access_mask = FSAL_MODE_MASK_SET(FSAL_W_OK | FSAL_X_OK) |
                FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_ADD_FILE);

  if(!p_context->export_context->fe_static_fs_info->accesscheck_support)
  status = fsal_internal_testAccess(p_context, access_mask, NULL, &parent_dir_attrs);
  else
    status = fsal_internal_access(p_context, p_dir_handle, access_mask,
                                  &parent_dir_attrs);
  if(FSAL_IS_ERROR(status))
      goto out_status_fsal_err;

  /* Create the link on the filesystem */

  TakeTokenFSCall();
  status = fsal_internal_link_fh(p_context, p_target_handle, p_dir_handle,
                                 p_link_name);
  ReleaseTokenFSCall();

  if(FSAL_IS_ERROR(status))
      goto out_status_fsal_err;

  /* optionnaly get attributes */

  if(p_attributes)
    {
      status = GPFSFSAL_getattrs(p_target_handle, p_context, 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);

 out_status_fsal_err:

  ReturnStatus(status, INDEX_FSAL_link);
}