コード例 #1
0
ファイル: xattrs.c プロジェクト: hongjil5/nfs-ganesha
fsal_status_t tank_getextattr_value_by_id(struct fsal_obj_handle *obj_hdl,
					  unsigned int xattr_id,
					  caddr_t buffer_addr,
					  size_t buffer_size,
					  size_t *p_output_size)
{
	struct zfs_fsal_obj_handle *obj_handle = NULL;
	int retval = -1;
	creden_t cred;

	obj_handle =
	    container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle);

	/* sanity checks */
	if (!obj_hdl || !p_output_size || !buffer_addr)
		return fsalstat(ERR_FSAL_FAULT, 0);

	cred.uid = op_ctx->creds->caller_uid;
	cred.gid = op_ctx->creds->caller_gid;

	/* check that this index match the type of entry */
	if ((xattr_id < XATTR_COUNT)
	    && !do_match_type(xattr_list[xattr_id].flags, obj_hdl->type)) {
		return fsalstat(ERR_FSAL_INVAL, 0);
	} else if (xattr_id >= XATTR_COUNT) {
		char attr_name[MAXPATHLEN];

		/* get the name for this attr */
		retval = xattr_id_to_name(ZFSFSAL_GetVFS(obj_handle->handle),
					  &cred,
					  obj_handle->handle->zfs_handle,
					  xattr_id,
					  attr_name);
		if (retval)
			return fsalstat(retval, 0);
		retval = libzfswrap_getxattr(ZFSFSAL_GetVFS(obj_handle->handle),
					     &cred,
					     obj_handle->handle->zfs_handle,
					     attr_name, &buffer_addr);
		if (retval)
			return fsalstat(posix2fsal_error(retval), retval);

		/* the xattr value can be a binary, or a string.
		 * trying to determine its type...
		 */
		*p_output_size = strnlen(buffer_addr, buffer_size);
		xattr_format_value(buffer_addr, p_output_size, buffer_size);

		return fsalstat(ERR_FSAL_NO_ERROR, 0);
	} else {		/* built-in attr */

		/* get the value */
		retval = xattr_list[xattr_id].get_func(obj_hdl, buffer_addr,
						       buffer_size,
						       p_output_size,
						       xattr_list[xattr_id]
						       .arg);
		return fsalstat(retval, 0);
	}
}
コード例 #2
0
ファイル: xattrs.c プロジェクト: JevonQ/nfs-ganesha
fsal_status_t tank_remove_extattr_by_id(struct fsal_obj_handle *obj_hdl,
					unsigned int xattr_id)
{
	char name[MAXNAMLEN];
	struct zfs_fsal_obj_handle *obj_handle = NULL;
	int retval = 0;
	creden_t cred;

	obj_handle =
	    container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle);

	cred.uid = op_ctx->creds->caller_uid;
	cred.gid = op_ctx->creds->caller_gid;

	retval = xattr_id_to_name(ZFSFSAL_GetVFS(obj_handle->handle),
				  &cred,
				  obj_handle->handle->zfs_handle,
				  xattr_id, name);
	if (retval)
		return fsalstat(retval, 0);
	retval = libzfswrap_removexattr(ZFSFSAL_GetVFS(obj_handle->handle),
					&cred,
					obj_handle->handle->zfs_handle,
					name);
	if (retval != 0)
		return fsalstat(posix2fsal_error(retval), retval);

	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
