Пример #1
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 GPFSFSAL_open(fsal_handle_t * p_filehandle,   /* IN */
                        fsal_op_context_t * p_context,  /* IN */
                        fsal_openflags_t openflags,     /* IN */
                        fsal_file_t * file_desc,        /* OUT */
                        fsal_attrib_list_t * p_file_attributes  /* [ IN/OUT ] */
    )
{

  int rc, errsv;
  fsal_status_t status;

  int fd;
  int posix_flags = 0;
  gpfsfsal_file_t * p_file_descriptor = (gpfsfsal_file_t *)file_desc;

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

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

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

  TakeTokenFSCall();
  status = fsal_internal_handle2fd(p_context, p_filehandle, &fd, posix_flags);
  ReleaseTokenFSCall();

  if(FSAL_IS_ERROR(status))
    ReturnStatus(status, INDEX_FSAL_open);

  /* output attributes */
  if(p_file_attributes)
    {

      p_file_attributes->asked_attributes = GPFS_SUPPORTED_ATTRIBUTES;
      status = GPFSFSAL_getattrs(p_filehandle, p_context, p_file_attributes);
      if(FSAL_IS_ERROR(status))
        ReturnStatus(status, INDEX_FSAL_open);
    }

  TakeTokenFSCall();
  p_file_descriptor->fd = fd;
  errsv = errno;
  ReleaseTokenFSCall();

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

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open);

}
Пример #2
0
/*
 * Common code used by fsal_lookup and fsal_readdir -
 * given the name try to stat an entry. If an entry is
 * regular file or directory then open it and use fd2handle
 * to get a real handle, otherwise use inum2handle to fake
 * a handle.
 */
fsal_status_t
xfsfsal_stat_by_name(fsal_op_context_t * context,
		     int atfd,
		     const char *name,
		     fsal_handle_t *handle,
		     fsal_attrib_list_t * attributes)
{
  int rc;
  int errsv;
  struct stat buffstat;
  fsal_status_t st;

  TakeTokenFSCall();
  rc = fstatat(atfd, name, &buffstat, AT_SYMLINK_NOFOLLOW);
  errsv = errno;
  ReleaseTokenFSCall();
  if(rc < 0)
      ReturnCode(posix2fsal_error(errsv), errsv);

  if(S_ISDIR(buffstat.st_mode) ||  S_ISREG(buffstat.st_mode))
    {
      int tmpfd;

      TakeTokenFSCall();
      tmpfd = openat(atfd, name, O_RDONLY | O_NOFOLLOW, 0600);
      errsv = errno;
      ReleaseTokenFSCall();
      if(tmpfd < 0)
	  ReturnCode(posix2fsal_error(errsv), errsv);

      st = fsal_internal_fd2handle(context, tmpfd, handle);
      close(tmpfd);
    } 
  else
    {
       st = fsal_internal_inum2handle(context, buffstat.st_ino, handle);
    }

  if(FSAL_IS_ERROR(st))
    return st;

  if(attributes)
    {
      st = posix2fsal_attributes(&buffstat, attributes);
      if(FSAL_IS_ERROR(st))
	{
	  FSAL_CLEAR_MASK(attributes->asked_attributes);
	  FSAL_SET_MASK(attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
	}
    }
  return st;
}
Пример #3
0
/**
 * FSAL_getattrs:
 * Get attributes for the object specified by its filehandle.
 *
 * \param filehandle (input):
 *        The handle of the object to get parameters.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param object_attributes (mandatory input/output):
 *        The retrieved attributes for the 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).
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t XFSFSAL_getattrs(fsal_handle_t * p_filehandle, /* IN */
                               fsal_op_context_t * p_context,        /* IN */
                               fsal_attrib_list_t * p_object_attributes /* IN/OUT */
    )
{
  int rc, errsv;
  fsal_status_t st;
  int fd;
  struct stat buffstat;

  /* sanity checks.
   * note : object_attributes is mandatory in FSAL_getattrs.
   */
  if(!p_filehandle || !p_context || !p_object_attributes)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs);

  TakeTokenFSCall();
  st = fsal_internal_handle2fd(p_context, p_filehandle, &fd, O_RDONLY);
  ReleaseTokenFSCall();

  if(FSAL_IS_ERROR(st))
    ReturnStatus(st, INDEX_FSAL_getattrs);

  /* get file metadata */
  TakeTokenFSCall();
  rc = fstat(fd, &buffstat);
  errsv = errno;
  ReleaseTokenFSCall();

  close(fd);

  if(rc != 0)
    {
      if(errsv == ENOENT)
        Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_getattrs);
      else
        Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_getattrs);
    }

  /* convert attributes */
  st = posix2fsal_attributes(&buffstat, p_object_attributes);
  if(FSAL_IS_ERROR(st))
    {
      FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
      FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
      ReturnStatus(st, INDEX_FSAL_getattrs);
    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_getattrs);

}
Пример #4
0
/**
 * FSAL_sync:
 * This function is used for processing stable writes and COMMIT requests.
 * Calling this function makes sure the changes to a specific file are
 * written to disk rather than kept in memory.
 *
 * \param file_descriptor (input):
 *        The file descriptor returned by FSAL_open.
 *
 * \return Major error codes:
 *      - ERR_FSAL_NO_ERROR: no error.
 *      - Another error code if an error occured during this call.
 */
fsal_status_t XFSFSAL_sync(xfsfsal_file_t * p_file_descriptor       /* IN */)
{
  int rc, errsv;

  /* sanity checks. */
  if(!p_file_descriptor)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_sync);

  if( p_file_descriptor->fd == 0 )
    Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_sync); /* Nothing to sync, the file is not opened */

  /* Flush data. */
  TakeTokenFSCall();
  rc = fsync(p_file_descriptor->fd);
  errsv = errno;
  ReleaseTokenFSCall();

  if(rc)
    {
      LogEvent(COMPONENT_FSAL, "Error in fsync operation");
      Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_sync);
    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_sync);
}
Пример #5
0
fsal_status_t POSIXFSAL_close(fsal_file_t * file_descriptor,      /* IN */
                              fsal_op_context_t * p_context       /* IN */
                             )
{
    posixfsal_file_t * p_file_descriptor = (posixfsal_file_t *) file_descriptor;
    int rc, errsv;

    /* sanity checks. */
    if(!p_file_descriptor)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close);

    /* call to close */

    TakeTokenFSCall();

