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. 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 ### Lib
A set of changes were made in the SPDK's lib code altering, 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); spdk_blob_close(cli_context->blob, close_cb, cli_context);
} }
/*
* Callback function for opening a blob after creating.
*/
static void 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; struct cli_context_t *cli_context = cb_arg;
int rc = 0;
uint64_t total = 0; uint64_t total = 0;
if (bserrno) { 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", unload_bs(cli_context, "Error in blob resize",
bserrno); bserrno);
return; 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); 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. * Callback function for creating a blob.
*/ */

View File

@ -266,6 +266,33 @@ sync_complete(void *arg1, int bserrno)
blob_write(hello_context); 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. * 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; struct hello_context_t *hello_context = cb_arg;
uint64_t free = 0; uint64_t free = 0;
uint64_t total = 0;
int rc = 0;
SPDK_NOTICELOG("entry\n"); SPDK_NOTICELOG("entry\n");
if (bserrno) { 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 * there'd usually be many blobs of various sizes. The resize
* unit is a cluster. * unit is a cluster.
*/ */
rc = spdk_blob_resize(hello_context->blob, free); spdk_blob_resize(hello_context->blob, free, resize_complete, hello_context);
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);
} }
/* /*

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 blob Blob to resize.
* \param sz The new number of clusters. * \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. * Set blob as read only.

View File

@ -53,6 +53,8 @@ struct spdk_lvol_req {
spdk_lvol_op_complete cb_fn; spdk_lvol_op_complete cb_fn;
void *cb_arg; void *cb_arg;
struct spdk_lvol *lvol; struct spdk_lvol *lvol;
size_t sz;
struct spdk_bdev *bdev;
char name[SPDK_LVOL_NAME_MAX]; 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_first(void);
struct lvol_store_bdev *vbdev_lvol_store_next(struct lvol_store_bdev *prev); 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); void *cb_arg);
#endif /* SPDK_INTERNAL_LVOLSTORE_H */ #endif /* SPDK_INTERNAL_LVOLSTORE_H */

View File

@ -929,6 +929,16 @@ static void
_vbdev_lvol_resize_cb(void *cb_arg, int lvolerrno) _vbdev_lvol_resize_cb(void *cb_arg, int lvolerrno)
{ {
struct spdk_lvol_req *req = cb_arg; 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); req->cb_fn(req->cb_arg, lvolerrno);
free(req); free(req);
@ -941,9 +951,6 @@ vbdev_lvol_resize(char *name, size_t sz,
struct spdk_lvol_req *req; struct spdk_lvol_req *req;
struct spdk_bdev *bdev; struct spdk_bdev *bdev;
struct spdk_lvol *lvol; struct spdk_lvol *lvol;
struct spdk_lvol_store *lvs;
uint64_t cluster_size;
int rc;
lvol = vbdev_get_lvol_by_unique_id(name); lvol = vbdev_get_lvol_by_unique_id(name);
if (lvol == NULL) { if (lvol == NULL) {
@ -957,9 +964,6 @@ vbdev_lvol_resize(char *name, size_t sz,
return -ENODEV; return -ENODEV;
} }
lvs = lvol->lvol_store;
cluster_size = spdk_bs_get_cluster_size(lvs->blobstore);
req = calloc(1, sizeof(*req)); req = calloc(1, sizeof(*req));
if (req == NULL) { if (req == NULL) {
cb_fn(cb_arg, -1); cb_fn(cb_arg, -1);
@ -967,17 +971,12 @@ vbdev_lvol_resize(char *name, size_t sz,
} }
req->cb_fn = cb_fn; req->cb_fn = cb_fn;
req->cb_arg = cb_arg; 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); spdk_lvol_resize(lvol, sz, _vbdev_lvol_resize_cb, req);
return 0;
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;
} }
static int 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 */ /* END spdk_bs_create_blob */
/* START spdk_blob_resize */ /* START spdk_blob_resize */
int void
spdk_blob_resize(struct spdk_blob *blob, uint64_t sz) spdk_blob_resize(struct spdk_blob *blob, uint64_t sz, spdk_blob_op_complete cb_fn, void *cb_arg)
{ {
int rc; 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); SPDK_DEBUGLOG(SPDK_LOG_BLOB, "Resizing blob %lu to %lu clusters\n", blob->id, sz);
if (blob->md_ro) { if (blob->md_ro) {
return -EPERM; cb_fn(cb_arg, -EPERM);
return;
} }
if (sz == blob->active.num_clusters) { if (sz == blob->active.num_clusters) {
return 0; cb_fn(cb_arg, 0);
return;
} }
rc = _spdk_blob_resize(blob, sz); rc = _spdk_blob_resize(blob, sz);
if (rc < 0) { cb_fn(cb_arg, rc);
return rc;
}
return 0;
} }
/* END spdk_blob_resize */ /* END spdk_blob_resize */