コード例 #3
0
ファイル: xattrs.c プロジェクト: JevonQ/nfs-ganesha
fsal_status_t tank_setextattr_value_by_id(struct fsal_obj_handle *obj_hdl,
					  unsigned int xattr_id,
					  caddr_t buffer_addr,
					  size_t buffer_size)
{
	char name[MAXNAMLEN];
	struct zfs_fsal_obj_handle *obj_handle = NULL;
	int retval = -1;
	creden_t cred;

	obj_handle =
	    container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle);

	if (attr_is_read_only(xattr_id))
		return fsalstat(ERR_FSAL_PERM, 0);
	else if (xattr_id < XATTR_COUNT)
		return fsalstat(ERR_FSAL_PERM, 0);

	cred.uid = op_ctx->creds->caller_uid;
	cred.gid = op_ctx->creds->caller_gid;

	retval =
	    xattr_id_to_name(ZFSFSAL_GetVFS(obj_handle->handle), &cred,
			     obj_handle->handle->zfs_handle, xattr_id, name);
	if (retval)
		return fsalstat(retval, 0);

	return tank_setextattr_value(obj_hdl, name, buffer_addr,
				     buffer_size, false);
}
コード例 #4
0
ファイル: xattrs.c プロジェクト: JevonQ/nfs-ganesha
fsal_status_t tank_setextattr_value(struct fsal_obj_handle *obj_hdl,
				    const char *xattr_name, caddr_t buffer_addr,
				    size_t buffer_size, int create)
{
	struct zfs_fsal_obj_handle *obj_handle = NULL;
	int rc = 0;
	creden_t cred;

	obj_handle =
	    container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle);

	/* remove final '\n', if any */
	chomp_attr_value((char *)buffer_addr, buffer_size);

	cred.uid = op_ctx->creds->caller_uid;
	cred.gid = op_ctx->creds->caller_gid;

	rc = libzfswrap_setxattr(ZFSFSAL_GetVFS(obj_handle->handle), &cred,
				 obj_handle->handle->zfs_handle, xattr_name,
				 buffer_addr);

	if (rc != 0)
		return fsalstat(posix2fsal_error(rc), rc);
	else
		return fsalstat(ERR_FSAL_NO_ERROR, 0);

}
コード例 #5
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);

}
コード例 #6
0
/**
 * Get the index of an xattr based on 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 pxattr_id found xattr_id
 *   
 *   \return ERR_FSAL_NO_ERROR if xattr_name exists, ERR_FSAL_NOENT otherwise
 */
fsal_status_t ZFSFSAL_GetXAttrIdByName(fsal_handle_t * obj_handle,     /* IN */
                                    const fsal_name_t * xattr_name,     /* IN */
                                    fsal_op_context_t * context,      /* IN */
                                    unsigned int *pxattr_id     /* OUT */
    )
{
  unsigned int index;
  int rc;
  int found = FALSE;
  zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle;
  zfsfsal_op_context_t *p_context = (zfsfsal_op_context_t *)context;

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

  for(index = 0; index < XATTR_COUNT; index++)
    {
      if(!strcmp(xattr_list[index].xattr_name, xattr_name->name))
        {
          found = TRUE;
          break;
        }
    }

  if(!found)
  {

    /* Get the right VFS */
    ZFSFSAL_VFS_RDLock();
    libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle);
    if(!p_vfs)
    {
      ZFSFSAL_VFS_Unlock();
      Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_access);
    }

    if((rc = xattr_name_to_id(p_vfs, p_context, p_objecthandle, xattr_name->name, &index)))
    {
      ZFSFSAL_VFS_Unlock();
      Return(rc, 0, INDEX_FSAL_GetXAttrValue);
    }
    found = TRUE;
  }

  if(found)
  {
    *pxattr_id = index;
    Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_GetXAttrValue);
  }
  else
    Return(ERR_FSAL_NOENT, ENOENT, INDEX_FSAL_GetXAttrValue);
}
コード例 #7
0
ファイル: xattrs.c プロジェクト: JevonQ/nfs-ganesha
fsal_status_t tank_getextattr_value_by_name(struct fsal_obj_handle *obj_hdl,
					    const char *xattr_name,
					    caddr_t buffer_addr,
					    size_t buffer_size,
					    size_t *p_output_size)
{
	struct zfs_fsal_obj_handle *obj_handle = NULL;
	unsigned int index;
	creden_t cred;
	int retval = 0;

	obj_handle =
	    container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle);

	/* sanity checks */
	if (!obj_hdl || !p_output_size || !buffer_addr || !xattr_name)
		return fsalstat(ERR_FSAL_FAULT, 0);

	cred.uid = op_ctx->creds->caller_uid;
	cred.gid = op_ctx->creds->caller_gid;

	/* look for this name */
	for (index = 0; index < XATTR_COUNT; index++) {
		if (do_match_type(xattr_list[index].flags,
				  obj_hdl->attributes.type)
		    && !strcmp(xattr_list[index].xattr_name,
			       xattr_name)) {
			return tank_getextattr_value_by_id(obj_hdl,
							   index, buffer_addr,
							   buffer_size,
							   p_output_size);
		}
	}

	/* is it an xattr? */
	retval = libzfswrap_getxattr(ZFSFSAL_GetVFS(obj_handle->handle),
				     &cred,
				     obj_handle->handle->zfs_handle,
				     xattr_name,
				     &buffer_addr);
	if (retval)
		return fsalstat(posix2fsal_error(retval), retval);
	/* the xattr value can be a binary, or a string.
	 * trying to determine its type...
	 */
	*p_output_size = strnlen(buffer_addr, buffer_size);
	xattr_format_value(buffer_addr, p_output_size, buffer_size);

	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