#ifdef _FSAL_POSIX_USE_STREAM
    rc = fclose(p_file_descriptor->p_file);
#else
    rc = close(p_file_descriptor->filefd);
#endif

    errsv = errno;

    ReleaseTokenFSCall();

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

    Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close);

}
Пример #6
0
fsal_status_t GPFSFSAL_close(fsal_file_t * p_file_descriptor        /* IN */
    )
{

  int rc, errsv;

  /* sanity checks. */
  if(!p_file_descriptor)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close);

  /* call to close */

  TakeTokenFSCall();

  rc = close(((gpfsfsal_file_t *)p_file_descriptor)->fd);
  errsv = errno;

  ReleaseTokenFSCall();

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

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close);

}
Пример #7
0
/**
 * FSAL_dynamic_fsinfo:
 * Return dynamic filesystem info such as
 * used size, free size, number of objects...
 *
 * \param filehandle (input):
 *        Handle of an object in the filesystem
 *        whom info is to be retrieved.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param dynamicinfo (output):
 *        Pointer to the static info of the filesystem.
 *
 * \return Major error codes:
 *      - ERR_FSAL_NO_ERROR: no error.
 *      - ERR_FSAL_FAULT: NULL pointer passed as input parameter.
 *      - ERR_FSAL_SERVERFAULT: Unexpected error.
 */
fsal_status_t GPFSFSAL_dynamic_fsinfo(gpfsfsal_handle_t * p_filehandle, /* IN */
                                  gpfsfsal_op_context_t * p_context,        /* IN */
                                  fsal_dynamicfsinfo_t * p_dynamicinfo  /* OUT */
    )
{
  fsal_path_t pathfsal;
  fsal_status_t status;
  struct statvfs buffstatvfs;
  int rc, errsv;
  /* sanity checks. */
  if(!p_filehandle || !p_dynamicinfo || !p_context)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_dynamic_fsinfo);

  TakeTokenFSCall();
  rc = fstatvfs(p_context->export_context->mount_root_fd, &buffstatvfs);
  errsv = errno;
  ReleaseTokenFSCall();
  if(rc)
    Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_dynamic_fsinfo);

  p_dynamicinfo->total_bytes = buffstatvfs.f_frsize * buffstatvfs.f_blocks;
  p_dynamicinfo->free_bytes = buffstatvfs.f_frsize * buffstatvfs.f_bfree;
  p_dynamicinfo->avail_bytes = buffstatvfs.f_frsize * buffstatvfs.f_bavail;

  p_dynamicinfo->total_files = buffstatvfs.f_files;
  p_dynamicinfo->free_files = buffstatvfs.f_ffree;
  p_dynamicinfo->avail_files = buffstatvfs.f_favail;

  p_dynamicinfo->time_delta.seconds = 1;
  p_dynamicinfo->time_delta.nseconds = 0;

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_dynamic_fsinfo);

}
Пример #8
0
/**
 *  return index if found,
 *  negative value on error.
 */
static int xattr_name_to_id(libzfswrap_vfs_t *p_vfs, zfsfsal_op_context_t *p_context, zfsfsal_handle_t *p_objecthandle, const char *psz_name, unsigned int *p_id)
{
  unsigned int i;
  char *psz_buffer, *ptr;
  size_t i_size;
  creden_t cred;

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

  /* get xattrs */
  TakeTokenFSCall();
  int rc = libzfswrap_listxattr(p_vfs, &cred,
                                p_objecthandle->data.zfs_handle, &psz_buffer, &i_size);
  ReleaseTokenFSCall();

  if(rc)
    return posix2fsal_error(rc);

  for(ptr = psz_buffer, i = 0; ptr < psz_buffer + i_size; i++, ptr += strlen(ptr) + 1)
  {
      if(!strcmp(psz_name, ptr))
      {
        *p_id = i + XATTR_COUNT;
        free(psz_buffer);
        return ERR_FSAL_NO_ERROR;
      }
  }
  free(psz_buffer);
  return ERR_FSAL_NOENT;
}
Пример #9
0
/**
 * FSAL_commit:
 * This function is used for processing stable writes and COMMIT requests.
 * Calling this function makes sure the changes to a specific file are
 * written to disk rather than kept in memory.
 *
 * \param file_descriptor (input):
 *        The file descriptor returned by FSAL_open.
 * \param offset:
 *        The starting offset for the portion of file to be synced
 * \param length:
 *        The length for the portion of file to be synced.
 *
 * \return Major error codes:
 *      - ERR_FSAL_NO_ERROR: no error.
 *      - Another error code if an error occured during this call.
 */
fsal_status_t POSIXFSAL_commit(fsal_file_t * file_descriptor,
                               fsal_op_context_t * p_context,        /* IN */
                               fsal_off_t    offset,
                               fsal_size_t   length )

{
    posixfsal_file_t * p_file_descriptor = (posixfsal_file_t *) file_descriptor;
    int rc, errsv;

    /* sanity checks. */
    if(!p_file_descriptor)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_commit);

    /* Flush data. */
    TakeTokenFSCall();
    rc = fsync(p_file_descriptor->filefd);
    errsv = errno;
    ReleaseTokenFSCall();

    if(rc)
    {
        LogEvent(COMPONENT_FSAL, "Error in fsync operation");
        Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_commit);
    }

    Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_commit);
}
Пример #10
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)
 *        - ERR_FSAL_STALE        (parent_directory_handle does not address an existing object)
 *        - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *        - Other error codes can be returned :
 *          ERR_FSAL_ACCESS, ERR_FSAL_EXIST, ERR_FSAL_IO, ...
 *            
 *        NB: if getting postop attributes failed,
 *        the function does not return an error
 *        but the FSAL_ATTR_RDATTR_ERR bit is set in
 *        the object_attributes->asked_attributes field.
 */
