Commit cc0d05b4 authored by Wu, Mengjin's avatar Wu, Mengjin Committed by Tomasz Zawadzki
Browse files

lib/nbd: hot remove will be correctly handled



BUG FIX: call nbd_bdev_hot_remove will stuck if
it is called when nbd has in-flight IOs.

nbd_bdev_hot_remove is asynchronous. It will
guarantee the stop of this nbd.

nbd hot remove test will be added later

Signed-off-by: default avatarMengjinWu <mengjin.wu@intel.com>
Change-Id: I0a0dfab31fafd3d61212ade53c74ad05dbbff268
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/8039


Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarZiye Yang <ziye.yang@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarGangCao <gang.cao@intel.com>
Reviewed-by: default avatarXiaodong Liu <xiaodong.liu@intel.com>
Reviewed-by: default avatar <dongx.yi@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent ea035517
Loading
Loading
Loading
Loading
+32 −7
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ struct spdk_nbd_disk {
	struct nbd_io		*io_in_recv;
	TAILQ_HEAD(, nbd_io)	received_io_list;
	TAILQ_HEAD(, nbd_io)	executed_io_list;
	TAILQ_HEAD(, nbd_io)	processing_io_list;

	bool			is_started;
	bool			is_closing;
@@ -477,6 +478,7 @@ nbd_io_done(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg)
		spdk_interrupt_set_event_types(nbd->intr, SPDK_INTERRUPT_EVENT_IN | SPDK_INTERRUPT_EVENT_OUT);
	}

	TAILQ_REMOVE(&nbd->processing_io_list, io, tailq);
	TAILQ_INSERT_TAIL(&nbd->executed_io_list, io, tailq);

	if (bdev_io != NULL) {
@@ -571,6 +573,7 @@ nbd_io_exec(struct spdk_nbd_disk *nbd)
	if (!TAILQ_EMPTY(&nbd->received_io_list)) {
		TAILQ_FOREACH_SAFE(io, &nbd->received_io_list, tailq, io_tmp) {
			TAILQ_REMOVE(&nbd->received_io_list, io, tailq);
			TAILQ_INSERT_TAIL(&nbd->processing_io_list, io, tailq);
			ret = nbd_submit_bdev_io(nbd, io);
			if (ret < 0) {
				return ret;
@@ -664,6 +667,7 @@ nbd_io_recv_internal(struct spdk_nbd_disk *nbd)
				if (spdk_likely((!nbd->is_closing) && nbd->is_started)) {
					TAILQ_INSERT_TAIL(&nbd->received_io_list, io, tailq);
				} else {
					TAILQ_INSERT_TAIL(&nbd->processing_io_list, io, tailq);
					nbd_io_done(NULL, false, io);
				}
				nbd->io_in_recv = NULL;
@@ -689,6 +693,7 @@ nbd_io_recv_internal(struct spdk_nbd_disk *nbd)
			if (spdk_likely((!nbd->is_closing) && nbd->is_started)) {
				TAILQ_INSERT_TAIL(&nbd->received_io_list, io, tailq);
			} else {
				TAILQ_INSERT_TAIL(&nbd->processing_io_list, io, tailq);
				nbd_io_done(NULL, false, io);
			}
			nbd->io_in_recv = NULL;
@@ -704,18 +709,22 @@ nbd_io_recv(struct spdk_nbd_disk *nbd)
{
	int i, rc, ret = 0;

	for (i = 0; i < GET_IO_LOOP_COUNT; i++) {
	/*
		 * nbd server should not accept requests after closing command
	 * nbd server should not accept request after closing command
	 */
	if (nbd->is_closing) {
			break;
		return 0;
	}

	for (i = 0; i < GET_IO_LOOP_COUNT; i++) {
		rc = nbd_io_recv_internal(nbd);
		if (rc < 0) {
			return rc;
		}
		ret += rc;
		if (nbd->is_closing) {
			break;
		}
	}

	return ret;
@@ -877,7 +886,22 @@ nbd_start_kernel(void *arg)
static void
nbd_bdev_hot_remove(struct spdk_nbd_disk *nbd)
{
	spdk_nbd_stop(nbd);
	struct nbd_io *io, *io_tmp;

	nbd->is_closing = true;
	nbd_cleanup_io(nbd);

	if (!TAILQ_EMPTY(&nbd->received_io_list)) {
		TAILQ_FOREACH_SAFE(io, &nbd->received_io_list, tailq, io_tmp) {
			TAILQ_REMOVE(&nbd->received_io_list, io, tailq);
			TAILQ_INSERT_TAIL(&nbd->processing_io_list, io, tailq);
		}
	}
	if (!TAILQ_EMPTY(&nbd->processing_io_list)) {
		TAILQ_FOREACH_SAFE(io, &nbd->processing_io_list, tailq, io_tmp) {
			nbd_io_done(NULL, false, io);
		}
	}
}

static void
@@ -1105,6 +1129,7 @@ spdk_nbd_start(const char *bdev_name, const char *nbd_path,

	TAILQ_INIT(&nbd->received_io_list);
	TAILQ_INIT(&nbd->executed_io_list);
	TAILQ_INIT(&nbd->processing_io_list);

	/* Add nbd_disk to the end of disk list */
	rc = nbd_disk_register(ctx->nbd);