View File

@ -188,7 +188,8 @@ struct spdk_fs_cb_args {
TAILQ_ENTRY(spdk_fs_request) tailq; TAILQ_ENTRY(spdk_fs_request) tailq;
} open; } open;
struct { struct {
const char *name; const char *name;
struct spdk_blob *blob;
} create; } create;
struct { struct {
const char *name; const char *name;
@ -858,20 +859,30 @@ fs_create_blob_close_cb(void *ctx, int bserrno)
} }
static void 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_request *req = ctx;
struct spdk_fs_cb_args *args = &req->args; struct spdk_fs_cb_args *args = &req->args;
struct spdk_file *f = args->file; struct spdk_file *f = args->file;
struct spdk_blob *blob = args->op.create.blob;
uint64_t length = 0; 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, "name", f->name, strlen(f->name) + 1);
spdk_blob_set_xattr(blob, "length", &length, sizeof(length)); spdk_blob_set_xattr(blob, "length", &length, sizeof(length));
spdk_blob_close(blob, fs_create_blob_close_cb, args); 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 static void
fs_create_blob_create_cb(void *ctx, spdk_blob_id blobid, int bserrno) 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); 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 static uint64_t
__bytes_to_clusters(uint64_t length, uint64_t cluster_sz) __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->fn.file_op = cb_fn;
args->arg = cb_arg; args->arg = cb_arg;
args->file = file; args->file = file;
args->op.truncate.length = length;
fs = file->fs; fs = file->fs;
num_clusters = __bytes_to_clusters(length, fs->bs_opts.cluster_sz); num_clusters = __bytes_to_clusters(length, fs->bs_opts.cluster_sz);
spdk_blob_resize(file->blob, num_clusters); spdk_blob_resize(file->blob, num_clusters, fs_truncate_resize_cb, req);
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 void static void
@ -1940,15 +1962,22 @@ __file_extend_done(void *arg, int bserrno)
__wake_caller(args); __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 static void
__file_extend_blob(void *_args) __file_extend_blob(void *_args)
{ {
struct spdk_fs_cb_args *args = _args; struct spdk_fs_cb_args *args = _args;
struct spdk_file *file = args->file; struct spdk_file *file = args->file;
spdk_blob_resize(file->blob, args->op.resize.num_clusters); spdk_blob_resize(file->blob, args->op.resize.num_clusters, __file_extend_resize_cb, args);
spdk_blob_sync_md(file->blob, __file_extend_done, args);
} }
static void static void

View File

@ -1088,7 +1088,7 @@ spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz,
} }
static void 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; struct spdk_lvol_req *req = cb_arg;
@ -1096,11 +1096,25 @@ _spdk_lvol_resize_cb(void *cb_arg, int lvolerrno)
free(req); 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_resize(struct spdk_lvol *lvol, uint64_t sz,
spdk_lvol_op_complete cb_fn, void *cb_arg) spdk_lvol_op_complete cb_fn, void *cb_arg)
{ {
int rc;
struct spdk_blob *blob = lvol->blob; struct spdk_blob *blob = lvol->blob;
struct spdk_lvol_store *lvs = lvol->lvol_store; struct spdk_lvol_store *lvs = lvol->lvol_store;
struct spdk_lvol_req *req; 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 */ /* Check if there is enough clusters left to resize */
if (new_clusters - used_clusters > free_clusters) { 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); 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)); req = calloc(1, sizeof(*req));
if (!req) { if (!req) {
SPDK_ERRLOG("Cannot alloc memory for lvol request pointer\n"); 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_fn = cb_fn;
req->cb_arg = cb_arg; req->cb_arg = cb_arg;
req->lvol = lvol;
rc = spdk_blob_resize(blob, sz); spdk_blob_resize(blob, sz, _spdk_lvol_blob_resize_cb, req);
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;
} }
static void static void

View File

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

View File

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