fsal_status_t ZFSFSAL_mkdir(zfsfsal_handle_t * parent_directory_handle,       /* IN */
                            fsal_name_t * p_dirname,       /* IN */
                            zfsfsal_op_context_t * p_context, /* IN */
                            fsal_accessmode_t accessmode,  /* IN */
                            zfsfsal_handle_t * object_handle, /* OUT */
                            fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */
    )
{

  int rc;
  mode_t unix_mode;

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

  /* convert fsal args to ZFS args */
  unix_mode = fsal2unix_mode(accessmode);


   /* Applying FSAL umask */
   unix_mode = unix_mode & ~global_fs_info.umask;

  TakeTokenFSCall();

  /* Create the directory */
  inogen_t object;
  rc = libzfswrap_mkdir(p_context->export_context->p_vfs, &p_context->user_credential.cred,
                        parent_directory_handle->data.zfs_handle, p_dirname->name, unix_mode, &object);

  ReleaseTokenFSCall();

  /* >> interpret returned error << */
  if(rc)
    Return(posix2fsal_error(rc), 0, INDEX_FSAL_create);

  /* set output handle */
  object_handle->data.zfs_handle = object;
  object_handle->data.type = FSAL_TYPE_DIR;

  if(object_attributes)
    {
      /**@TODO: skip this => libzfswrap_mkdir might return attributes */
      fsal_status_t status = ZFSFSAL_getattrs(object_handle, p_context, object_attributes);

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

    }

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

}
Пример #11
0
/**
 * FSAL_commit:
 * This function is used for processing stable writes and COMMIT requests.
 * Calling this function makes sure the changes to a specific file are
 * written to disk rather than kept in memory.
 *
 * \param file_descriptor (input):
 *        The file descriptor returned by FSAL_open.
 * \param offset:
 *        The starting offset for the portion of file to be synced       
 * \param length:
 *        The length for the portion of file to be synced.
 *
 * \return Major error codes:
 *      - ERR_FSAL_NO_ERROR: no error.
 *      - Another error code if an error occured during this call.
 */
fsal_status_t XFSFSAL_commit( fsal_file_t * p_file_descriptor,
                            fsal_op_context_t * p_context,        /* IN */
                            fsal_off_t    offset, 
                            fsal_size_t   length )
{
  int rc, errsv;

  /* sanity checks. */
  if(!p_file_descriptor)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_commit);

  if(((xfsfsal_file_t *)p_file_descriptor)->fd == 0 )
    Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_commit); /* Nothing to sync, the file is not opened */

  /* Flush data. */
  TakeTokenFSCall();
  rc = fsync(((xfsfsal_file_t *)p_file_descriptor)->fd);
  errsv = errno;
  ReleaseTokenFSCall();

  if(rc)
    {
      LogEvent(COMPONENT_FSAL, "Error in fsync operation");
      Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_commit);
    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_commit);
}
Пример #12
0
fsal_status_t ZFSFSAL_SetXAttrValue(fsal_handle_t * obj_handle,        /* IN */
                                 const fsal_name_t * xattr_name,        /* IN */
                                 fsal_op_context_t * p_context, /* IN */
                                 caddr_t buffer_addr,   /* IN */
                                 size_t buffer_size,    /* IN */
                                 int create     /* IN */
    )
{
  //@TODO: use the create parameter ?
  int rc;
  creden_t cred;
  zfsfsal_handle_t * p_objecthandle = (zfsfsal_handle_t *)obj_handle;

  /* Hook to prevent any modification in the snapshots */
  if(p_objecthandle->data.i_snap != 0)
    Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_SetXAttrValue);

  /* Remove trailing '\n', if any */
  chomp_attr_value((char*)buffer_addr, buffer_size);
  cred.uid = p_context->credential.user;
  cred.gid = p_context->credential.group;

  TakeTokenFSCall();
  rc = libzfswrap_setxattr(((zfsfsal_op_context_t *)p_context)->export_context->p_vfs, &cred,
                           p_objecthandle->data.zfs_handle, xattr_name->name, (char*)buffer_addr);
  ReleaseTokenFSCall();

  if(rc)
    Return(posix2fsal_error(rc), 0, INDEX_FSAL_SetXAttrValue);

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_SetXAttrValue);
}
Пример #13
0
/*
 * Free the resources allocated for reading directory entries.
 *     
 * \param dir_descriptor (input):
 *        Pointer to a directory descriptor filled by FSAL_opendir.
 * 
 * \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 dpmfsal_closedir(fsal_dir_t * dir_descriptor // IN
)
{
    int rc;

    // Sanity checks
    if (!dir_descriptor)
        Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_closedir);

    LogInfo(COMPONENT_FSAL, "dpmfsal_closedir: start");

    TakeTokenFSCall();
    rc = dpns_closedir(dir_descriptor->p_dir);
    ReleaseTokenFSCall();
    if (rc)
        Return(dpns2fsal_error(serrno), serrno, INDEX_FSAL_opendir);

    if (dpns_endsess() < 0)
    	Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_closedir);

    // Fill the descriptor with 0s
    memset(dir_descriptor, 0, sizeof(fsal_dir_t));

    Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_closedir);
}
Пример #14
0
/**
 *  Removes a xattr by Id
 *
 * \param p_objecthandle Handle of the object you want to get attribute for.
 * \param p_context pointer to the current security context.
 * \param xattr_id xattr's id
 */
