Commit 463925ff authored by Jim Harris's avatar Jim Harris Committed by Daniel Verkamp
Browse files

blob: make spdk_blob_resize an async operation



To support resize operations during I/O, we will need
to send messages to each thread to quiesce I/O while
the resize operation is in progress to guard against
the cluster map memory changing while another thread
is accessing the cluster map.

Therefore, spdk_blob_resize needs to be asynchronous.

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

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


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 33aad6ee
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -38,6 +38,10 @@ A number of functions have been renamed:

The old names still exist but are deprecated.  They will be removed in the v18.07 release.

spdk_blob_resize() is now an asynchronous operation to enable resizing a blob while I/O
are in progress to that blob on other threads.  An explicit spdk_blob_sync_md() is still
required to sync the updated metadata to disk.

### Lib

A set of changes were made in the SPDK's lib code altering,
+20 −13
Original line number Diff line number Diff line
@@ -289,25 +289,13 @@ sync_cb(void *arg1, int bserrno)
	spdk_blob_close(cli_context->blob, close_cb, cli_context);
}

/*
 * Callback function for opening a blob after creating.
 */
static void
open_now_resize_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
resize_cb(void *cb_arg, int bserrno)
{
	struct cli_context_t *cli_context = cb_arg;
	int rc = 0;
	uint64_t total = 0;

	if (bserrno) {
		unload_bs(cli_context, "Error in open completion",
			  bserrno);
		return;
	}
	cli_context->blob = blob;

	rc = spdk_blob_resize(cli_context->blob, cli_context->num_clusters);
	if (rc) {
		unload_bs(cli_context, "Error in blob resize",
			  bserrno);
		return;
@@ -324,6 +312,25 @@ open_now_resize_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
	spdk_blob_sync_md(cli_context->blob, sync_cb, cli_context);
}

/*
 * Callback function for opening a blob after creating.
 */
static void
open_now_resize_cb(void *cb_arg, struct spdk_blob *blob, int bserrno)
{
	struct cli_context_t *cli_context = cb_arg;

	if (bserrno) {
		unload_bs(cli_context, "Error in open completion",
			  bserrno);
		return;
	}
	cli_context->blob = blob;

	spdk_blob_resize(cli_context->blob, cli_context->num_clusters,
			 resize_cb, cli_context);
}

/*
 * Callback function for creating a blob.
 */
+28 −23
Original line number Diff line number Diff line
@@ -266,6 +266,33 @@ sync_complete(void *arg1, int bserrno)
	blob_write(hello_context);
}

static void
resize_complete(void *cb_arg, int bserrno)
{
	struct hello_context_t *hello_context = cb_arg;
	uint64_t total = 0;

	if (bserrno) {
		unload_bs(hello_context, "Error in blob resize", bserrno);
		return;
	}

	total = spdk_blob_get_num_clusters(hello_context->blob);
	SPDK_NOTICELOG("resized blob now has USED clusters of %" PRIu64 "\n",
		       total);

	/*
	 * Metadata is stored in volatile memory for performance
	 * reasons and therefore needs to be synchronized with
	 * non-volatile storage to make it persistent. This can be
	 * done manually, as shown here, or if not it will be done
	 * automatically when the blob is closed. It is always a
	 * good idea to sync after making metadata changes unless
	 * it has an unacceptable impact on application performance.
	 */
	spdk_blob_sync_md(hello_context->blob, sync_complete, hello_context);
}

/*
 * Callback function for opening a blob.
 */
@@ -274,8 +301,6 @@ open_complete(void *cb_arg, struct spdk_blob *blob, int bserrno)
{
	struct hello_context_t *hello_context = cb_arg;
	uint64_t free = 0;
	uint64_t total = 0;
	int rc = 0;

	SPDK_NOTICELOG("entry\n");
	if (bserrno) {
@@ -297,27 +322,7 @@ open_complete(void *cb_arg, struct spdk_blob *blob, int bserrno)
	 * there'd usually be many blobs of various sizes. The resize
	 * unit is a cluster.
	 */
	rc = spdk_blob_resize(hello_context->blob, free);
	if (rc) {
		unload_bs(hello_context, "Error in blob resize",
			  bserrno);
		return;
	}

	total = spdk_blob_get_num_clusters(hello_context->blob);
	SPDK_NOTICELOG("resized blob now has USED clusters of %" PRIu64 "\n",
		       total);

	/*
	 * Metadata is stored in volatile memory for performance
	 * reasons and therefore needs to be synchronized with
	 * non-volatile storage to make it persistent. This can be
	 * done manually, as shown here, or if not it will be done
	 * automatically when the blob is closed. It is always a
	 * good idea to sync after making metadata changes unless
	 * it has an unacceptable impact on application performance.
	 */
	spdk_blob_sync_md(hello_context->blob, sync_complete, hello_context);
	spdk_blob_resize(hello_context->blob, free, resize_complete, hello_context);
}

/*
+3 −2
Original line number Diff line number Diff line
@@ -383,10 +383,11 @@ void spdk_bs_open_blob(struct spdk_blob_store *bs, spdk_blob_id blobid,
 *
 * \param blob Blob to resize.
 * \param sz The new number of clusters.
 * \param cb_fn Called when the operation is complete.
 * \param cb_arg Argument passed to function cb_fn.
 *
 * \return 0 on success, negative errno on failure.
 */
int spdk_blob_resize(struct spdk_blob *blob, size_t sz);
void spdk_blob_resize(struct spdk_blob *blob, size_t sz, spdk_blob_op_complete cb_fn, void *cb_arg);

/**
 * Set blob as read only.
+4 −2
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ struct spdk_lvol_req {
	spdk_lvol_op_complete   cb_fn;
	void                    *cb_arg;
	struct spdk_lvol	*lvol;
	size_t			sz;
	struct spdk_bdev	*bdev;
	char			name[SPDK_LVOL_NAME_MAX];
};

@@ -117,7 +119,7 @@ struct lvol_task {
struct lvol_store_bdev *vbdev_lvol_store_first(void);
struct lvol_store_bdev *vbdev_lvol_store_next(struct lvol_store_bdev *prev);

int spdk_lvol_resize(struct spdk_lvol *lvol, uint64_t sz, spdk_lvol_op_complete cb_fn,
void spdk_lvol_resize(struct spdk_lvol *lvol, uint64_t sz, spdk_lvol_op_complete cb_fn,
		      void *cb_arg);

#endif /* SPDK_INTERNAL_LVOLSTORE_H */
Loading