Commit 0194aa5b authored by Artur Paszkiewicz's avatar Artur Paszkiewicz Committed by Jim Harris
Browse files

bdev/lvol: eliminate grow examine code duplication



These functions:
 _vbdev_lvs_grow_examine_finish
 _vbdev_lvs_grow_examine_cb
 _vbdev_lvs_grow_examine

are almost exact copies of:
 _vbdev_lvs_examine_finish
 _vbdev_lvs_examine_cb
 vbdev_lvs_examine

Remove the duplicated grow functions. Factor out the common entry point
into _vbdev_lvs_examine() which accepts a callback to perform the
required action (spdk_lvs_load or spdk_lvs_grow).

Change-Id: I9805f29e22812051608873207401e3786dab7103
Signed-off-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16942


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent f64fe6fe
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -26,11 +26,10 @@ struct spdk_lvs_req {
};

struct spdk_lvs_grow_req {
	struct spdk_lvs_req	base;
	spdk_lvs_op_complete	cb_fn;
	void			*cb_arg;
	struct spdk_lvol_store	*lvol_store;
	struct lvol_store_bdev	*lvs_bdev;
	int			lvserrno;
	int			lvol_cnt;
};

+68 −154
Original line number Diff line number Diff line
@@ -1319,16 +1319,25 @@ vbdev_lvs_get_ctx_size(void)
	return sizeof(struct vbdev_lvol_io);
}

static void
_vbdev_lvs_examine_done(struct spdk_lvs_req *req, int lvserrno)
{
	req->cb_fn(req->cb_arg, lvserrno);
}

static void
_vbdev_lvs_examine_failed(void *cb_arg, int lvserrno)
{
	spdk_bdev_module_examine_done(&g_lvol_if);
	struct spdk_lvs_req *req = cb_arg;

	_vbdev_lvs_examine_done(req, req->lvserrno);
}