fsal_status_t ZFSFSAL_RemoveXAttrById(fsal_handle_t * obj_handle,      /* IN */
                                   fsal_op_context_t * context,       /* IN */
                                   unsigned int xattr_id)       /* IN */
{
  int rc;
  creden_t cred;
  char psz_name[FSAL_MAX_NAME_LEN];
  zfsfsal_handle_t * p_objecthandle = (zfsfsal_handle_t *)obj_handle;
  zfsfsal_op_context_t *p_context = (zfsfsal_op_context_t *)context;

  /* Hook to prevent any modification in the snapshots */
  if(p_objecthandle->data.i_snap != 0)
    Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_SetXAttrValue);

  if((rc = xattr_id_to_name(p_context->export_context->p_vfs, p_context, p_objecthandle,
                            xattr_id, psz_name)))
    Return(rc, 0, INDEX_FSAL_SetXAttrValue);

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

  TakeTokenFSCall();
  rc = libzfswrap_removexattr(p_context->export_context->p_vfs, &cred,
                              p_objecthandle->data.zfs_handle, psz_name);
  ReleaseTokenFSCall();

  if(rc)
    Return(posix2fsal_error(rc), 0, INDEX_FSAL_SetXAttrValue);
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_SetXAttrValue);
}
Пример #15
0
fsal_status_t ZFSFSAL_close(zfsfsal_file_t * file_descriptor  /* IN */
    )
{
  int rc = 0;

  /* sanity checks. */
  if(!file_descriptor)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_close);

  TakeTokenFSCall();

  if(!file_descriptor->is_closed)
  {
    rc = libzfswrap_close(file_descriptor->p_vfs, &file_descriptor->cred,
                          file_descriptor->p_vnode, file_descriptor->flags);
    file_descriptor->is_closed = 1;
  }

  ReleaseTokenFSCall();

  if(rc)
    Return(posix2fsal_error(rc), rc, INDEX_FSAL_close);

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_close);

}
Пример #16
0
/**
 * Get the value of an extended attribute from its name.
 *
 * \param p_objecthandle Handle of the object you want to get attribute for.
 * \param xattr_name the name of the attribute to be read.
 * \param p_context pointer to the current security context.
 * \param buffer_addr address of the buffer where the xattr value is to be stored.
 * \param buffer_size size of the buffer where the xattr value is to be stored.
 * \param p_output_size size of the data actually stored into the buffer.
 */
