Example #1
0
fsal_status_t ZFSFSAL_symlink(zfsfsal_handle_t * parent_directory_handle,     /* IN */
                           fsal_name_t * p_linkname,    /* IN */
                           fsal_path_t * p_linkcontent, /* IN */
                           zfsfsal_op_context_t * p_context,       /* IN */
                           fsal_accessmode_t accessmode,        /* IN (ignored) */
                           zfsfsal_handle_t * link_handle, /* OUT */
                           fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */
    )
{

  int rc;

  /* sanity checks.
   * note : link_attributes is optional.
   */
  if(!parent_directory_handle ||
     !p_context || !link_handle || !p_linkname || !p_linkcontent)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);

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

  if(!global_fs_info.symlink_support)
    Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_symlink);

  TakeTokenFSCall();

  inogen_t object;
  rc = libzfswrap_symlink(p_context->export_context->p_vfs, &p_context->user_credential.cred,
                          parent_directory_handle->data.zfs_handle, p_linkname->name,
                          p_linkcontent->path, &object);

  ReleaseTokenFSCall();

  /* >> convert status and return on error <<  */

  /* >> set output handle << */
  link_handle->data.zfs_handle = object;
  link_handle->data.type = FSAL_TYPE_LNK;

  if(link_attributes)
    {

      fsal_status_t status = ZFSFSAL_getattrs(link_handle, p_context, link_attributes);

      /* On error, we set a flag in the returned attributes */
      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(link_attributes->asked_attributes);
          FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }
    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_symlink);
}
Example #2
0
fsal_status_t ZFSFSAL_symlink(fsal_handle_t * parent_directory_handle,     /* IN */
                           fsal_name_t * p_linkname,    /* IN */
                           fsal_path_t * p_linkcontent, /* IN */
                           fsal_op_context_t * p_context,       /* IN */
                           fsal_accessmode_t accessmode,        /* IN (ignored) */
                           fsal_handle_t * link_handle, /* OUT */
                           fsal_attrib_list_t * link_attributes /* [ IN/OUT ] */
    )
{

  creden_t cred;

  /* sanity checks.
   * note : link_attributes is optional.
   */
  if(!parent_directory_handle ||
     !p_context || !link_handle || !p_linkname || !p_linkcontent)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_symlink);

  /* Tests if symlinking is allowed by configuration. */
  if(!global_fs_info.symlink_support)
    Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_symlink);

  /* Hook to prevent creation of anything inside the snapshot */
  if(((zfsfsal_handle_t *)parent_directory_handle)->data.i_snap != 0)
  {
    LogDebug(COMPONENT_FSAL, "Trying to create a symlink inside a snapshot");
    Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_symlink);
  }

  cred.uid = p_context->credential.user;
  cred.gid = p_context->credential.group;

  TakeTokenFSCall();

  inogen_t object;
  libzfswrap_symlink(((zfsfsal_op_context_t *)p_context)->export_context->p_vfs,
                     &cred,
                     ((zfsfsal_handle_t *)parent_directory_handle)->data.zfs_handle,
                     p_linkname->name,
                     p_linkcontent->path, &object);

  ReleaseTokenFSCall();

  /* >> convert status and return on error <<  */

  /* >> set output handle << */
  ((zfsfsal_handle_t *)link_handle)->data.zfs_handle = object;
  ((zfsfsal_handle_t *)link_handle)->data.type = FSAL_TYPE_LNK;
  ((zfsfsal_handle_t *)link_handle)->data.i_snap = 0;

  if(link_attributes)
    {

      fsal_status_t status = ZFSFSAL_getattrs(link_handle, p_context, link_attributes);

      /* On error, we set a flag in the returned attributes */
      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(link_attributes->asked_attributes);
          FSAL_SET_MASK(link_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }
    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_symlink);
}