Commit be9a3b9f authored by Jim Harris's avatar Jim Harris
Browse files

bdev: pass descriptors for I/O operations



This enables checking permissions - for example,
spdk_bdev_write will fail if the descriptor was not
created with write permissions.

Signed-off-by: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: I68b65a560f471f2e0f71a7f42cfa6689b911110f

Reviewed-on: https://review.gerrithub.io/369493


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent f71447e8
Loading
Loading
Loading
Loading
+17 −9
Original line number Diff line number Diff line
@@ -164,6 +164,14 @@ int spdk_bdev_open(struct spdk_bdev *bdev, bool write, spdk_bdev_remove_cb_t rem
 */
void spdk_bdev_close(struct spdk_bdev_desc *desc);

/**
 * Get the bdev associated with a bdev descriptor.
 *
 * \param desc Open block device desciptor
 * \return bdev associated with the descriptor
 */
struct spdk_bdev *spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc);

bool spdk_bdev_io_type_supported(struct spdk_bdev *bdev, enum spdk_bdev_io_type io_type);

int spdk_bdev_dump_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx *w);
@@ -256,7 +264,7 @@ struct spdk_io_channel *spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc);
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 */
int spdk_bdev_read(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
int spdk_bdev_read(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		   void *buf, uint64_t offset, uint64_t nbytes,
		   spdk_bdev_io_completion_cb cb, void *cb_arg);

@@ -280,7 +288,7 @@ int spdk_bdev_read(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 */
int spdk_bdev_readv(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
int spdk_bdev_readv(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		    struct iovec *iov, int iovcnt,
		    uint64_t offset, uint64_t nbytes,
		    spdk_bdev_io_completion_cb cb, void *cb_arg);
@@ -300,7 +308,7 @@ int spdk_bdev_readv(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 */
int spdk_bdev_write(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
int spdk_bdev_write(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		    void *buf, uint64_t offset, uint64_t nbytes,
		    spdk_bdev_io_completion_cb cb, void *cb_arg);

@@ -324,7 +332,7 @@ int spdk_bdev_write(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 */
int spdk_bdev_writev(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
int spdk_bdev_writev(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		     struct iovec *iov, int iovcnt,
		     uint64_t offset, uint64_t len,
		     spdk_bdev_io_completion_cb cb, void *cb_arg);
@@ -345,7 +353,7 @@ int spdk_bdev_writev(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 */
int spdk_bdev_unmap(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
int spdk_bdev_unmap(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		    struct spdk_scsi_unmap_bdesc *unmap_d,
		    uint16_t bdesc_count,
		    spdk_bdev_io_completion_cb cb, void *cb_arg);
@@ -366,7 +374,7 @@ int spdk_bdev_unmap(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 */
int spdk_bdev_flush(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
int spdk_bdev_flush(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		    uint64_t offset, uint64_t length,
		    spdk_bdev_io_completion_cb cb, void *cb_arg);

@@ -382,7 +390,7 @@ int spdk_bdev_flush(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 */
int spdk_bdev_reset(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
int spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		    spdk_bdev_io_completion_cb cb, void *cb_arg);

/**
@@ -405,7 +413,7 @@ int spdk_bdev_reset(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 */
int spdk_bdev_nvme_admin_passthru(struct spdk_bdev *bdev,
int spdk_bdev_nvme_admin_passthru(struct spdk_bdev_desc *desc,
				  struct spdk_io_channel *ch,
				  const struct spdk_nvme_cmd *cmd,
				  void *buf, size_t nbytes,
@@ -432,7 +440,7 @@ int spdk_bdev_nvme_admin_passthru(struct spdk_bdev *bdev,
 * be called (even if the request ultimately failed). Return
 * negated errno on failure, in which case the callback will not be called.
 */
int spdk_bdev_nvme_io_passthru(struct spdk_bdev *bdev,
int spdk_bdev_nvme_io_passthru(struct spdk_bdev_desc *bdev_desc,
			       struct spdk_io_channel *ch,
			       const struct spdk_nvme_cmd *cmd,
			       void *buf, size_t nbytes,
+1 −0
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ struct spdk_scsi_task {
	uint8_t				function; /* task mgmt function */
	uint8_t				response; /* task mgmt response */
	struct spdk_scsi_lun		*lun;
	struct spdk_bdev_desc		*desc;
	struct spdk_io_channel		*ch;
	struct spdk_scsi_port		*target_port;
	struct spdk_scsi_port		*initiator_port;
+1 −1
Original line number Diff line number Diff line
@@ -398,7 +398,7 @@ void spdk_bdev_poller_stop(struct spdk_bdev_poller **ppoller);

void spdk_bdev_io_get_buf(struct spdk_bdev_io *bdev_io, spdk_bdev_io_get_buf_cb cb);
struct spdk_bdev_io *spdk_bdev_get_io(void);
void spdk_bdev_io_resubmit(struct spdk_bdev_io *bdev_io, struct spdk_bdev *new_bdev);
void spdk_bdev_io_resubmit(struct spdk_bdev_io *bdev_io, struct spdk_bdev_desc *new_bdev_desc);
void spdk_bdev_io_complete(struct spdk_bdev_io *bdev_io,
			   enum spdk_bdev_io_status status);

+56 −10
Original line number Diff line number Diff line
@@ -580,8 +580,10 @@ spdk_bdev_io_submit(struct spdk_bdev_io *bdev_io)
}

void
spdk_bdev_io_resubmit(struct spdk_bdev_io *bdev_io, struct spdk_bdev *new_bdev)
spdk_bdev_io_resubmit(struct spdk_bdev_io *bdev_io, struct spdk_bdev_desc *new_bdev_desc)
{
	struct spdk_bdev *new_bdev = new_bdev_desc->bdev;

	assert(bdev_io->status == SPDK_BDEV_IO_STATUS_PENDING);
	bdev_io->bdev = new_bdev;

@@ -764,10 +766,11 @@ spdk_bdev_io_valid(struct spdk_bdev *bdev, uint64_t offset, uint64_t nbytes)
}

int
spdk_bdev_read(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
spdk_bdev_read(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
	       void *buf, uint64_t offset, uint64_t nbytes,
	       spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = desc->bdev;
	struct spdk_bdev_io *bdev_io;
	struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
	int rc;
@@ -802,11 +805,12 @@ spdk_bdev_read(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
}

int
spdk_bdev_readv(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
spdk_bdev_readv(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		struct iovec *iov, int iovcnt,
		uint64_t offset, uint64_t nbytes,
		spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = desc->bdev;
	struct spdk_bdev_io *bdev_io;
	struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
	int rc;
@@ -839,14 +843,19 @@ spdk_bdev_readv(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
}

int
spdk_bdev_write(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
spdk_bdev_write(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		void *buf, uint64_t offset, uint64_t nbytes,
		spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = desc->bdev;
	struct spdk_bdev_io *bdev_io;
	struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
	int rc;

	if (!desc->write) {
		return -EBADF;
	}

	if (spdk_bdev_io_valid(bdev, offset, nbytes) != 0) {
		return -EINVAL;
	}
@@ -877,15 +886,20 @@ spdk_bdev_write(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
}

int
spdk_bdev_writev(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
spdk_bdev_writev(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		 struct iovec *iov, int iovcnt,
		 uint64_t offset, uint64_t len,
		 spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = desc->bdev;
	struct spdk_bdev_io *bdev_io;
	struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
	int rc;

	if (!desc->write) {
		return -EBADF;
	}

	if (spdk_bdev_io_valid(bdev, offset, len) != 0) {
		return -EINVAL;
	}
@@ -914,15 +928,20 @@ spdk_bdev_writev(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
}

int
spdk_bdev_unmap(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
spdk_bdev_unmap(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		struct spdk_scsi_unmap_bdesc *unmap_d,
		uint16_t bdesc_count,
		spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = desc->bdev;
	struct spdk_bdev_io *bdev_io;
	struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
	int rc;

	if (!desc->write) {
		return -EBADF;
	}

	if (bdesc_count == 0) {
		SPDK_ERRLOG("Invalid bdesc_count 0\n");
		return -EINVAL;
@@ -956,14 +975,19 @@ spdk_bdev_unmap(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
}

int
spdk_bdev_flush(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
spdk_bdev_flush(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		uint64_t offset, uint64_t length,
		spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = desc->bdev;
	struct spdk_bdev_io *bdev_io;
	struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
	int rc;

	if (!desc->write) {
		return -EBADF;
	}

	bdev_io = spdk_bdev_get_io();
	if (!bdev_io) {
		SPDK_ERRLOG("bdev_io memory allocation failed duing flush\n");
@@ -1045,9 +1069,10 @@ _spdk_bdev_start_next_reset(struct spdk_bdev *bdev)
}

int
spdk_bdev_reset(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
spdk_bdev_reset(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
		spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = desc->bdev;
	struct spdk_bdev_io *bdev_io;
	struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);

@@ -1087,14 +1112,19 @@ spdk_bdev_get_io_stat(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
}

int
spdk_bdev_nvme_admin_passthru(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
spdk_bdev_nvme_admin_passthru(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
			      const struct spdk_nvme_cmd *cmd, void *buf, size_t nbytes,
			      spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = desc->bdev;
	struct spdk_bdev_io *bdev_io;
	struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
	int rc;

	if (!desc->write) {
		return -EBADF;
	}

	bdev_io = spdk_bdev_get_io();
	if (!bdev_io) {
		SPDK_ERRLOG("bdev_io memory allocation failed during nvme_admin_passthru\n");
@@ -1119,14 +1149,24 @@ spdk_bdev_nvme_admin_passthru(struct spdk_bdev *bdev, struct spdk_io_channel *ch
}

int
spdk_bdev_nvme_io_passthru(struct spdk_bdev *bdev, struct spdk_io_channel *ch,
spdk_bdev_nvme_io_passthru(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch,
			   const struct spdk_nvme_cmd *cmd, void *buf, size_t nbytes,
			   spdk_bdev_io_completion_cb cb, void *cb_arg)
{
	struct spdk_bdev *bdev = desc->bdev;
	struct spdk_bdev_io *bdev_io;
	struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch);
	int rc;

	if (!desc->write) {
		/*
		 * Do not try to parse the NVMe command - we could maybe use bits in the opcode
		 *  to easily determine if the command is a read or write, but for now just
		 *  do not allow io_passthru with a read-only descriptor.
		 */
		return -EBADF;
	}

	bdev_io = spdk_bdev_get_io();
	if (!bdev_io) {
		SPDK_ERRLOG("bdev_io memory allocation failed during nvme_admin_passthru\n");
@@ -1560,6 +1600,12 @@ spdk_bdev_module_release_bdev(struct spdk_bdev *bdev)
	bdev->claim_module = NULL;
}

struct spdk_bdev *
spdk_bdev_desc_get_bdev(struct spdk_bdev_desc *desc)
{
	return desc->bdev;
}

void
spdk_bdev_io_get_iovec(struct spdk_bdev_io *bdev_io, struct iovec **iovp, int *iovcntp)
{
+8 −2
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ struct vbdev_error_info {
struct vbdev_error_disk {
	struct spdk_bdev		disk;
	struct spdk_bdev		*base_bdev;
	struct spdk_bdev_desc		*base_bdev_desc;
	struct vbdev_error_info		error_vector[SPDK_BDEV_IO_TYPE_RESET];

	TAILQ_ENTRY(vbdev_error_disk)	tailq;
@@ -162,7 +163,7 @@ vbdev_error_submit_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev

	error_type = vbdev_error_get_error_type(error_disk, bdev_io->type);
	if (error_type == 0) {
		spdk_bdev_io_resubmit(bdev_io, error_disk->base_bdev);
		spdk_bdev_io_resubmit(bdev_io, error_disk->base_bdev_desc);
		return;
	} else if (error_type == VBDEV_IO_FAILURE) {
		error_disk->error_vector[bdev_io->type].error_num--;
@@ -259,7 +260,12 @@ spdk_vbdev_error_create(struct spdk_bdev *base_bdev)
		goto cleanup;
	}

	rc = spdk_bdev_module_claim_bdev(base_bdev, NULL, SPDK_GET_BDEV_MODULE(error));
	rc = spdk_bdev_open(base_bdev, false, NULL, NULL, &disk->base_bdev_desc);
	if (rc) {
		SPDK_ERRLOG("could not open bdev %s\n", spdk_bdev_get_name(base_bdev));
	}

	rc = spdk_bdev_module_claim_bdev(base_bdev, disk->base_bdev_desc, SPDK_GET_BDEV_MODULE(error));
	if (rc) {
		SPDK_ERRLOG("could not claim bdev %s\n", spdk_bdev_get_name(base_bdev));
		goto cleanup;
Loading