コード例 #8
0
ファイル: xattrs.c プロジェクト: JevonQ/nfs-ganesha
fsal_status_t tank_getextattr_id_by_name(struct fsal_obj_handle *obj_hdl,
					 const char *xattr_name,
					 unsigned int *pxattr_id)
{
	unsigned int index;
	int rc;
	bool found = false;
	struct zfs_fsal_obj_handle *obj_handle = NULL;
	creden_t cred;

	/* sanity checks */
	if (!obj_hdl || !xattr_name)
		return fsalstat(ERR_FSAL_FAULT, 0);

	obj_handle =
	    container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle);

	cred.uid = op_ctx->creds->caller_uid;
	cred.gid = op_ctx->creds->caller_gid;

	for (index = 0; index < XATTR_COUNT; index++) {
		if (!strcmp(xattr_list[index].xattr_name, xattr_name)) {
			found = true;
			break;
		}
	}

	/* search in xattrs */
	if (!found) {
		rc = xattr_name_to_id(ZFSFSAL_GetVFS(obj_handle->handle), &cred,
				      obj_handle->handle->zfs_handle,
				      (char *)xattr_name);
		if (rc)
			return fsalstat(posix2fsal_error(rc), rc);
		else {
			index = rc;
			found = true;
		}
	}
	*pxattr_id = index;
	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