fsal_status_t ZFSFSAL_GetXAttrValueByName(fsal_handle_t * obj_handle,  /* IN */
                                          const fsal_name_t * xattr_name,  /* IN */
                                          fsal_op_context_t * p_context,   /* IN */
                                          caddr_t buffer_addr,     /* IN/OUT */
                                          size_t buffer_size,      /* IN */
                                          size_t * p_output_size   /* OUT */
    )
{
  unsigned int index;
  char *psz_value;
  int rc;
  creden_t cred;
  zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle;

  /* sanity checks */
  if(!p_objecthandle || !p_context || !p_output_size || !buffer_addr || !xattr_name)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_GetXAttrValue);

  /* look for this name */
  for(index = 0; index < XATTR_COUNT; index++)
    {
      if(do_match_type(xattr_list[index].flags, p_objecthandle->data.type)
         && !strcmp(xattr_list[index].xattr_name, xattr_name->name))
        {

          return ZFSFSAL_GetXAttrValueById((fsal_handle_t *)p_objecthandle, index, p_context, buffer_addr,
                                           buffer_size, p_output_size);
        }
    }

  /* Get the right VFS */
  libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle);
  if(!p_vfs)
  {
    ZFSFSAL_VFS_Unlock();
    Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_GetXAttrValue);
  }
  cred.uid = p_context->credential.user;
  cred.gid = p_context->credential.group;

  TakeTokenFSCall();
  if((rc = libzfswrap_getxattr(p_vfs, &cred,
                               p_objecthandle->data.zfs_handle, xattr_name->name, &psz_value)))
  {
    ZFSFSAL_VFS_Unlock();
    Return(posix2fsal_error(rc), 0, INDEX_FSAL_GetXAttrValue);
  }
  ZFSFSAL_VFS_Unlock();

  /* Copy the string (remove this call by changing the libzfswrap API) */
  strncpy(buffer_addr, psz_value, buffer_size);
  buffer_addr[buffer_size - 1] = '\0';
  *p_output_size = strlen(psz_value);
  free(psz_value);

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue);

}
Пример #17
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 GPFSFSAL_opendir(fsal_handle_t * p_dir_handle,        /* IN */
                           fsal_op_context_t * p_context,       /* IN */
                           fsal_dir_t * dir_desc,       /* OUT */
                           fsal_attrib_list_t * p_dir_attributes        /* [ IN/OUT ] */
    )
{
  fsal_status_t status;
  fsal_accessflags_t access_mask = 0;
  fsal_attrib_list_t dir_attrs;
  gpfsfsal_dir_t *p_dir_descriptor = (gpfsfsal_dir_t *)dir_desc;

  /* 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 */
  TakeTokenFSCall();
  status =
      fsal_internal_handle2fd(p_context, p_dir_handle,
			      &p_dir_descriptor->fd,
                              O_RDONLY | O_DIRECTORY);
  ReleaseTokenFSCall();

  if(FSAL_IS_ERROR(status))
    ReturnStatus(status, INDEX_FSAL_opendir);

  /* get directory metadata */
  dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES;
  status = GPFSFSAL_getattrs(p_dir_handle, p_context, &dir_attrs);
  if(FSAL_IS_ERROR(status))
    ReturnStatus(status, INDEX_FSAL_opendir);

  /* Test access rights for this directory */

  /* Set both mode and ace4 mask */
  access_mask = FSAL_MODE_MASK_SET(FSAL_R_OK) |
                FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_LIST_DIR);

  status = fsal_internal_testAccess(p_context, access_mask, NULL, &dir_attrs);
  if(FSAL_IS_ERROR(status))
    ReturnStatus(status, INDEX_FSAL_opendir);

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

  memcpy(&(p_dir_descriptor->context), p_context, sizeof(fsal_op_context_t));
  memcpy(&(p_dir_descriptor->handle), p_dir_handle, sizeof(fsal_handle_t));

  if(p_dir_attributes)
      *p_dir_attributes = dir_attrs;

  p_dir_descriptor->dir_offset = 0;

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_opendir);

}
Пример #18
0
fsal_status_t SNMPFSAL_readlink(snmpfsal_handle_t * linkhandle, /* IN */
                                snmpfsal_op_context_t * p_context,      /* IN */
                                fsal_path_t * p_link_content,   /* OUT */
                                fsal_attrib_list_t * link_attributes    /* [ IN/OUT ] */
    )
{

  int rc;
  fsal_status_t st;
  char link_content_out[FSAL_MAX_PATH_LEN];

  /* sanity checks.
   * note : link_attributes is optional.
   */
  if(!linkhandle || !p_context || !p_link_content)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink);

  TakeTokenFSCall();

  /* >> call your filesystem readlink function << */

  ReleaseTokenFSCall();

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

  /* >> convert fs output to fsal_path_t
   * for example, if this is a char * (link_content_out) :
   */

  st = FSAL_str2path(link_content_out, FSAL_MAX_PATH_LEN, p_link_content);

  if(FSAL_IS_ERROR(st))
    Return(st.major, st.minor, INDEX_FSAL_readlink);

  /* retrieves object attributes, if asked */

  if(link_attributes)
    {

      fsal_status_t status;

      status = SNMPFSAL_getattrs(linkhandle, 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);
        }

    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink);

}
Пример #19
0
fsal_status_t FUSEFSAL_truncate(fsal_handle_t *handle, /* IN */
                                fsal_op_context_t * p_context,      /* IN */
                                fsal_size_t length,     /* IN */
                                fsal_file_t * file_descriptor,      /* Unused in this FSAL */
                                fsal_attrib_list_t * object_attributes  /* [ IN/OUT ] */
    )
{

  int rc;
  char object_path[FSAL_MAX_PATH_LEN];
  fusefsal_handle_t * filehandle = (fusefsal_handle_t *)handle;

  /* sanity checks.
   * note : object_attributes is optional.
   */
  if(!filehandle || !p_context)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_truncate);

  if(!p_fs_ops->truncate)
    Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_truncate);

  /* get the full path for the object */
  rc = NamespacePath(filehandle->data.inode, filehandle->data.device, filehandle->data.validator,
                     object_path);
  if(rc)
    Return(ERR_FSAL_STALE, rc, INDEX_FSAL_truncate);

  /* set context for the next operation, so it can be retrieved by FS thread */
  fsal_set_thread_context(p_context);

  TakeTokenFSCall();
  rc = p_fs_ops->truncate(object_path, (off_t) length);
  ReleaseTokenFSCall();

  if(rc)
    Return(fuse2fsal_error(rc, TRUE), rc, INDEX_FSAL_truncate);

  if(object_attributes)
    {

      fsal_status_t st;

      st = FUSEFSAL_getattrs(handle, p_context, object_attributes);

      if(FSAL_IS_ERROR(st))
        {
          FSAL_CLEAR_MASK(object_attributes->asked_attributes);
          FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
        }

    }

  /* No error occured */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_truncate);

}
Пример #20
0
fsal_status_t ZFSFSAL_readlink(zfsfsal_handle_t * linkhandle, /* IN */
                            zfsfsal_op_context_t * p_context,      /* IN */
                            fsal_path_t * p_link_content,       /* OUT */
                            fsal_attrib_list_t * link_attributes        /* [ IN/OUT ] */
    )
{

  int rc;
  fsal_status_t st;
  char link_content_out[FSAL_MAX_PATH_LEN];

  /* sanity checks.
   * note : link_attributes is optional.
   */
  if(!linkhandle || !p_context || !p_link_content)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_readlink);

  TakeTokenFSCall();

  rc = libzfswrap_readlink(p_context->export_context->p_vfs, &p_context->user_credential.cred,
                           linkhandle->data.zfs_handle, link_content_out, sizeof(link_content_out));

  ReleaseTokenFSCall();

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

  /* >> convert fs output to fsal_path_t
   * for example, if this is a char * (link_content_out) :
   */

  st = FSAL_str2path(link_content_out, FSAL_MAX_PATH_LEN, p_link_content);

  if(FSAL_IS_ERROR(st))
    Return(st.major, st.minor, INDEX_FSAL_readlink);

  /* retrieves object attributes, if asked */

  if(link_attributes)
    {

      fsal_status_t status;

      status = ZFSFSAL_getattrs(linkhandle, 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);
        }

    }
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_readlink);

}
Пример #21
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);
}
Пример #22
0
/**
 * FSAL_getetxattrs:
 * Get attributes for the object specified by its filehandle.
 *
 * \param filehandle (input):
 *        The handle of the object to get parameters.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param object_attributes (mandatory input/output):
 *        The retrieved attributes for the 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).
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t XFSFSAL_getextattrs(xfsfsal_handle_t * p_filehandle, /* IN */
                                  xfsfsal_op_context_t * p_context,        /* IN */
                                  fsal_extattrib_list_t * p_object_attributes /* OUT */
    )
{
  fsal_status_t st ;
  xfs_bstat_t bstat;
  xfs_ino_t xfs_ino;
  struct stat buffstat;
  int fd = 0 ;

  /* sanity checks.
   * note : object_attributes is mandatory in FSAL_getattrs.
   */
  if(!p_filehandle || !p_context || !p_object_attributes)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs);

  TakeTokenFSCall();
  st = fsal_internal_handle2fd(p_context, p_filehandle, &fd, O_RDONLY);
  ReleaseTokenFSCall();

  if(FSAL_IS_ERROR(st))
    ReturnStatus(st, INDEX_FSAL_getextattrs);

  if( p_object_attributes->asked_attributes & FSAL_ATTR_GENERATION )
   {
     /* get file metadata */
     xfs_ino = p_filehandle->data.inode ;
     TakeTokenFSCall();
     if(fsal_internal_get_bulkstat_by_inode(fd, &xfs_ino, &bstat) < 0)
      {
        close(fd);
        ReleaseTokenFSCall();
        ReturnCode(posix2fsal_error(errno), errno);
      }
     ReleaseTokenFSCall();

     p_object_attributes->generation = bstat.bs_gen ;
    }
 
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_getextattrs);
} /* XFSFSAL_getextattrs */
Пример #23
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, export...).
 * \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 (optionnal input/output): 
 *        The postop 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).
 *        Can be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - ERR_FSAL_STALE        (parent_directory_handle does not address an existing object)
 *        - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *        - Other error codes can be returned :
 *          ERR_FSAL_ACCESS, ERR_FSAL_EXIST, ERR_FSAL_IO, ...
 *            
 *        NB: if getting postop attributes failed,
 *        the function does not return an error
 *        but the FSAL_ATTR_RDATTR_ERR bit is set in
 *        the object_attributes->asked_attributes field.
 */
