blob: check if resize failed
This patch provides logic for returning errors instead of assert when size is larger than blobstore size. Signed-off-by: Piotr Pelplinski <piotr.pelplinski@intel.com> Change-Id: I16d12338e2b682c39bd33d507d57ea126501a0d7 Reviewed-on: https://review.gerrithub.io/392749 Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
21ec62533d
commit
b9252b1272
@ -997,6 +997,7 @@ _spdk_resize_blob(struct spdk_blob_data *blob, uint64_t sz)
|
|||||||
uint64_t i;
|
uint64_t i;
|
||||||
uint64_t *tmp;
|
uint64_t *tmp;
|
||||||
uint64_t lfc; /* lowest free cluster */
|
uint64_t lfc; /* lowest free cluster */
|
||||||
|
uint64_t num_clusters;
|
||||||
struct spdk_blob_store *bs;
|
struct spdk_blob_store *bs;
|
||||||
|
|
||||||
bs = blob->bs;
|
bs = blob->bs;
|
||||||
@ -1013,42 +1014,42 @@ _spdk_resize_blob(struct spdk_blob_data *blob, uint64_t sz)
|
|||||||
* larger without syncing, then the cluster array already
|
* larger without syncing, then the cluster array already
|
||||||
* contains spare assigned clusters we can use.
|
* contains spare assigned clusters we can use.
|
||||||
*/
|
*/
|
||||||
blob->active.num_clusters = spdk_min(blob->active.cluster_array_size,
|
num_clusters = spdk_min(blob->active.cluster_array_size,
|
||||||
sz);
|
sz);
|
||||||
|
} else {
|
||||||
|
num_clusters = blob->active.num_clusters;
|
||||||
}
|
}
|
||||||
|
|
||||||
blob->state = SPDK_BLOB_STATE_DIRTY;
|
|
||||||
|
|
||||||
/* Do two passes - one to verify that we can obtain enough clusters
|
/* Do two passes - one to verify that we can obtain enough clusters
|
||||||
* and another to actually claim them.
|
* and another to actually claim them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
lfc = 0;
|
lfc = 0;
|
||||||
for (i = blob->active.num_clusters; i < sz; i++) {
|
for (i = num_clusters; i < sz; i++) {
|
||||||
lfc = spdk_bit_array_find_first_clear(bs->used_clusters, lfc);
|
lfc = spdk_bit_array_find_first_clear(bs->used_clusters, lfc);
|
||||||
if (lfc >= bs->total_clusters) {
|
if (lfc >= bs->total_clusters) {
|
||||||
/* No more free clusters. Cannot satisfy the request */
|
/* No more free clusters. Cannot satisfy the request */
|
||||||
assert(false);
|
return -ENOSPC;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
lfc++;
|
lfc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sz > blob->active.num_clusters) {
|
if (sz > num_clusters) {
|
||||||
/* Expand the cluster array if necessary.
|
/* Expand the cluster array if necessary.
|
||||||
* We only shrink the array when persisting.
|
* We only shrink the array when persisting.
|
||||||
*/
|
*/
|
||||||
tmp = realloc(blob->active.clusters, sizeof(uint64_t) * sz);
|
tmp = realloc(blob->active.clusters, sizeof(uint64_t) * sz);
|
||||||
if (sz > 0 && tmp == NULL) {
|
if (sz > 0 && tmp == NULL) {
|
||||||
assert(false);
|
return -ENOMEM;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
blob->active.clusters = tmp;
|
blob->active.clusters = tmp;
|
||||||
blob->active.cluster_array_size = sz;
|
blob->active.cluster_array_size = sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blob->state = SPDK_BLOB_STATE_DIRTY;
|
||||||
|
|
||||||
lfc = 0;
|
lfc = 0;
|
||||||
for (i = blob->active.num_clusters; i < sz; i++) {
|
for (i = num_clusters; i < sz; i++) {
|
||||||
lfc = spdk_bit_array_find_first_clear(bs->used_clusters, lfc);
|
lfc = spdk_bit_array_find_first_clear(bs->used_clusters, lfc);
|
||||||
SPDK_DEBUGLOG(SPDK_LOG_BLOB, "Claiming cluster %lu for blob %lu\n", lfc, blob->id);
|
SPDK_DEBUGLOG(SPDK_LOG_BLOB, "Claiming cluster %lu for blob %lu\n", lfc, blob->id);
|
||||||
_spdk_bs_claim_cluster(bs, lfc);
|
_spdk_bs_claim_cluster(bs, lfc);
|
||||||
@ -2792,7 +2793,13 @@ void spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_
|
|||||||
if (opts->thin_provision) {
|
if (opts->thin_provision) {
|
||||||
_spdk_blob_set_thin_provision(blob);
|
_spdk_blob_set_thin_provision(blob);
|
||||||
}
|
}
|
||||||
spdk_blob_resize(__data_to_blob(blob), opts->num_clusters);
|
|
||||||
|
rc = spdk_blob_resize(__data_to_blob(blob), opts->num_clusters);
|
||||||
|
if (rc < 0) {
|
||||||
|
_spdk_blob_free(blob);
|
||||||
|
cb_fn(cb_arg, 0, rc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
cpl.type = SPDK_BS_CPL_TYPE_BLOBID;
|
cpl.type = SPDK_BS_CPL_TYPE_BLOBID;
|
||||||
cpl.u.blobid.cb_fn = cb_fn;
|
cpl.u.blobid.cb_fn = cb_fn;
|
||||||
cpl.u.blobid.cb_arg = cb_arg;
|
cpl.u.blobid.cb_arg = cb_arg;
|
||||||
|
@ -338,6 +338,14 @@ blob_create(void)
|
|||||||
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);
|
||||||
|
|
||||||
|
/* Try to create blob with size larger than blobstore */
|
||||||
|
|
||||||
|
spdk_blob_opts_init(&opts);
|
||||||
|
opts.num_clusters = bs->total_clusters + 1;
|
||||||
|
|
||||||
|
spdk_bs_create_blob_ext(bs, &opts, blob_op_with_id_complete, NULL);
|
||||||
|
CU_ASSERT(g_bserrno == -ENOSPC);
|
||||||
|
|
||||||
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
spdk_bs_unload(g_bs, bs_op_complete, NULL);
|
||||||
CU_ASSERT(g_bserrno == 0);
|
CU_ASSERT(g_bserrno == 0);
|
||||||
g_bs = NULL;
|
g_bs = NULL;
|
||||||
@ -502,6 +510,10 @@ blob_resize(void)
|
|||||||
CU_ASSERT(rc == 0);
|
CU_ASSERT(rc == 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. */
|
||||||
|
rc = spdk_blob_resize(blob, bs->total_clusters + 1);
|
||||||
|
CU_ASSERT(rc == -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user