コード例 #9
0
ファイル: xattrs.c プロジェクト: JevonQ/nfs-ganesha
fsal_status_t tank_remove_extattr_by_name(struct fsal_obj_handle *obj_hdl,
					  const char *xattr_name)
{
	struct zfs_fsal_obj_handle *obj_handle = NULL;
	int retval = 0;
	creden_t cred;

	obj_handle =
	    container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle);

	cred.uid = op_ctx->creds->caller_uid;
	cred.gid = op_ctx->creds->caller_gid;

	retval = libzfswrap_removexattr(ZFSFSAL_GetVFS(obj_handle->handle),
					&cred,
					obj_handle->handle->zfs_handle,
					xattr_name);
	if (retval != 0)
		return fsalstat(posix2fsal_error(retval), retval);
	return fsalstat(ERR_FSAL_NO_ERROR, 0);

}
コード例 #10
0
fsal_status_t ZFSFSAL_close(fsal_file_t * file_desc  /* IN */
    )
{
  int rc = 0;
  zfsfsal_file_t * file_descriptor = (zfsfsal_file_t *)file_desc;

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

  TakeTokenFSCall();

  if(!file_descriptor->is_closed)
  {
    /* Test that the vfs still exist */
    ZFSFSAL_VFS_RDLock();
    libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(&file_descriptor->handle);
    if(!p_vfs)
    {
      ZFSFSAL_VFS_Unlock();
      ReleaseTokenFSCall();
      Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_close);
    }

    rc = libzfswrap_close(p_vfs, &file_descriptor->cred, file_descriptor->p_vnode,
                          file_descriptor->flags);
    ZFSFSAL_VFS_Unlock();
    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);

}
コード例 #11
0
ファイル: xattrs.c プロジェクト: JevonQ/nfs-ganesha
fsal_status_t tank_list_ext_attrs(struct fsal_obj_handle *obj_hdl,
				  unsigned int argcookie,
				  fsal_xattrent_t *xattrs_tab,
				  unsigned int xattrs_tabsize,
				  unsigned int *p_nb_returned, int *end_of_list)
{
	unsigned int index;
	unsigned int out_index;
	unsigned int cookie = argcookie;
	struct zfs_fsal_obj_handle *obj_handle = NULL;

	char names[MAXPATHLEN], *ptr;
	size_t namesize;
	int xattr_idx;
	int retval;
	creden_t cred;

	/* sanity checks */
	if (!obj_hdl || !xattrs_tab || !p_nb_returned || !end_of_list)
		return fsalstat(ERR_FSAL_FAULT, 0);

	obj_handle =
	    container_of(obj_hdl, struct zfs_fsal_obj_handle, obj_handle);

	cred.uid = op_ctx->creds->caller_uid;
	cred.gid = op_ctx->creds->caller_gid;

	/* Deal with special cookie */
	if (cookie == XATTR_RW_COOKIE)
		cookie = XATTR_COUNT;

	for (index = cookie, out_index = 0;
	     index < XATTR_COUNT && out_index < xattrs_tabsize; index++) {
		if (do_match_type(xattr_list[index].flags,
				  obj_hdl->attributes.type)) {
			/* fills an xattr entry */
			xattrs_tab[out_index].xattr_id = index;
			strncpy(xattr_list[index].xattr_name,
				xattrs_tab[out_index].xattr_name, MAXNAMLEN);
			xattr_list[index].xattr_name[MAXNAMLEN] = '\0';
			xattrs_tab[out_index].xattr_cookie = index + 1;

			/* set asked attributes (all supported) */
			xattrs_tab[out_index].attributes.mask =
			    obj_hdl->attributes.mask;

			if (file_attributes_to_xattr_attrs(&obj_hdl->attributes,
							   &xattrs_tab
							   [out_index]
							   .attributes,
							   index)) {
				/* set error flag */
				xattrs_tab[out_index].attributes.mask =
				    ATTR_RDATTR_ERR;
			}

			/* next output slot */
			out_index++;
		}
	}

	/* save a call if output array is full */
	if (out_index == xattrs_tabsize) {
		*end_of_list = false;
		*p_nb_returned = out_index;
		return fsalstat(ERR_FSAL_NO_ERROR, 0);
	}

	/* get the path of the file in Lustre */

	/* get xattrs */

	retval = libzfswrap_listxattr(ZFSFSAL_GetVFS(obj_handle->handle),
				      &cred,
				      obj_handle->handle->zfs_handle,
				      (char **)&names, &namesize);
	if (retval)
		return fsalstat(posix2fsal_error(retval), retval);

	if (namesize > 0) {
		size_t len = 0;

		errno = 0;

		for (ptr = names, xattr_idx = 0;
		     (ptr < names + namesize) && (out_index < xattrs_tabsize);
		     xattr_idx++, ptr += len + 1) {
			len = strlen(ptr);
			index = XATTR_COUNT + xattr_idx;

			/* skip if index is before cookie */
			if (index < cookie)
				continue;

			/* fills an xattr entry */
			xattrs_tab[out_index].xattr_id = index;
			strncpy(xattrs_tab[out_index].xattr_name, ptr, len + 1);
			xattrs_tab[out_index].xattr_cookie = index + 1;

			/* set asked attributes (all supported) */
			xattrs_tab[out_index].attributes.mask =
			    obj_hdl->attributes.mask;

			if (file_attributes_to_xattr_attrs
			    (&obj_hdl->attributes,
			     &xattrs_tab[out_index].attributes, index)) {
				/* set error flag */
				xattrs_tab[out_index].attributes.mask =
				    ATTR_RDATTR_ERR;
			}

			/* next output slot */
			out_index++;
		}
		/* all xattrs are in the output array */
		if (ptr >= names + namesize)
			*end_of_list = true;
		else
			*end_of_list = false;
	} else			/* no xattrs */
		*end_of_list = true;

	*p_nb_returned = out_index;

	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
コード例 #12
0
/**
 * Get the value of an extended attribute from its index.
 *
 * \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_GetXAttrValueById(fsal_handle_t * obj_handle,    /* IN */
                                     unsigned int xattr_id,     /* IN */
                                     fsal_op_context_t * context,     /* IN */
                                     caddr_t buffer_addr,       /* IN/OUT */
                                     size_t buffer_size,        /* IN */
                                     size_t * p_output_size     /* OUT */
    )
{
  int rc;
  char buff[MAXNAMLEN];
  zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle;
  zfsfsal_op_context_t *p_context = (zfsfsal_op_context_t *)context;

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

  /* check that this index match the type of entry */
  if(xattr_id < XATTR_COUNT
     && !do_match_type(xattr_list[xattr_id].flags, p_objecthandle->data.type))
  {
    Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_GetXAttrValue);
  }

  /* Get the right VFS */
  ZFSFSAL_VFS_RDLock();
  libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle);
  if(!p_vfs)
  {
    ZFSFSAL_VFS_Unlock();
    Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_GetXAttrValue);
  }

  if(xattr_id >= XATTR_COUNT)
  {
    char psz_attr_name[MAXPATHLEN];
    char *psz_value;
    creden_t cred;

    if((rc = xattr_id_to_name(p_vfs, p_context, p_objecthandle, xattr_id, psz_attr_name)))
    {
      ZFSFSAL_VFS_Unlock();
      Return(rc, errno, INDEX_FSAL_GetXAttrValue);
    }
    cred.uid = p_context->credential.user;
    cred.gid = p_context->credential.group;

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

    /* 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);
  }
  else
  {
    rc = xattr_list[xattr_id].get_func(p_objecthandle, p_context,
                                       buffer_addr, buffer_size,
                                       p_output_size);
    /* Get the value */
    if(xattr_list[xattr_id].print_func == NULL)
      rc = xattr_list[xattr_id].get_func(p_objecthandle, p_context,
                                         buffer_addr, buffer_size, p_output_size);
    else
    {
      rc = xattr_list[xattr_id].get_func(p_objecthandle, p_context,
                                         buff, MAXNAMLEN, p_output_size);
      xattr_list[xattr_id].print_func(buff, MAXNAMLEN, buffer_addr, p_output_size);
    }
  }

  ZFSFSAL_VFS_Unlock();
  Return(rc, 0, INDEX_FSAL_GetXAttrValue);
}
コード例 #13
0
/**
 * Retrieves the list of extended attributes for an object in the filesystem.
 * 
 * \param p_objecthandle Handle of the object we want to get extended attributes.
 * \param cookie index of the next entry to be returned.
 * \param p_context pointer to the current security context.
 * \param xattrs_tab a table for storing extended attributes list to.
 * \param xattrs_tabsize the maximum number of xattr entries that xattrs_tab
 *            can contain.
 * \param p_nb_returned the number of xattr entries actually stored in xattrs_tab.
 * \param end_of_list this boolean indicates that the end of xattrs list has been reached.
 */