fsal_status_t ZFSFSAL_create(zfsfsal_handle_t * parent_directory_handle,      /* IN */
                             fsal_name_t * p_filename,     /* IN */
                             zfsfsal_op_context_t * p_context,        /* IN */
                             fsal_accessmode_t accessmode, /* IN */
                             zfsfsal_handle_t * object_handle,        /* OUT */
                             fsal_attrib_list_t * object_attributes        /* [ IN/OUT ] */
    )
{

  int rc;

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

  /* >> convert fsal args to your fs args.
   * Don't forget applying FSAL umask :
   * mode = mode & ~global_fs_info.umask << */

  TakeTokenFSCall();

  inogen_t object;
  rc = libzfswrap_create(p_context->export_context->p_vfs, &p_context->user_credential.cred,
                         parent_directory_handle->data.zfs_handle, p_filename->name,
                         fsal2unix_mode(accessmode), &object);

  ReleaseTokenFSCall();

  /* >> interpret returned error << */
  if(rc)
    Return(posix2fsal_error(rc), 0, INDEX_FSAL_create);

  /* >> set output handle << */
  object_handle->data.zfs_handle = object;
  object_handle->data.type = FSAL_TYPE_FILE;

  if(object_attributes)
    {
      fsal_status_t status = ZFSFSAL_getattrs(object_handle, p_context, object_attributes);

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

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

}
Пример #24
0
/**
 * FSAL_link:
 * Create a hardlink.
 *
 * \param exttarget (input):
 *        Handle of the target object.
 * \param extdir (input):
 *        Pointer to the directory handle where
 *        the hardlink is to be created.
 * \param link_name (input):
 *        Pointer to the name of the hardlink to be created.
 * \param extcontext (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)
 *        - ERR_FSAL_STALE        (target or dir does not address an existing object)
 *        - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *        - Other error codes can be returned :
 *          ERR_FSAL_ACCESS, ERR_FSAL_EXIST, ERR_FSAL_IO, ...
 *
 *        NB: if getting postop attributes failed,
 *        the function does not return an error
 *        but the FSAL_ATTR_RDATTR_ERR bit is set in
 *        the attributes->asked_attributes field.
 */
fsal_status_t CEPHFSAL_link(fsal_handle_t * exttarget,
                            fsal_handle_t * extdir,
                            fsal_name_t * link_name,
                            fsal_op_context_t * extcontext,
                            fsal_attrib_list_t * attributes)
{
  int rc;
  struct stat st;
  char strname[FSAL_MAX_NAME_LEN];
  cephfsal_handle_t* target = (cephfsal_handle_t*) exttarget;
  cephfsal_handle_t* dir = (cephfsal_handle_t*) extdir;
  cephfsal_op_context_t* context = (cephfsal_op_context_t*) context;
  struct ceph_mount_info *cmount = context->export_context->cmount;
  int uid = FSAL_OP_CONTEXT_TO_UID(context);
  int gid = FSAL_OP_CONTEXT_TO_GID(context);

  /* sanity checks.
   * note : attributes is optional.
   */
  if(!target || !dir || !context || !link_name)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_link);

  memset(target, 0, sizeof(cephfsal_handle_t));

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

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

  FSAL_name2str(link_name, strname, FSAL_MAX_NAME_LEN);

  TakeTokenFSCall();
  rc = ceph_ll_link(cmount, VINODE(target), VINODE(dir), strname, &st,
                    uid, gid);
  ReleaseTokenFSCall();

  if (rc < 0)
    Return(posix2fsal_error(rc), 0, INDEX_FSAL_link);

  if(attributes)
    {
      fsal_status_t status;
      status = posix2fsal_attributes(&st, attributes);
      if(FSAL_IS_ERROR(status))
        {
          FSAL_CLEAR_MASK(attributes->asked_attributes);
          FSAL_SET_MASK(attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
          Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_link);
        }
    }

  /* OK */
  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_link);
}
Пример #25
0
/**
 * GPFSFSAL_getattrs:
 * Get attributes for the object specified by its filehandle.
 *
 * \param filehandle (input):
 *        The handle of the object to get parameters.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param object_attributes (mandatory input/output):
 *        The retrieved attributes for the 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).
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t GPFSFSAL_getattrs(fsal_handle_t * p_filehandle,       /* IN */
                            fsal_op_context_t * p_context,      /* IN */
                            fsal_attrib_list_t * p_object_attributes    /* IN/OUT */
    )
{
  fsal_status_t st;
  gpfsfsal_xstat_t buffxstat;

#ifdef _USE_NFS4_ACL
  fsal_accessflags_t access_mask = 0;
#endif

  /* sanity checks.
   * note : object_attributes is mandatory in GPFSFSAL_getattrs.
   */
  if(!p_filehandle || !p_context || !p_object_attributes)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs);

  TakeTokenFSCall();
  st = fsal_get_xstat_by_handle(p_context,
                           p_filehandle,
                                &buffxstat);
  ReleaseTokenFSCall();

  if(FSAL_IS_ERROR(st))
    ReturnStatus(st, INDEX_FSAL_getattrs);

  /* convert attributes */
  st = gpfsfsal_xstat_2_fsal_attributes(&buffxstat, p_object_attributes);
  if(FSAL_IS_ERROR(st))
    {
      FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
      FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
      ReturnStatus(st, INDEX_FSAL_getattrs);
    }