static void
_vbdev_lvs_examine_finish(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
{
	struct spdk_lvol_store *lvs = cb_arg;
	struct spdk_lvs_req *req = cb_arg;
	struct spdk_lvol_store *lvs = req->lvol_store;

	if (lvolerrno != 0) {
		SPDK_ERRLOG("Error opening lvol %s\n", lvol->unique_id);
@@ -1348,10 +1357,9 @@ _vbdev_lvs_examine_finish(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
	SPDK_INFOLOG(vbdev_lvol, "Opening lvol %s succeeded\n", lvol->unique_id);

end:

	if (lvs->lvols_opened >= lvs->lvol_count) {
		SPDK_INFOLOG(vbdev_lvol, "Opening lvols finished\n");
		spdk_bdev_module_examine_done(&g_lvol_if);
		_vbdev_lvs_examine_done(req, 0);
	}
}

@@ -1361,32 +1369,35 @@ _vbdev_lvs_examine_cb(void *arg, struct spdk_lvol_store *lvol_store, int lvserrn
	struct lvol_store_bdev *lvs_bdev;
	struct spdk_lvs_with_handle_req *req = (struct spdk_lvs_with_handle_req *)arg;
	struct spdk_lvol *lvol, *tmp;
	struct spdk_lvs_req *ori_req = req->cb_arg;

	if (lvserrno == -EEXIST) {
		SPDK_INFOLOG(vbdev_lvol,
			     "Name for lvolstore on device %s conflicts with name for already loaded lvs\n",
			     req->base_bdev->name);
		/* On error blobstore destroys bs_dev itself */
		spdk_bdev_module_examine_done(&g_lvol_if);
		_vbdev_lvs_examine_done(ori_req, lvserrno);
		goto end;
	} else if (lvserrno != 0) {
		SPDK_INFOLOG(vbdev_lvol, "Lvol store not found on %s\n", req->base_bdev->name);
		/* On error blobstore destroys bs_dev itself */
		spdk_bdev_module_examine_done(&g_lvol_if);
		_vbdev_lvs_examine_done(ori_req, lvserrno);
		goto end;
	}

	lvserrno = spdk_bs_bdev_claim(lvol_store->bs_dev, &g_lvol_if);
	if (lvserrno != 0) {
		SPDK_INFOLOG(vbdev_lvol, "Lvol store base bdev already claimed by another bdev\n");
		spdk_lvs_unload(lvol_store, _vbdev_lvs_examine_failed, NULL);
		ori_req->lvserrno = lvserrno;
		spdk_lvs_unload(lvol_store, _vbdev_lvs_examine_failed, ori_req);
		goto end;
	}

	lvs_bdev = calloc(1, sizeof(*lvs_bdev));
	if (!lvs_bdev) {
		SPDK_ERRLOG("Cannot alloc memory for lvs_bdev\n");
		spdk_lvs_unload(lvol_store, _vbdev_lvs_examine_failed, NULL);
		ori_req->lvserrno = lvserrno;
		spdk_lvs_unload(lvol_store, _vbdev_lvs_examine_failed, ori_req);
		goto end;
	}

@@ -1400,13 +1411,15 @@ _vbdev_lvs_examine_cb(void *arg, struct spdk_lvol_store *lvol_store, int lvserrn

	lvol_store->lvols_opened = 0;

	ori_req->lvol_store = lvol_store;

	if (TAILQ_EMPTY(&lvol_store->lvols)) {
		SPDK_INFOLOG(vbdev_lvol, "Lvol store examination done\n");
		spdk_bdev_module_examine_done(&g_lvol_if);
		_vbdev_lvs_examine_done(ori_req, 0);
	} else {
		/* Open all lvols */
		TAILQ_FOREACH_SAFE(lvol, &lvol_store->lvols, link, tmp) {
			spdk_lvol_open(lvol, _vbdev_lvs_examine_finish, lvol_store);
			spdk_lvol_open(lvol, _vbdev_lvs_examine_finish, ori_req);
		}
	}

@@ -1415,23 +1428,17 @@ end:
}

static void
vbdev_lvs_examine(struct spdk_bdev *bdev)
_vbdev_lvs_examine(struct spdk_bdev *bdev, struct spdk_lvs_req *ori_req,
		   void (*action)(struct spdk_bs_dev *bs_dev, spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg))
{
	struct spdk_bs_dev *bs_dev;
	struct spdk_lvs_with_handle_req *req;
	int rc;

	if (spdk_bdev_get_md_size(bdev) != 0) {
		SPDK_INFOLOG(vbdev_lvol, "Cannot create bs dev on %s\n which is formatted with metadata",
			     bdev->name);
		spdk_bdev_module_examine_done(&g_lvol_if);
		return;
	}

	req = calloc(1, sizeof(*req));
	if (req == NULL) {
		spdk_bdev_module_examine_done(&g_lvol_if);
		SPDK_ERRLOG("Cannot alloc memory for vbdev lvol store request pointer\n");
		_vbdev_lvs_examine_done(ori_req, -ENOMEM);
		return;
	}

@@ -1439,165 +1446,73 @@ vbdev_lvs_examine(struct spdk_bdev *bdev)
					 NULL, &bs_dev);
	if (rc < 0) {
		SPDK_INFOLOG(vbdev_lvol, "Cannot create bs dev on %s\n", bdev->name);
		spdk_bdev_module_examine_done(&g_lvol_if);
		_vbdev_lvs_examine_done(ori_req, rc);
		free(req);
		return;
	}

	req->base_bdev = bdev;
	req->cb_arg = ori_req;

	spdk_lvs_load(bs_dev, _vbdev_lvs_examine_cb, req);
}

struct spdk_lvol *
vbdev_lvol_get_from_bdev(struct spdk_bdev *bdev)
{
	if (!bdev || bdev->module != &g_lvol_if) {
		return NULL;
	}

	if (bdev->ctxt == NULL) {
		SPDK_ERRLOG("No lvol ctx assigned to bdev %s\n", bdev->name);
		return NULL;
	}

	return (struct spdk_lvol *)bdev->ctxt;
	action(bs_dev, _vbdev_lvs_examine_cb, req);
}

static void
_vbdev_lvs_grow_finish(void *arg, int lvserrno)
vbdev_lvs_examine_done(void *arg, int lvserrno)
{
	struct spdk_lvs_grow_req *req = arg;
	req->cb_fn(req->cb_arg, req->lvserrno);
	struct spdk_lvs_req *req = arg;

	spdk_bdev_module_examine_done(&g_lvol_if);
	free(req);
}

static void
_vbdev_lvs_grow_examine_finish(void *cb_arg, struct spdk_lvol *lvol, int lvolerrno)
vbdev_lvs_examine(struct spdk_bdev *bdev)
{
	struct spdk_lvs_grow_req *req = cb_arg;
	struct spdk_lvol_store *lvs = req->lvol_store;
	struct spdk_lvs_req *req;

	if (lvolerrno != 0) {
		SPDK_ERRLOG("Error opening lvol %s\n", lvol->unique_id);
		TAILQ_REMOVE(&lvs->lvols, lvol, link);
		assert(lvs->lvol_count > 0);
		lvs->lvol_count--;
		free(lvol);
		goto end;
	if (spdk_bdev_get_md_size(bdev) != 0) {
		SPDK_INFOLOG(vbdev_lvol, "Cannot create bs dev on %s\n which is formatted with metadata",
			     bdev->name);
		spdk_bdev_module_examine_done(&g_lvol_if);
		return;
	}

	if (_create_lvol_disk(lvol, false)) {
		SPDK_ERRLOG("Cannot create bdev for lvol %s\n", lvol->unique_id);
		assert(lvs->lvol_count > 0);
		lvs->lvol_count--;
		SPDK_INFOLOG(vbdev_lvol, "Opening lvol %s failed\n", lvol->unique_id);
		goto end;
	req = calloc(1, sizeof(*req));
	if (req == NULL) {
		SPDK_ERRLOG("Cannot alloc memory for vbdev lvol store request pointer\n");
		spdk_bdev_module_examine_done(&g_lvol_if);
		return;
	}

	lvs->lvols_opened++;
	SPDK_INFOLOG(vbdev_lvol, "Opening lvol %s succeeded\n", lvol->unique_id);
	req->cb_fn = vbdev_lvs_examine_done;
	req->cb_arg = req;

end:
	if (lvs->lvols_opened >= lvs->lvol_count) {
		SPDK_INFOLOG(vbdev_lvol, "Opening lvols finished\n");
		_vbdev_lvs_grow_finish(req, 0);
	}
	_vbdev_lvs_examine(bdev, req, spdk_lvs_load);
}

static void
_vbdev_lvs_grow_examine_cb(void *arg, struct spdk_lvol_store *lvol_store, int lvserrno)
struct spdk_lvol *
vbdev_lvol_get_from_bdev(struct spdk_bdev *bdev)
{
	struct lvol_store_bdev *lvs_bdev;
	struct spdk_lvs_with_handle_req *req = (struct spdk_lvs_with_handle_req *)arg;
	struct spdk_lvol *lvol, *tmp;
	struct spdk_lvs_grow_req *ori_req = req->cb_arg;

	if (lvserrno == -EEXIST) {
		SPDK_INFOLOG(vbdev_lvol,
			     "Name for lvolstore on device %s conflicts with name for already loaded lvs\n",
			     req->base_bdev->name);
		ori_req->lvserrno = lvserrno;
		_vbdev_lvs_grow_finish(ori_req, lvserrno);
		goto end;
	} else if (lvserrno != 0) {
		SPDK_INFOLOG(vbdev_lvol, "Lvol store not found on %s\n", req->base_bdev->name);
		/* On error blobstore destroys bs_dev itself */
		ori_req->lvserrno = lvserrno;
		_vbdev_lvs_grow_finish(ori_req, lvserrno);
		goto end;
	}

	lvserrno = spdk_bs_bdev_claim(lvol_store->bs_dev, &g_lvol_if);
	if (lvserrno != 0) {
		SPDK_INFOLOG(vbdev_lvol, "Lvol store base bdev already claimed by another bdev\n");
		ori_req->lvserrno = lvserrno;
		spdk_lvs_unload(lvol_store, _vbdev_lvs_grow_finish, ori_req);
		goto end;
	}

	lvs_bdev = calloc(1, sizeof(*lvs_bdev));
	if (!lvs_bdev) {
		SPDK_ERRLOG("Cannot alloc memory for lvs_bdev\n");
		ori_req->lvserrno = -ENOMEM;
		spdk_lvs_unload(lvol_store, _vbdev_lvs_grow_finish, ori_req);
		goto end;
	if (!bdev || bdev->module != &g_lvol_if) {
		return NULL;
	}

	lvs_bdev->lvs = lvol_store;
	lvs_bdev->bdev = req->base_bdev;

	TAILQ_INSERT_TAIL(&g_spdk_lvol_pairs, lvs_bdev, lvol_stores);
	SPDK_INFOLOG(vbdev_lvol, "Lvol store found on %s - begin parsing\n",
		     req->base_bdev->name);

	lvol_store->lvols_opened = 0;

	ori_req->lvol_store = lvol_store;
	ori_req->lvserrno = 0;
	if (TAILQ_EMPTY(&lvol_store->lvols)) {
		SPDK_INFOLOG(vbdev_lvol, "Lvol store examination done\n");
		_vbdev_lvs_grow_finish(ori_req, 0);
	} else {
		/* Open all lvols */
		TAILQ_FOREACH_SAFE(lvol, &lvol_store->lvols, link, tmp) {
			spdk_lvol_open(lvol, _vbdev_lvs_grow_examine_finish, ori_req);
		}
	if (bdev->ctxt == NULL) {
		SPDK_ERRLOG("No lvol ctx assigned to bdev %s\n", bdev->name);
		return NULL;
	}

end:
	free(req);
	return (struct spdk_lvol *)bdev->ctxt;
}

static void
_vbdev_lvs_grow_examine(struct spdk_bdev *bdev, struct spdk_lvs_grow_req *ori_req)
_vbdev_lvs_grow_finish(void *arg, int lvserrno)
{
	struct spdk_bs_dev *bs_dev;
	struct spdk_lvs_with_handle_req *req;
	int rc;

	req = calloc(1, sizeof(*req));
	if (req == NULL) {
		SPDK_ERRLOG("Cannot alloc memory for vbdev lvol store request pointer\n");
		ori_req->lvserrno = -ENOMEM;
		_vbdev_lvs_grow_finish(ori_req, -ENOMEM);
		return;
	}
	struct spdk_lvs_grow_req *req = arg;

	rc = spdk_bdev_create_bs_dev_ext(bdev->name, vbdev_lvs_base_bdev_event_cb,
					 NULL, &bs_dev);
	if (rc < 0) {
		SPDK_INFOLOG(vbdev_lvol, "Cannot create bs dev on %s\n", bdev->name);
		ori_req->lvserrno = rc;
		_vbdev_lvs_grow_finish(ori_req, rc);
	req->cb_fn(req->cb_arg, lvserrno);
	free(req);
		return;
	}

	req->base_bdev = bdev;
	req->cb_arg = ori_req;

	spdk_lvs_grow(bs_dev, _vbdev_lvs_grow_examine_cb, req);
}

static void
@@ -1608,15 +1523,16 @@ _vbdev_lvs_grow_unload_cb(void *cb_arg, int lvserrno)
	struct spdk_bdev *bdev;

	if (lvserrno != 0) {
		req->cb_fn(req->cb_arg, lvserrno);
		free(req);
		_vbdev_lvs_grow_finish(req, lvserrno);
		return;
	}

	lvs_bdev = req->lvs_bdev;
	bdev = lvs_bdev->bdev;
	TAILQ_REMOVE(&g_spdk_lvol_pairs, lvs_bdev, lvol_stores);
	_vbdev_lvs_grow_examine(bdev, req);
	req->base.cb_fn = _vbdev_lvs_grow_finish;
	req->base.cb_arg = req;
	_vbdev_lvs_examine(bdev, &req->base, spdk_lvs_grow);
	free(lvs_bdev);
}

@@ -1624,7 +1540,7 @@ static void
_vbdev_lvs_grow_remove_bdev_unregistered_cb(void *cb_arg, int bdeverrno)
{
	struct spdk_lvs_grow_req *req = cb_arg;
	struct spdk_lvol_store *lvs = req->lvol_store;
	struct spdk_lvol_store *lvs = req->base.lvol_store;

	if (bdeverrno != 0) {
		SPDK_DEBUGLOG(vbdev_lvol, "Lvol unregistered with errno %d\n", bdeverrno);
@@ -1637,8 +1553,7 @@ _vbdev_lvs_grow_remove_bdev_unregistered_cb(void *cb_arg, int bdeverrno)
		if (_vbdev_lvs_are_lvols_closed(lvs)) {
			spdk_lvs_unload(lvs, _vbdev_lvs_grow_unload_cb, req);
		} else {
			req->cb_fn(req->cb_arg, -EINVAL);
			free(req);
			_vbdev_lvs_grow_finish(req, -EINVAL);
		}
	}
}
@@ -1658,12 +1573,11 @@ vbdev_lvs_grow(struct spdk_lvol_store *lvs,
	}
	req->cb_fn = cb_fn;
	req->cb_arg = cb_arg;
	req->lvol_store = lvs;
	req->base.lvol_store = lvs;
	req->lvs_bdev = vbdev_get_lvs_bdev_by_lvs(lvs);
	if (req->lvs_bdev == NULL) {
		SPDK_ERRLOG("Cannot get valid lvs_bdev\n");
		cb_fn(cb_arg, -EINVAL);
		free(req);
		_vbdev_lvs_grow_finish(req, -EINVAL);
		return;
	}