fsal_status_t ZFSFSAL_ListXAttrs(fsal_handle_t * obj_handle,   /* IN */
                              unsigned int argcookie,      /* IN */
                              fsal_op_context_t * p_context,    /* IN */
                              fsal_xattrent_t * xattrs_tab,     /* IN/OUT */
                              unsigned int xattrs_tabsize,      /* IN */
                              unsigned int *p_nb_returned,      /* OUT */
                              int *end_of_list  /* OUT */
    )
{
  unsigned int index;
  unsigned int out_index;
  fsal_status_t st;
  fsal_attrib_list_t file_attrs;
  int rc;
  creden_t cred;
  zfsfsal_handle_t *p_objecthandle = (zfsfsal_handle_t *)obj_handle;
  unsigned int cookie = argcookie ;

  /* sanity checks */
  if(!p_objecthandle || !p_context || !xattrs_tab || !p_nb_returned || !end_of_list)
    Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_ListXAttrs);

  /* Deal with special cookie */
  if( argcookie == FSAL_XATTR_RW_COOKIE ) cookie = XATTR_COUNT ;

  /* object attributes we want to retrieve from parent */
  file_attrs.asked_attributes = FSAL_ATTR_MODE | FSAL_ATTR_FILEID | FSAL_ATTR_OWNER
      | FSAL_ATTR_GROUP | FSAL_ATTR_ATIME | FSAL_ATTR_MTIME | FSAL_ATTR_TYPE
      | FSAL_ATTR_CTIME | FSAL_ATTR_CREATION | FSAL_ATTR_CHGTIME | FSAL_ATTR_FSID;

  /* don't retrieve unsuipported attributes */
  file_attrs.asked_attributes &= global_fs_info.supported_attrs;

  st = ZFSFSAL_getattrs(obj_handle, p_context, &file_attrs);

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

  /* Get the right VFS */
  ZFSFSAL_VFS_RDLock();
  libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(p_objecthandle);
  if(!p_vfs)
  {
    ZFSFSAL_VFS_Unlock();
    Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_ListXAttrs);
  }


  for(index = cookie, out_index = 0;
      index < XATTR_COUNT && out_index < xattrs_tabsize; index++)
    {
      if(do_match_type(xattr_list[index].flags, p_objecthandle->data.type))
        {
          /* fills an xattr entry */
          xattrs_tab[out_index].xattr_id = index;
          FSAL_str2name(xattr_list[index].xattr_name, FSAL_MAX_NAME_LEN,
                        &xattrs_tab[out_index].xattr_name);
          xattrs_tab[out_index].xattr_cookie = index + 1;

          /* set asked attributes (all supported) */
          xattrs_tab[out_index].attributes.asked_attributes =
              global_fs_info.supported_attrs;

          if(file_attributes_to_xattr_attrs
             (&file_attrs, &xattrs_tab[out_index].attributes, index))
            {
              /* set error flag */
              xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR;
            }

          /* next output slot */
          out_index++;
        }
    }

  /* Save a call if the output array is full */
  if(out_index == xattrs_tabsize)
  {
    *end_of_list = FALSE;
    *p_nb_returned = out_index;
    ZFSFSAL_VFS_Unlock();
    Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs);
  }

  /* List the extended attributes */
  char *psz_buffer;
  size_t i_size;

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

  TakeTokenFSCall();
  rc = libzfswrap_listxattr(p_vfs, &cred,
                            p_objecthandle->data.zfs_handle, &psz_buffer, &i_size);
  ReleaseTokenFSCall();
  ZFSFSAL_VFS_Unlock();

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

  if(i_size > 0)
  {
    size_t len = 0;
    char *ptr;
    int xattr_idx;

    for(ptr = psz_buffer, xattr_idx = 0;
        (ptr < psz_buffer + i_size) && (out_index < xattrs_tabsize);
        xattr_idx++, ptr += len + 1)
    {
      len = strlen(ptr);
      index = XATTR_COUNT + xattr_idx;

      /* Skip if the index is before the cookie */
      if(index < cookie)
        continue;

      xattrs_tab[out_index].xattr_id = index;
      FSAL_str2name(ptr, len + 1, &xattrs_tab[out_index].xattr_name);
      xattrs_tab[out_index].xattr_cookie = index + 1;

      /* set asked attributes (all supported) */
      xattrs_tab[out_index].attributes.asked_attributes =
                                global_fs_info.supported_attrs;

      if(file_attributes_to_xattr_attrs(&file_attrs,
                                        &xattrs_tab[out_index].attributes,
                                        index))
      {
        /* set error flag */
        xattrs_tab[out_index].attributes.asked_attributes = FSAL_ATTR_RDATTR_ERR;
      }

      /* next output slot */
      out_index++;
    }

    /* Every xattrs are in the output array */
    if(ptr >= psz_buffer + i_size)
      *end_of_list = TRUE;
    else
      *end_of_list = FALSE;
  }
  else
    *end_of_list = TRUE;
  free(psz_buffer);

  *p_nb_returned = out_index;

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_ListXAttrs);

}
コード例 #14
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)
 *      - ERR_FSAL_ACCESS       (user doesn't have the permissions for opening the file)
 *      - ERR_FSAL_STALE        (filehandle does not address an existing object) 
 *      - ERR_FSAL_INVAL        (filehandle does not address a regular file,
 *                               or open flags are conflicting)
 *      - ERR_FSAL_FAULT        (a NULL pointer was passed as mandatory argument)
 *      - Other error codes can be returned :
 *        ERR_FSAL_IO, ...
 */
fsal_status_t ZFSFSAL_open(fsal_handle_t * file_hdl,     /* IN */
                        fsal_op_context_t * p_context,  /* IN */
                        fsal_openflags_t openflags,     /* IN */
                        fsal_file_t * file_desc,  /* OUT */
                        fsal_attrib_list_t * file_attributes    /* [ IN/OUT ] */
    )
{
  int rc;
  creden_t cred;
  zfsfsal_handle_t * filehandle = (zfsfsal_handle_t *)file_hdl;
  zfsfsal_file_t * file_descriptor = ( zfsfsal_file_t *)file_desc;

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

  /* Check if this is a file */
  if(filehandle->data.type != FSAL_TYPE_FILE)
    Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_open);

  /* Get the right VFS */
  ZFSFSAL_VFS_RDLock();
  libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(filehandle);
  if(!p_vfs)
  {
    ZFSFSAL_VFS_Unlock();
    Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_open);
  }

  /* >> convert fsal open flags to your FS open flags
   * Take care of conflicting flags << */
  int posix_flags;
  rc = fsal2posix_openflags(openflags, &posix_flags);
  if(rc)
    Return(rc, 0, INDEX_FSAL_open);
  cred.uid = p_context->credential.user;
  cred.gid = p_context->credential.group;

  TakeTokenFSCall();

  /* >> call your FS open function << */
  libzfswrap_vnode_t *p_vnode;
  rc = libzfswrap_open(p_vfs, &cred,
                       filehandle->data.zfs_handle, posix_flags, &p_vnode);

  ReleaseTokenFSCall();
  ZFSFSAL_VFS_Unlock();

  /* >> interpret returned status << */
  if(rc)
    Return(posix2fsal_error(rc), 0, INDEX_FSAL_open);

  /* >> fill output struct << */
  file_descriptor->flags = posix_flags;
  file_descriptor->current_offset = 0;
  file_descriptor->p_vnode = p_vnode;
  file_descriptor->handle = *filehandle;
  file_descriptor->cred = cred;
  file_descriptor->is_closed = 0;

  if(file_attributes)
  {
      fsal_status_t status = ZFSFSAL_getattrs(file_hdl, p_context, file_attributes);
      /* On error, we set a flag in the returned attributes */
      if(FSAL_IS_ERROR(status))
      {
          FSAL_CLEAR_MASK(file_attributes->asked_attributes);
          FSAL_SET_MASK(file_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
      }
  }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_open);
}
コード例 #15
0
/**
 * FSAL_write:
 * Perform a write operation on an opened file.
 *
 * \param file_descriptor (input):
 *        The file descriptor returned by FSAL_open.
 * \param p_context (input):
 *        Authentication context for the operation (user,...).
 * \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(fsal_file_t * file_desc, /* IN */
                         fsal_op_context_t * p_context,  /* 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;
  zfsfsal_file_t * file_descriptor = (zfsfsal_file_t *)file_desc;

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

  /* Hook to prevent writing into a snapshot */
  if(file_descriptor->handle.data.i_snap != 0)
  {
    LogDebug(COMPONENT_FSAL, "Trying to write to a file inside a snapshot");
    Return(ERR_FSAL_ROFS, 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;
    }
  }
  /* Test that the vfs still exist */
  ZFSFSAL_VFS_RDLock();
  libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(&file_descriptor->handle);
  if(!p_vfs)
  {
    ZFSFSAL_VFS_Unlock();
    ReleaseTokenFSCall();
    Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_write);
  }


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

  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);

}
コード例 #16
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(fsal_file_t * file_desc,  /* 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;
  zfsfsal_file_t * file_descriptor = (zfsfsal_file_t *)file_desc;

  /* 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;
    }
  }

  /* Test that the vfs still exist */
  ZFSFSAL_VFS_RDLock();
  libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(&file_descriptor->handle);
  if(!p_vfs)
  {
    ZFSFSAL_VFS_Unlock();
    ReleaseTokenFSCall();
    Return(ERR_FSAL_NOENT, 0, INDEX_FSAL_read);
  }

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

  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);

}