#ifdef _USE_NFS4_ACL
  if(p_object_attributes->acl)
    {
      /* Check permission to get attributes and ACL. */
      access_mask = FSAL_MODE_MASK_SET(0) |  /* Dummy */
                    FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_READ_ATTR |
                                       FSAL_ACE_PERM_READ_ACL);
    
      st = fsal_internal_testAccess(p_context, access_mask, NULL, p_object_attributes);
      if(FSAL_IS_ERROR(st))
        ReturnStatus(st, INDEX_FSAL_getattrs);
    }
#endif

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_getattrs);

}
Пример #26
0
/**
 * FSAL_read:
 * Perform a read operation on an opened file.
 *
 * \param file_descriptor (input):
 *        The file descriptor returned by FSAL_open.
 * \param seek_descriptor (optional input):
 *        Specifies the position where data is to be read.
 *        If not specified, data will be read at the current position.
 * \param buffer_size (input):
 *        Amount (in bytes) of data to be read.
 * \param buffer (output):
 *        Address where the read data is to be stored in memory.
 * \param read_amount (output):
 *        Pointer to the amount of data (in bytes) that have been read
 *        during this call.
 * \param end_of_file (output):
 *        Pointer to a boolean that indicates whether the end of file
 *        has been reached during this call.
 *
 * \return Major error codes:
 *      - ERR_FSAL_NO_ERROR     (no error)
 *      - ERR_FSAL_INVAL        (invalid parameter)
 *      - ERR_FSAL_NOT_OPENED   (tried to read in a non-opened zfsfsal_file_t)
 *      - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *      - Other error codes can be returned :
 *        ERR_FSAL_IO, ...
 */
fsal_status_t ZFSFSAL_read(zfsfsal_file_t * file_descriptor,  /* IN */
                        fsal_seek_t * seek_descriptor,  /* [IN] */
                        fsal_size_t buffer_size,        /* IN */
                        caddr_t buffer, /* OUT */
                        fsal_size_t * read_amount,      /* OUT */
                        fsal_boolean_t * end_of_file    /* OUT */
    )
{
  off_t offset = 0;
  int rc;
  int behind = 0;

  /* sanity checks. */

  if(!file_descriptor || !buffer || !read_amount || !end_of_file)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_read);

  TakeTokenFSCall();

  if(seek_descriptor)
  {
    switch(seek_descriptor->whence)
    {
    case FSAL_SEEK_CUR:
      offset = file_descriptor->current_offset + seek_descriptor->offset;
      break;
    case FSAL_SEEK_SET:
      offset = seek_descriptor->offset;
      break;
    case FSAL_SEEK_END:
      behind = 1;
      offset = seek_descriptor->offset;
      break;
    }
  }

  rc = libzfswrap_read(file_descriptor->p_vfs, &file_descriptor->cred, file_descriptor->p_vnode, buffer, buffer_size, behind, offset);

  ReleaseTokenFSCall();

  /* >> interpreted returned status << */
  if(!rc)
    *end_of_file = 1;

  /* >> dont forget setting output vars : read_amount, end_of_file << */
  *read_amount = buffer_size;

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_read);

}
Пример #27
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)
 *        - ERR_FSAL_STALE        (target_handle or dir_handle does not address an existing object)
 *        - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *        - Other error codes can be returned :
 *          ERR_FSAL_ACCESS, ERR_FSAL_EXIST, ERR_FSAL_IO, ...
 *            
 *        NB: if getting postop attributes failed,
 *        the function does not return an error
 *        but the FSAL_ATTR_RDATTR_ERR bit is set in
 *        the attributes->asked_attributes field.
 */
fsal_status_t ZFSFSAL_link(zfsfsal_handle_t * target_handle,  /* IN */
                           zfsfsal_handle_t * dir_handle,     /* IN */
                           fsal_name_t * p_link_name,      /* IN */
                           zfsfsal_op_context_t * p_context,  /* IN */
                           fsal_attrib_list_t * attributes /* [ IN/OUT ] */
    )
{

  int rc;

  /* sanity checks.
   * note : attributes is optional.
   */
  if(!target_handle || !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);

  TakeTokenFSCall();

  rc = libzfswrap_link(p_context->export_context->p_vfs, &p_context->user_credential.cred,
                       dir_handle->data.zfs_handle, target_handle->data.zfs_handle, p_link_name->name);

  ReleaseTokenFSCall();

  /* >> interpret returned error << */
  if(rc)
    Return(posix2fsal_error(rc), 0, INDEX_FSAL_link);

  if(attributes)
    {
      fsal_status_t status = ZFSFSAL_getattrs(target_handle, p_context, attributes);

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

    }

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

}
Пример #28
0
/**
 * FSAL_write:
 * Perform a write operation on an opened file.
 *
 * \param file_descriptor (input):
 *        The file descriptor returned by FSAL_open.
 * \param seek_descriptor (optional input):
 *        Specifies the position where data is to be written.
 *        If not specified, data will be written at the current position.
 * \param buffer_size (input):
 *        Amount (in bytes) of data to be written.
 * \param buffer (input):
 *        Address in memory of the data to write to file.
 * \param write_amount (output):
 *        Pointer to the amount of data (in bytes) that have been written
 *        during this call.
 *
 * \return Major error codes:
 *      - ERR_FSAL_NO_ERROR     (no error)
 *      - ERR_FSAL_INVAL        (invalid parameter)
 *      - ERR_FSAL_NOT_OPENED   (tried to write in a non-opened zfsfsal_file_t)
 *      - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *      - Other error codes can be returned :
 *        ERR_FSAL_IO, ERR_FSAL_NOSPC, ERR_FSAL_DQUOT...
 */
