Commit 3318278a authored by Haoqian He's avatar Haoqian He Committed by Jim Harris
Browse files

vhost: check if vsession exists before remove scsi vdev



Before remove the vhost scsi target when deleting controller,
we can return EBUSY if still exist vsession, which means the
inflight IO has not finished yet. Otherwise the guest may get
I/O error.

Change-Id: Ib76b276efe1e9c6fa324bedc3cb5d9d4622c753f
Signed-off-by: default avatarHaoqian He <haoqian.he@smartx.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/25517


Community-CI: Mellanox Build Bot
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Community CI Samsung <spdk.community.ci.samsung@gmail.com>
Reviewed-by: default avatarChangpeng Liu <changpeliu@tencent.com>
Reviewed-by: default avatarJim Harris <jim.harris@nvidia.com>
parent a2f5e1c2
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -1849,6 +1849,26 @@ vhost_user_dev_create(struct spdk_vhost_dev *vdev, const char *name, struct spdk
	return rc;
}


bool
vhost_user_dev_busy(struct spdk_vhost_dev *vdev)
{
	struct spdk_vhost_user_dev *user_dev = to_user_dev(vdev);

	if (pthread_mutex_trylock(&user_dev->lock) != 0) {
		return true;
	}

	/* This is the case that uses RPC call `vhost_delete_controller` while VM is connected */
	if (!TAILQ_EMPTY(&user_dev->vsessions) && g_vhost_user_started) {
		SPDK_ERRLOG("Controller %s has still valid connection.\n", vdev->name);
		pthread_mutex_unlock(&user_dev->lock);
		return true;
	}
	pthread_mutex_unlock(&user_dev->lock);
	return false;
}

int
vhost_user_dev_unregister(struct spdk_vhost_dev *vdev)
{
+1 −0
Original line number Diff line number Diff line
@@ -507,6 +507,7 @@ int vhost_user_dev_create(struct spdk_vhost_dev *vdev, const char *name,
int vhost_user_dev_init(struct spdk_vhost_dev *vdev, const char *name,
			struct spdk_cpuset *cpumask, const struct spdk_vhost_user_dev_backend *user_backend);
int vhost_user_dev_start(struct spdk_vhost_dev *vdev);
bool vhost_user_dev_busy(struct spdk_vhost_dev *vdev);
int vhost_user_dev_unregister(struct spdk_vhost_dev *vdev);
int vhost_user_init(void);
void vhost_user_fini(spdk_vhost_fini_cb vhost_cb);
+5 −0
Original line number Diff line number Diff line
@@ -939,6 +939,11 @@ vhost_scsi_dev_remove(struct spdk_vhost_dev *vdev)
	int rc = 0, i;

	assert(svdev != NULL);

	if (vhost_user_dev_busy(vdev)) {
		return -EBUSY;
	}

	for (i = 0; i < SPDK_VHOST_SCSI_CTRLR_MAX_DEVS; ++i) {
		if (svdev->scsi_dev_state[i].dev) {
			rc = spdk_vhost_scsi_dev_remove_tgt(vdev, i, NULL, NULL);