Exemplo n.º 1
0
/**
 * FSAL_readlink:
 * Read the content of a symbolic link.
 *
 * \param dir_hdl (input):
 *        Handle of the link to be read.
 * \param p_context (input):
 *        Authentication context for the operation (user,...).
 * \param p_link_content (output):
 *        Pointer to an fsal path structure where
 *        the link content is to be stored..
 * \param link_len (input/output):
 *        In pointer to len of content buff.
 .        Out actual len of content.
 * \param link_attributes (optionnal input/output):
 *        The post operation attributes of the symlink link.
 *        As input, it defines the attributes that the caller
 *        wants to retrieve (by positioning flags into this structure)
 *        and the output is built considering this input
 *        (it fills the structure according to the flags it contains).
 *        May be NULL.
 *
 * \return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t PTFSAL_readlink(struct fsal_obj_handle *dir_hdl,	/* IN */
			      const struct req_op_context *p_context,	/* IN */
			      char *p_link_content,	/* OUT */
			      size_t *link_len,	/* IN/OUT */
			      struct attrlist *p_link_attributes)
{				/* IN/OUT */

	fsal_status_t status;
	struct pt_fsal_obj_handle *pt_hdl;
	char link_content_out[PATH_MAX];

	/* sanity checks.
	 * note : link_attributes is optional.
	 */
	if (!dir_hdl || !p_context || !p_link_content)
		return fsalstat(ERR_FSAL_FAULT, 0);

	pt_hdl = container_of(dir_hdl, struct pt_fsal_obj_handle, obj_handle);

	memset(link_content_out, 0, sizeof(link_content_out));

	/* Read the link on the filesystem */
	status = fsal_readlink_by_handle(p_context, p_context->fsal_export,
				pt_hdl->handle, p_link_content, *link_len);

	if (FSAL_IS_ERROR(status))
		return status;

	/* retrieves object attributes, if asked */

	if (p_link_attributes) {

		status = PTFSAL_getattrs(p_context->fsal_export, p_context,
					 pt_hdl->handle, p_link_attributes);

		/* On error, we set a flag in the returned attributes */

		if (FSAL_IS_ERROR(status)) {
			FSAL_CLEAR_MASK(p_link_attributes->mask);
			FSAL_SET_MASK(p_link_attributes->mask, ATTR_RDATTR_ERR);
		}

	}

	return fsalstat(ERR_FSAL_NO_ERROR, 0);

}
Exemplo n.º 2
0
/**
 *  @brief Read the content of a symbolic link.
 *
 *  @param dir_hdl Handle of the link to be read.
 *  @param op_ctx Authentication context for the operation (user,...).
 *  @param link_content Fsal path struct where the link content is to be stored
 *  @param link_len Len of content buff. Out actual len of content.
 *
 *  @return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t
GPFSFSAL_readlink(struct fsal_obj_handle *dir_hdl,
		  const struct req_op_context *op_ctx, char *link_content,
		  size_t link_len)
{
	struct gpfs_fsal_obj_handle *gpfs_hdl;
	struct gpfs_fsal_export *exp = container_of(op_ctx->fsal_export,
					struct gpfs_fsal_export, export);
	int export_fd = exp->export_fd;

	gpfs_hdl =
	    container_of(dir_hdl, struct gpfs_fsal_obj_handle, obj_handle);

	/* Read the link on the filesystem */
	return fsal_readlink_by_handle(export_fd, gpfs_hdl->handle,
				       link_content, link_len);
}
Exemplo n.º 3
0
/**
 *  @brief Read the content of a symbolic link.
 *
 *  @param dir_hdl Handle of the link to be read.
 *  @param op_ctx Authentication context for the operation (user,...).
 *  @param link_content Fsal path struct where the link content is to be stored
 *  @param link_len Len of content buff. Out actual len of content.
 *
 *  @return Major error codes :
 *        - ERR_FSAL_NO_ERROR     (no error)
 *        - Another error code if an error occured.
 */
