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: Jim Harris <james.r.harris@intel.com>
Change-Id: Ida037334739b4b80a1dbc76e8f1c70bca8b73582

Reviewed-on: https://review.gerrithub.io/404616
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Jim Harris 2018-03-19 14:05:44 -07:00 committed by Daniel Verkamp
parent 33aad6ee8d
commit 463925ff0f
12 changed files with 213 additions and 181 deletions

View File

@ -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,

View File

@ -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.
*/

View File

@ -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);
}
/*

View File

@ -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.

View File

@ -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 *cb_arg);
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 */

View File

@ -929,6 +929,16 @@ static void
_vbdev_lvol_resize_cb(void *cb_arg, int lvolerrno)
{
struct spdk_lvol_req *req = cb_arg;
uint64_t cluster_size;
int rc;
if (lvolerrno == 0) {
cluster_size = spdk_bs_get_cluster_size(req->lvol->lvol_store->blobstore);
rc = spdk_bdev_notify_blockcnt_change(req->bdev, req->sz * cluster_size / req->bdev->blocklen);
if (rc != 0) {
SPDK_ERRLOG("Could not change num blocks for bdev_lvol.\n");
}
}
req->cb_fn(req->cb_arg, lvolerrno);
free(req);
@ -941,9 +951,6 @@ vbdev_lvol_resize(char *name, size_t sz,
struct spdk_lvol_req *req;
struct spdk_bdev *bdev;
struct spdk_lvol *lvol;
struct spdk_lvol_store *lvs;
uint64_t cluster_size;
int rc;
lvol = vbdev_get_lvol_by_unique_id(name);
if (lvol == NULL) {
@ -957,9 +964,6 @@ vbdev_lvol_resize(char *name, size_t sz,
return -ENODEV;
}
lvs = lvol->lvol_store;
cluster_size = spdk_bs_get_cluster_size(lvs->blobstore);
req = calloc(1, sizeof(*req));
if (req == NULL) {
cb_fn(cb_arg, -1);
@ -967,17 +971,12 @@ vbdev_lvol_resize(char *name, size_t sz,
}
req->cb_fn = cb_fn;
req->cb_arg = cb_arg;
req->sz = sz;
req->bdev = bdev;
req->lvol = lvol;
rc = spdk_lvol_resize(lvol, sz, _vbdev_lvol_resize_cb, req);
if (rc == 0) {
rc = spdk_bdev_notify_blockcnt_change(bdev, sz * cluster_size / bdev->blocklen);
if (rc != 0) {
SPDK_ERRLOG("Could not change num blocks for bdev_lvol.\n");
}
}
return rc;
spdk_lvol_resize(lvol, sz, _vbdev_lvol_resize_cb, req);
return 0;
}
static int

View File

@ -3574,8 +3574,8 @@ void spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_
/* END spdk_bs_create_blob */
/* START spdk_blob_resize */
int
spdk_blob_resize(struct spdk_blob *blob, uint64_t sz)
void
spdk_blob_resize(struct spdk_blob *blob, uint64_t sz, spdk_blob_op_complete cb_fn, void *cb_arg)
{
int rc;
@ -3584,19 +3584,17 @@ spdk_blob_resize(struct spdk_blob *blob, uint64_t sz)
SPDK_DEBUGLOG(SPDK_LOG_BLOB, "Resizing blob %lu to %lu clusters\n", blob->id, sz);
if (blob->md_ro) {
return -EPERM;
cb_fn(cb_arg, -EPERM);
return;
}
if (sz == blob->active.num_clusters) {
return 0;
cb_fn(cb_arg, 0);
return;
}
rc = _spdk_blob_resize(blob, sz);
if (rc < 0) {
return rc;
}
return 0;
cb_fn(cb_arg, rc);
}
/* END spdk_blob_resize */

View File

@ -188,7 +188,8 @@ struct spdk_fs_cb_args {
TAILQ_ENTRY(spdk_fs_request) tailq;
} open;
struct {
const char *name;
const char *name;
struct spdk_blob *blob;
} create;
struct {
const char *name;
@ -858,20 +859,30 @@ fs_create_blob_close_cb(void *ctx, int bserrno)
}
static void
fs_create_blob_open_cb(void *ctx, struct spdk_blob *blob, int bserrno)
fs_create_blob_resize_cb(void *ctx, int bserrno)
{
struct spdk_fs_request *req = ctx;
struct spdk_fs_cb_args *args = &req->args;
struct spdk_file *f = args->file;
struct spdk_blob *blob = args->op.create.blob;
uint64_t length = 0;
spdk_blob_resize(blob, 1);
spdk_blob_set_xattr(blob, "name", f->name, strlen(f->name) + 1);
spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
spdk_blob_close(blob, fs_create_blob_close_cb, args);
}
static void
fs_create_blob_open_cb(void *ctx, struct spdk_blob *blob, int bserrno)
{
struct spdk_fs_request *req = ctx;
struct spdk_fs_cb_args *args = &req->args;
args->op.create.blob = blob;
spdk_blob_resize(blob, 1, fs_create_blob_resize_cb, req);
}
static void
fs_create_blob_create_cb(void *ctx, spdk_blob_id blobid, int bserrno)
{
@ -1404,6 +1415,24 @@ fs_truncate_complete_cb(void *ctx, int bserrno)
free_fs_request(req);
}
static void
fs_truncate_resize_cb(void *ctx, int bserrno)
{
struct spdk_fs_request *req = ctx;
struct spdk_fs_cb_args *args = &req->args;
struct spdk_file *file = args->file;
uint64_t *length = &args->op.truncate.length;
spdk_blob_set_xattr(file->blob, "length", length, sizeof(*length));
file->length = *length;
if (file->append_pos > file->length) {
file->append_pos = file->length;
}
spdk_blob_sync_md(file->blob, fs_truncate_complete_cb, args);
}
static uint64_t
__bytes_to_clusters(uint64_t length, uint64_t cluster_sz)
{
@ -1435,19 +1464,12 @@ spdk_file_truncate_async(struct spdk_file *file, uint64_t length,
args->fn.file_op = cb_fn;
args->arg = cb_arg;
args->file = file;
args->op.truncate.length = length;
fs = file->fs;
num_clusters = __bytes_to_clusters(length, fs->bs_opts.cluster_sz);
spdk_blob_resize(file->blob, num_clusters);
spdk_blob_set_xattr(file->blob, "length", &length, sizeof(length));
file->length = length;
if (file->append_pos > file->length) {
file->append_pos = file->length;
}
spdk_blob_sync_md(file->blob, fs_truncate_complete_cb, args);
spdk_blob_resize(file->blob, num_clusters, fs_truncate_resize_cb, req);
}
static void
@ -1940,15 +1962,22 @@ __file_extend_done(void *arg, int bserrno)
__wake_caller(args);
}
static void
__file_extend_resize_cb(void *_args, int bserrno)
{
struct spdk_fs_cb_args *args = _args;
struct spdk_file *file = args->file;
spdk_blob_sync_md(file->blob, __file_extend_done, args);
}
static void
__file_extend_blob(void *_args)
{
struct spdk_fs_cb_args *args = _args;
struct spdk_file *file = args->file;
spdk_blob_resize(file->blob, args->op.resize.num_clusters);
spdk_blob_sync_md(file->blob, __file_extend_done, args);
spdk_blob_resize(file->blob, args->op.resize.num_clusters, __file_extend_resize_cb, args);
}
static void

View File

@ -1088,7 +1088,7 @@ spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz,
}
static void
_spdk_lvol_resize_cb(void *cb_arg, int lvolerrno)
_spdk_lvol_resize_done(void *cb_arg, int lvolerrno)
{
struct spdk_lvol_req *req = cb_arg;
@ -1096,11 +1096,25 @@ _spdk_lvol_resize_cb(void *cb_arg, int lvolerrno)
free(req);
}
int
static void
_spdk_lvol_blob_resize_cb(void *cb_arg, int bserrno)
{
struct spdk_lvol_req *req = cb_arg;
struct spdk_lvol *lvol = req->lvol;
if (bserrno != 0) {
req->cb_fn(req->cb_arg, bserrno);
free(req);
return;
}
spdk_blob_sync_md(lvol->blob, _spdk_lvol_resize_done, req);
}
void
spdk_lvol_resize(struct spdk_lvol *lvol, uint64_t sz,
spdk_lvol_op_complete cb_fn, void *cb_arg)
{
int rc;
struct spdk_blob *blob = lvol->blob;
struct spdk_lvol_store *lvs = lvol->lvol_store;
struct spdk_lvol_req *req;
@ -1113,31 +1127,22 @@ spdk_lvol_resize(struct spdk_lvol *lvol, uint64_t sz,
/* Check if there is enough clusters left to resize */
if (new_clusters - used_clusters > free_clusters) {
SPDK_ERRLOG("Not enough free clusters left on lvol store to resize lvol to %zu clusters\n", sz);
return -ENOMEM;
cb_fn(cb_arg, -ENOMEM);
return;
}
}
req = calloc(1, sizeof(*req));
if (!req) {
SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n");
return -ENOMEM;
cb_fn(cb_arg, -ENOMEM);
return;
}
req->cb_fn = cb_fn;
req->cb_arg = cb_arg;
req->lvol = lvol;
rc = spdk_blob_resize(blob, sz);
if (rc < 0) {
goto invalid;
}
spdk_blob_sync_md(blob, _spdk_lvol_resize_cb, req);
return rc;
invalid:
req->cb_fn(req->cb_arg, rc);
free(req);
return rc;
spdk_blob_resize(blob, sz, _spdk_lvol_blob_resize_cb, req);
}
static void

View File

@ -334,12 +334,10 @@ spdk_lvs_destroy(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn,
return 0;
}
int
void
spdk_lvol_resize(struct spdk_lvol *lvol, size_t sz, spdk_lvol_op_complete cb_fn, void *cb_arg)
{
cb_fn(cb_arg, 0);
return 0;
}
int

View File

@ -590,7 +590,6 @@ blob_resize(void)
struct spdk_blob *blob;
spdk_blob_id blobid;
uint64_t free_clusters;
int rc;
dev = init_dev();
@ -613,20 +612,20 @@ blob_resize(void)
/* Confirm that resize fails if blob is marked read-only. */
blob->md_ro = true;
rc = spdk_blob_resize(blob, 5);
CU_ASSERT(rc == -EPERM);
spdk_blob_resize(blob, 5, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == -EPERM);
blob->md_ro = false;
/* The blob started at 0 clusters. Resize it to be 5. */
rc = spdk_blob_resize(blob, 5);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 5, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
/* Shrink the blob to 3 clusters. This will not actually release
* the old clusters until the blob is synced.
*/
rc = spdk_blob_resize(blob, 3);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 3, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
/* Verify there are still 5 clusters in use */
CU_ASSERT((free_clusters - 5) == spdk_bs_free_cluster_count(bs));
@ -636,13 +635,13 @@ blob_resize(void)
CU_ASSERT((free_clusters - 3) == spdk_bs_free_cluster_count(bs));
/* Resize the blob to be 10 clusters. Growth takes effect immediately. */
rc = spdk_blob_resize(blob, 10);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 10, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT((free_clusters - 10) == spdk_bs_free_cluster_count(bs));
/* Try to resize the blob to size larger than blobstore. */
rc = spdk_blob_resize(blob, bs->total_clusters + 1);
CU_ASSERT(rc == -ENOSPC);
spdk_blob_resize(blob, bs->total_clusters + 1, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == -ENOSPC);
spdk_blob_close(blob, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
@ -775,7 +774,6 @@ blob_write(void)
spdk_blob_id blobid;
uint64_t pages_per_cluster;
uint8_t payload[10 * 4096];
int rc;
dev = init_dev();
@ -804,8 +802,8 @@ blob_write(void)
CU_ASSERT(g_bserrno == -EINVAL);
/* Resize the blob */
rc = spdk_blob_resize(blob, 5);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 5, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
/* Confirm that write fails if blob is marked read-only. */
blob->data_ro = true;
@ -847,7 +845,6 @@ blob_read(void)
spdk_blob_id blobid;
uint64_t pages_per_cluster;
uint8_t payload[10 * 4096];
int rc;
dev = init_dev();
@ -876,8 +873,8 @@ blob_read(void)
CU_ASSERT(g_bserrno == -EINVAL);
/* Resize the blob */
rc = spdk_blob_resize(blob, 5);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 5, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
/* Confirm that read passes if blob is marked read-only. */
blob->data_ro = true;
@ -919,7 +916,6 @@ blob_rw_verify(void)
spdk_blob_id blobid;
uint8_t payload_read[10 * 4096];
uint8_t payload_write[10 * 4096];
int rc;
dev = init_dev();
@ -941,8 +937,8 @@ blob_rw_verify(void)
CU_ASSERT(g_blob != NULL);
blob = g_blob;
rc = spdk_blob_resize(blob, 32);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 32, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
memset(payload_write, 0xE5, sizeof(payload_write));
spdk_blob_io_write(blob, channel, payload_write, 4, 10, blob_op_complete, NULL);
@ -976,7 +972,6 @@ blob_rw_verify_iov(void)
struct iovec iov_read[3];
struct iovec iov_write[3];
void *buf;
int rc;
dev = init_dev();
memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
@ -999,8 +994,8 @@ blob_rw_verify_iov(void)
SPDK_CU_ASSERT_FATAL(g_blob != NULL);
blob = g_blob;
rc = spdk_blob_resize(blob, 2);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 2, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
/*
* Manually adjust the offset of the blob's second cluster. This allows
@ -1078,7 +1073,6 @@ blob_rw_verify_iov_nomem(void)
uint8_t payload_write[10 * 4096];
struct iovec iov_write[3];
uint32_t req_count;
int rc;
dev = init_dev();
memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
@ -1101,8 +1095,8 @@ blob_rw_verify_iov_nomem(void)
CU_ASSERT(g_blob != NULL);
blob = g_blob;
rc = spdk_blob_resize(blob, 2);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 2, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
/*
* Choose a page offset just before the cluster boundary. The first 6 pages of payload
@ -1143,7 +1137,6 @@ blob_rw_iov_read_only(void)
uint8_t payload_write[4096];
struct iovec iov_read;
struct iovec iov_write;
int rc;
dev = init_dev();
memset(g_dev_buffer, 0, DEV_BUFFER_SIZE);
@ -1166,8 +1159,8 @@ blob_rw_iov_read_only(void)
SPDK_CU_ASSERT_FATAL(g_blob != NULL);
blob = g_blob;
rc = spdk_blob_resize(blob, 2);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 2, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
/* Verify that writev failed if read_only flag is set. */
blob->data_ro = true;
@ -1202,7 +1195,6 @@ blob_unmap(void)
spdk_blob_id blobid;
struct spdk_blob_opts opts;
uint8_t payload[4096];
int rc;
int i;
dev = init_dev();
@ -1228,8 +1220,8 @@ blob_unmap(void)
SPDK_CU_ASSERT_FATAL(g_blob != NULL);
blob = g_blob;
rc = spdk_blob_resize(blob, 10);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 10, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
memset(payload, 0, sizeof(payload));
payload[0] = 0xFF;
@ -1259,8 +1251,8 @@ blob_unmap(void)
blob->active.clusters[8] = 0;
/* Unmap clusters by resizing to 0 */
rc = spdk_blob_resize(blob, 0);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 0, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
spdk_blob_sync_md(blob, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
@ -1522,8 +1514,8 @@ bs_load(void)
CU_ASSERT(rc == 0);
/* Resize the blob */
rc = spdk_blob_resize(blob, 10);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 10, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
spdk_blob_close(blob, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
@ -1865,7 +1857,7 @@ bs_usable_clusters(void)
struct spdk_bs_dev *dev;
struct spdk_bs_opts opts;
uint32_t clusters;
int i, rc;
int i;
/* Init blobstore */
dev = init_dev();
@ -1904,8 +1896,8 @@ bs_usable_clusters(void)
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(g_blob != NULL);
rc = spdk_blob_resize(g_blob, 10);
CU_ASSERT(rc == 0);
spdk_blob_resize(g_blob, 10, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
g_bserrno = -1;
spdk_blob_close(g_blob, blob_op_complete, NULL);
@ -2082,8 +2074,8 @@ blob_serialize(void)
* over of the extents.
*/
for (i = 0; i < 6; i++) {
rc = spdk_blob_resize(blob[i % 2], (i / 2) + 1);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob[i % 2], (i / 2) + 1, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
}
for (i = 0; i < 2; i++) {
@ -2265,8 +2257,8 @@ blob_dirty_shutdown(void)
CU_ASSERT(rc == 0);
/* Resize the blob */
rc = spdk_blob_resize(blob, 10);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 10, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
/* Set the blob as the super blob */
spdk_bs_set_super(g_bs, blobid1, blob_op_complete, NULL);
@ -2310,8 +2302,8 @@ blob_dirty_shutdown(void)
CU_ASSERT(spdk_blob_get_num_clusters(blob) == 10);
/* Resize the blob */
rc = spdk_blob_resize(blob, 20);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 20, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
free_clusters = spdk_bs_free_cluster_count(g_bs);
@ -2364,8 +2356,8 @@ blob_dirty_shutdown(void)
CU_ASSERT(rc == 0);
/* Resize the blob */
rc = spdk_blob_resize(blob, 10);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 10, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
free_clusters = spdk_bs_free_cluster_count(g_bs);
@ -2571,8 +2563,8 @@ blob_flags(void)
/* Change the size of blob_data_ro to check if flags are serialized
* when blob has non zero number of extents */
rc = spdk_blob_resize(blob_data_ro, 10);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob_data_ro, 10, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
/* Set the xattr to check if flags are serialized
* when blob has non zero number of xattrs */
@ -2855,7 +2847,6 @@ blob_thin_prov_alloc(void)
struct spdk_blob_opts opts;
spdk_blob_id blobid;
uint64_t free_clusters;
int rc;
dev = init_dev();
@ -2884,15 +2875,15 @@ blob_thin_prov_alloc(void)
CU_ASSERT(spdk_blob_get_num_clusters(blob) == 0);
/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
rc = spdk_blob_resize(blob, 5);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 5, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
CU_ASSERT(blob->active.num_clusters == 5);
CU_ASSERT(spdk_blob_get_num_clusters(blob) == 5);
/* Shrink the blob to 3 clusters - still unallocated */
rc = spdk_blob_resize(blob, 3);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 3, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
CU_ASSERT(blob->active.num_clusters == 3);
CU_ASSERT(spdk_blob_get_num_clusters(blob) == 3);
@ -3034,7 +3025,6 @@ blob_thin_prov_rw(void)
uint64_t free_clusters;
uint8_t payload_read[10 * 4096];
uint8_t payload_write[10 * 4096];
int rc;
dev = init_dev();
@ -3064,8 +3054,8 @@ blob_thin_prov_rw(void)
CU_ASSERT(blob->active.num_clusters == 0);
/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
rc = spdk_blob_resize(blob, 5);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 5, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
CU_ASSERT(blob->active.num_clusters == 5);
@ -3123,8 +3113,6 @@ blob_thin_prov_rw_iov(void)
struct iovec iov_read[3];
struct iovec iov_write[3];
int rc;
dev = init_dev();
spdk_bs_init(dev, NULL, bs_op_with_handle_complete, NULL);
@ -3153,8 +3141,8 @@ blob_thin_prov_rw_iov(void)
CU_ASSERT(blob->active.num_clusters == 0);
/* The blob started at 0 clusters. Resize it to be 5, but still unallocated. */
rc = spdk_blob_resize(blob, 5);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, 5, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(free_clusters == spdk_bs_free_cluster_count(bs));
CU_ASSERT(blob->active.num_clusters == 5);
@ -3265,8 +3253,8 @@ bs_load_iter(void)
CU_ASSERT(rc == 0);
/* Resize the blob */
rc = spdk_blob_resize(blob, i);
CU_ASSERT(rc == 0);
spdk_blob_resize(blob, i, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
spdk_blob_close(blob, blob_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);

View File

@ -321,15 +321,15 @@ void spdk_blob_close(struct spdk_blob *b, spdk_blob_op_complete cb_fn, void *cb_
cb_fn(cb_arg, b->close_status);
}
int
spdk_blob_resize(struct spdk_blob *blob, uint64_t sz)
void
spdk_blob_resize(struct spdk_blob *blob, uint64_t sz, spdk_blob_op_complete cb_fn, void *cb_arg)
{
if (g_resize_rc != 0) {
return g_resize_rc;
return cb_fn(cb_arg, g_resize_rc);
} else if (sz > DEV_BUFFER_SIZE / BS_CLUSTER_SIZE) {
return -1;
return cb_fn(cb_arg, -ENOMEM);
}
return 0;
cb_fn(cb_arg, 0);
}
void
@ -927,34 +927,30 @@ lvol_resize(void)
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
/* Resize to same size */
rc = spdk_lvol_resize(g_lvol, 10, lvol_store_op_complete, NULL);
CU_ASSERT(rc == 0);
spdk_lvol_resize(g_lvol, 10, lvol_store_op_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
/* Resize to smaller size */
rc = spdk_lvol_resize(g_lvol, 5, lvol_store_op_complete, NULL);
CU_ASSERT(rc == 0);
spdk_lvol_resize(g_lvol, 5, lvol_store_op_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
/* Resize to bigger size */
rc = spdk_lvol_resize(g_lvol, 15, lvol_store_op_complete, NULL);
CU_ASSERT(rc == 0);
spdk_lvol_resize(g_lvol, 15, lvol_store_op_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
/* Resize to size = 0 */
rc = spdk_lvol_resize(g_lvol, 0, lvol_store_op_complete, NULL);
CU_ASSERT(rc == 0);
spdk_lvol_resize(g_lvol, 0, lvol_store_op_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
/* Resize to bigger size than available */
rc = spdk_lvol_resize(g_lvol, 0xFFFFFFFF, lvol_store_op_complete, NULL);
CU_ASSERT(rc != 0);
g_lvserrno = 0;
spdk_lvol_resize(g_lvol, 0xFFFFFFFF, lvol_store_op_complete, NULL);
CU_ASSERT(g_lvserrno != 0);
/* Fail resize */
g_resize_rc = -1;
g_lvserrno = 0;
rc = spdk_lvol_resize(g_lvol, 10, lvol_store_op_complete, NULL);
CU_ASSERT(rc != 0);
spdk_lvol_resize(g_lvol, 10, lvol_store_op_complete, NULL);
CU_ASSERT(g_lvserrno != 0);
g_resize_rc = 0;