fsal_status_t ZFSFSAL_write(zfsfsal_file_t * file_descriptor, /* IN */
                         fsal_seek_t * seek_descriptor, /* IN */
                         fsal_size_t buffer_size,       /* IN */
                         caddr_t buffer,        /* IN */
                         fsal_size_t * write_amount     /* OUT */
    )
{
  int rc, behind = 0;
  off_t offset;

  /* sanity checks. */
  if(!file_descriptor || !buffer || !write_amount)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_write);

  TakeTokenFSCall();

  if(seek_descriptor)
  {
    switch(seek_descriptor->whence)
    {
    case FSAL_SEEK_CUR:
      offset = file_descriptor->current_offset + seek_descriptor->offset;
      break;
    case FSAL_SEEK_SET:
      offset = seek_descriptor->offset;
      break;
    case FSAL_SEEK_END:
      behind = 1;
      offset = seek_descriptor->offset;
      break;
    }
  }

  rc = libzfswrap_write(file_descriptor->p_vfs, &file_descriptor->cred, file_descriptor->p_vnode, buffer, buffer_size, behind, offset);


  ReleaseTokenFSCall();

  /* >> interpreted returned status << */
  if(rc)
    Return(posix2fsal_error(rc), 0, INDEX_FSAL_write);

  /* >> dont forget setting output vars : write_amount << */
  *write_amount = buffer_size;

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_write);

}
Пример #29
0
/**
 * FSAL_opendir :
 *     Opens a directory for reading its content.
 *
 * \param exthandle (input)
 *         the handle of the directory to be opened.
 * \param extcontext (input)
 *         Permission context for the operation (user, export context...).
 * \param extdescriptor (output)
 *         pointer to an allocated structure that will receive
 *         directory stream informations, on successfull completion.
 * \param attributes (optional output)
 *         On successfull completion,the structure pointed
 *         by dir_attributes receives the new directory attributes.
 *         Can be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - ERR_FSAL_ACCESS       (user does not have read permission on directory)
 *        - ERR_FSAL_STALE        (exthandle does not address an existing object)
 *        - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *        - Other error codes can be returned :
 *          ERR_FSAL_IO, ...
 */
fsal_status_t CEPHFSAL_opendir(fsal_handle_t * exthandle,
                               fsal_op_context_t * extcontext,
                               fsal_dir_t * extdescriptor,
                               fsal_attrib_list_t * dir_attributes)
{
  cephfsal_handle_t* handle = (cephfsal_handle_t*) exthandle;
  cephfsal_op_context_t* context = (cephfsal_op_context_t*) extcontext;
  cephfsal_dir_t* descriptor = (cephfsal_dir_t*) extdescriptor;
  fsal_status_t status;
  int rc;
  int uid = FSAL_OP_CONTEXT_TO_UID(context);
  int gid = FSAL_OP_CONTEXT_TO_GID(context);
  struct ceph_dir_result *dh;

  /* sanity checks
   * note : dir_attributes is optional.
   */
  if(!handle || !context || !descriptor)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_opendir);

  TakeTokenFSCall();
  /* XXX ceph_ll_opendir has void in the interface, but Client::ll_opendir
   * is using dir_result_t. */
  rc = ceph_ll_opendir(context->export_context->cmount, VINODE(handle),
                       (void *) &dh, uid, gid);
  ReleaseTokenFSCall();

  if (rc < 0)
    Return(posix2fsal_error(rc), 0, INDEX_FSAL_opendir);

  descriptor->dh = dh;
  descriptor->vi = VINODE(handle);
  descriptor->ctx = *context;

  if(dir_attributes)
    {
      status = CEPHFSAL_getattrs(exthandle, extcontext, dir_attributes);

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

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_opendir);
}
Пример #30
0
/**
 * FSAL_getattrs:
 * Get attributes for the object specified by its filehandle.
 *
 * \param filehandle (input):
 *        The handle of the object to get parameters.
 * \param cred (input):
 *        Authentication context for the operation (user,...).
 * \param object_attributes (mandatory input/output):
 *        The retrieved attributes for the 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).
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t LUSTREFSAL_getattrs(fsal_handle_t * p_filehandle,   /* IN */
                                  fsal_op_context_t * p_context,  /* IN */
                                  fsal_attrib_list_t * p_object_attributes      /* IN/OUT */
    )
{
  int rc;
  fsal_status_t st;
  fsal_path_t fsalpath;
  struct stat buffstat;

  /* sanity checks.
   * note : object_attributes is mandatory in FSAL_getattrs.
   */
  if(!p_filehandle || !p_context || !p_object_attributes)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs);

  /* get the path of the file */
  st = fsal_internal_Handle2FidPath(p_context, p_filehandle, &fsalpath);
  if(FSAL_IS_ERROR(st))
    ReturnStatus(st, INDEX_FSAL_getattrs);

  /* get file metadata */
  TakeTokenFSCall();
  rc = lstat(fsalpath.path, &buffstat);
  ReleaseTokenFSCall();

  if(rc != 0)
    {
      rc = errno;
      if(rc == ENOENT)
        Return(ERR_FSAL_STALE, rc, INDEX_FSAL_getattrs);
      else
        Return(posix2fsal_error(rc), rc, INDEX_FSAL_getattrs);
    }

  /* convert attributes */
  st = posix2fsal_attributes(&buffstat, p_object_attributes);
  if(FSAL_IS_ERROR(st))
    {
      FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
      FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
      ReturnStatus(st, INDEX_FSAL_getattrs);
    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_getattrs);

}