fsal_status_t
GPFSFSAL_readlink(struct fsal_obj_handle *dir_hdl,
		  const struct req_op_context *op_ctx, char *link_content,
		  size_t *link_len)
{
	struct gpfs_fsal_obj_handle *gpfs_hdl;
	struct gpfs_filesystem *gpfs_fs;

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

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

	/* Read the link on the filesystem */
	return fsal_readlink_by_handle(gpfs_fs->root_fd, gpfs_hdl->handle,
				       link_content, link_len);
}
Exemplo n.º 4
0
/**
 * @brief create GPFS handle
 *
 * @param exp_hdl export handle
 * @param hdl_desc handle description
 * @param handle object handle
 * @return status
 *
 * Does what original FSAL_ExpandHandle did (sort of)
 * returns a ref counted handle to be later used in cache_inode etc.
 * NOTE! you must release this thing when done with it!
 * BEWARE! Thanks to some holes in the *AT syscalls implementation,
 * we cannot get an fd on an AF_UNIX socket, nor reliably on block or
 * character special devices.  Sorry, it just doesn't...
 * we could if we had the handle of the dir it is in, but this method
 * is for getting handles off the wire for cache entries that have LRU'd.
 * Ideas and/or clever hacks are welcome...
 */
fsal_status_t gpfs_create_handle(struct fsal_export *exp_hdl,
				 struct gsh_buffdesc *hdl_desc,
				 struct fsal_obj_handle **handle,
				 struct attrlist *attrs_out)
{
	int retval = 0;
	fsal_status_t status;
	struct gpfs_fsal_obj_handle *hdl;
	struct gpfs_file_handle *fh;
	struct attrlist attrib;
	char *link_content = NULL;
	ssize_t retlink = PATH_MAX - 1;
	char link_buff[PATH_MAX];
	struct fsal_fsid__ fsid;
	struct fsal_filesystem *fs;
	struct gpfs_filesystem *gpfs_fs;

	*handle = NULL;		/* poison it first */
	if ((hdl_desc->len > (sizeof(struct gpfs_file_handle))))
		return fsalstat(ERR_FSAL_FAULT, 0);

	fh = alloca(hdl_desc->len);
	memcpy(fh, hdl_desc->addr, hdl_desc->len); /* struct aligned copy */

	gpfs_extract_fsid(fh, &fsid);

	fs = lookup_fsid(&fsid, GPFS_FSID_TYPE);

	if (fs == NULL) {
		LogInfo(COMPONENT_FSAL,
			"Could not find filesystem for fsid=0x%016"PRIx64
			".0x%016"PRIx64" from handle",
			fsid.major, fsid.minor);
		return fsalstat(ERR_FSAL_STALE, ESTALE);
	}

	if (fs->fsal != exp_hdl->fsal) {
		LogInfo(COMPONENT_FSAL,
			"Non GPFS filesystem fsid=0x%016"PRIx64
			".0x%016"PRIx64" from handle",
			fsid.major, fsid.minor);
		return fsalstat(ERR_FSAL_STALE, ESTALE);
	}

	gpfs_fs = fs->private_data;

	fsal_prepare_attrs(&attrib, ATTR_GPFS_ALLOC_HANDLE);

	if (attrs_out != NULL)
		attrib.mask |= attrs_out->mask;

	status = GPFSFSAL_getattrs(exp_hdl, gpfs_fs, op_ctx, fh, &attrib);
	if (FSAL_IS_ERROR(status))
		return status;

	if (attrib.type == SYMBOLIC_LINK) {	/* I could lazy eval this... */

		status = fsal_readlink_by_handle(gpfs_fs->root_fd, fh,
						 link_buff, &retlink);
		if (FSAL_IS_ERROR(status))
			return status;

		if (retlink < 0 || retlink == PATH_MAX) {
			retval = errno;
			if (retlink == PATH_MAX)
				retval = ENAMETOOLONG;
			return fsalstat(posix2fsal_error(retval), retval);
		}
		link_buff[retlink] = '\0';
		link_content = link_buff;
	}

	hdl = alloc_handle(fh, fs, &attrib, link_content, exp_hdl);

	if (attrs_out != NULL) {
		/* Copy the attributes to caller, passing ACL ref. */
		fsal_copy_attrs(attrs_out, &attrib, true);
	} else {
		/* Done with the attrs */
		fsal_release_attrs(&attrib);
	}

	*handle = &hdl->obj_handle;

	return status;
}