lvol: enable creation of thin provisioned lvols

Signed-off-by: Maciej Szwed <maciej.szwed@intel.com>
Change-Id: Ie6a651d0238d09729e28d5456a84ba090faeb465
Reviewed-on: https://review.gerrithub.io/391568
Reviewed-by: Jim Harris <james.r.harris@intel.com>
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:
Maciej Szwed 2018-01-26 14:33:27 +01:00 committed by Ben Walker
parent 9103821d3e
commit 9ed6bedd3e
9 changed files with 118 additions and 31 deletions

View File

@ -143,12 +143,13 @@ int spdk_lvs_destroy(struct spdk_lvol_store *lvol_store,
* \param lvs Handle to lvolstore
* \param name Name of lvol
* \param sz size of lvol in bytes
* \param thin_provisioned Enables thin provisioning
* \param cb_fn Completion callback
* \param cb_arg Completion callback custom arguments
* \return error
*/
int spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz,
spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg);
bool thin_provisioned, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg);
/**
* \brief Closes lvol and removes information about lvol from its lvolstore.

View File

@ -725,7 +725,7 @@ end:
int
vbdev_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz,
spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
bool thin_provision, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
{
struct spdk_lvol_with_handle_req *req;
int rc;
@ -737,7 +737,7 @@ vbdev_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz,
req->cb_fn = cb_fn;
req->cb_arg = cb_arg;
rc = spdk_lvol_create(lvs, name, sz, _vbdev_lvol_create_cb, req);
rc = spdk_lvol_create(lvs, name, sz, thin_provision, _vbdev_lvol_create_cb, req);
if (rc != 0) {
free(req);
}

View File

@ -53,8 +53,7 @@ void vbdev_lvs_destruct(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn,
void vbdev_lvs_unload(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg);
int vbdev_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz,
spdk_lvol_op_with_handle_complete cb_fn,
void *cb_arg);
bool thin_provisioned, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg);
int vbdev_lvol_resize(char *name, size_t sz, spdk_lvol_op_complete cb_fn, void *cb_arg);

View File

@ -248,6 +248,7 @@ struct rpc_construct_lvol_bdev {
char *lvs_name;
char *lvol_name;
uint64_t size;
bool thin_provision;
};
static void
@ -263,6 +264,7 @@ static const struct spdk_json_object_decoder rpc_construct_lvol_bdev_decoders[]
{"lvs_name", offsetof(struct rpc_construct_lvol_bdev, lvs_name), spdk_json_decode_string, true},
{"lvol_name", offsetof(struct rpc_construct_lvol_bdev, lvol_name), spdk_json_decode_string, true},
{"size", offsetof(struct rpc_construct_lvol_bdev, size), spdk_json_decode_uint64},
{"thin_provision", offsetof(struct rpc_construct_lvol_bdev, thin_provision), spdk_json_decode_bool, true},
};
static void
@ -323,7 +325,8 @@ spdk_rpc_construct_lvol_bdev(struct spdk_jsonrpc_request *request,
sz = (size_t)req.size;
rc = vbdev_lvol_create(lvs, req.lvol_name, sz, _spdk_rpc_construct_lvol_bdev_cb, request);
rc = vbdev_lvol_create(lvs, req.lvol_name, sz, req.thin_provision,
_spdk_rpc_construct_lvol_bdev_cb, request);
if (rc < 0) {
goto invalid;
}

View File

@ -936,11 +936,12 @@ _spdk_lvol_create_cb(void *cb_arg, spdk_blob_id blobid, int lvolerrno)
int
spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz,
spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
bool thin_provision, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
{
struct spdk_lvol_with_handle_req *req;
struct spdk_blob_store *bs;
struct spdk_lvol *lvol, *tmp;
struct spdk_blob_opts opts;
uint64_t num_clusters, free_clusters;
if (lvs == NULL) {
@ -996,7 +997,10 @@ spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, uint64_t sz,
strncpy(lvol->name, name, SPDK_LVS_NAME_MAX);
req->lvol = lvol;
spdk_bs_create_blob(lvs->blobstore, _spdk_lvol_create_cb, req);
spdk_blob_opts_init(&opts);
opts.thin_provision = thin_provision;
spdk_bs_create_blob_ext(lvs->blobstore, &opts, _spdk_lvol_create_cb, req);
return 0;
}

View File

@ -258,6 +258,7 @@ if __name__ == "__main__":
p = subparsers.add_parser('construct_lvol_bdev', help='Add a bdev with an logical volume backend')
p.add_argument('-u', '--uuid', help='lvol store UUID', required=False)
p.add_argument('-l', '--lvs_name', help='lvol store name', required=False)
p.add_argument('-t', '--thin-provision', action='store_true', help='create lvol bdev as thin provisioned')
p.add_argument('lvol_name', help='name for this lvol')
p.add_argument('size', help='size in MiB for this bdev', type=int)
p.set_defaults(func=rpc.lvol.construct_lvol_bdev)

View File

@ -11,6 +11,8 @@ def construct_lvol_store(args):
def construct_lvol_bdev(args):
num_bytes = (args.size * 1024 * 1024)
params = {'lvol_name': args.lvol_name, 'size': num_bytes}
if args.thin_provision:
params['thin_provision'] = args.thin_provision
if (args.uuid and args.lvs_name) or (not args.uuid and not args.lvs_name):
print("You need to specify either uuid or name of lvolstore")
else:

View File

@ -460,7 +460,7 @@ _lvol_create(struct spdk_lvol_store *lvs)
int
spdk_lvol_create(struct spdk_lvol_store *lvs, const char *name, size_t sz,
spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
bool thin_provision, spdk_lvol_op_with_handle_complete cb_fn, void *cb_arg)
{
struct spdk_lvol *lvol;
@ -519,7 +519,7 @@ ut_lvs_destroy(void)
/* Suuccessfully create lvol, which should be unloaded with lvs later */
g_lvolerrno = -1;
rc = vbdev_lvol_create(lvs, "lvol", sz, vbdev_lvol_create_complete, NULL);
rc = vbdev_lvol_create(lvs, "lvol", sz, false, vbdev_lvol_create_complete, NULL);
CU_ASSERT(rc == 0);
CU_ASSERT(g_lvolerrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -553,7 +553,7 @@ ut_lvol_init(void)
/* Successful lvol create */
g_lvolerrno = -1;
rc = vbdev_lvol_create(g_lvs, "lvol", sz, vbdev_lvol_create_complete, NULL);
rc = vbdev_lvol_create(g_lvs, "lvol", sz, false, vbdev_lvol_create_complete, NULL);
SPDK_CU_ASSERT_FATAL(rc == 0);
CU_ASSERT(g_lvol != NULL);
CU_ASSERT(g_lvolerrno == 0);
@ -703,7 +703,7 @@ ut_lvol_resize(void)
/* Successful lvol create */
g_lvolerrno = -1;
rc = vbdev_lvol_create(g_lvs, "lvol", sz, vbdev_lvol_create_complete, NULL);
rc = vbdev_lvol_create(g_lvs, "lvol", sz, false, vbdev_lvol_create_complete, NULL);
CU_ASSERT(rc == 0);
CU_ASSERT(g_lvolerrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -761,7 +761,7 @@ ut_lvs_unload(void)
/* Suuccessfully create lvol, which should be destroyed with lvs later */
g_lvolerrno = -1;
rc = vbdev_lvol_create(lvs, "lvol", sz, vbdev_lvol_create_complete, NULL);
rc = vbdev_lvol_create(lvs, "lvol", sz, false, vbdev_lvol_create_complete, NULL);
CU_ASSERT(rc == 0);
CU_ASSERT(g_lvolerrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);

View File

@ -52,6 +52,8 @@
#define SPDK_BLOB_OPTS_MAX_MD_OPS 32
#define SPDK_BLOB_OPTS_MAX_CHANNEL_OPS 512
#define SPDK_BLOB_THIN_PROV (1ULL << 0)
const char *uuid = "828d9766-ae50-11e7-bd8d-001e67edf350";
struct spdk_blob {
@ -63,6 +65,7 @@ struct spdk_blob {
TAILQ_ENTRY(spdk_blob) link;
char uuid[UUID_STRING_LEN];
char name[SPDK_LVS_NAME_MAX];
bool thin_provisioned;
};
int g_lvolerrno;
@ -352,9 +355,27 @@ spdk_bs_free_cluster_count(struct spdk_blob_store *bs)
return BS_FREE_CLUSTERS;
}
void
spdk_blob_opts_init(struct spdk_blob_opts *opts)
{
opts->num_clusters = 0;
opts->thin_provision = false;
opts->xattr_count = 0;
opts->xattr_names = NULL;
opts->xattr_ctx = NULL;
opts->get_xattr_value = NULL;
}
void
spdk_bs_create_blob(struct spdk_blob_store *bs,
spdk_blob_op_with_id_complete cb_fn, void *cb_arg)
{
spdk_bs_create_blob_ext(bs, NULL, cb_fn, cb_arg);
}
void
spdk_bs_create_blob_ext(struct spdk_blob_store *bs, const struct spdk_blob_opts *opts,
spdk_blob_op_with_id_complete cb_fn, void *cb_arg)
{
struct spdk_blob *b;
@ -362,6 +383,9 @@ spdk_bs_create_blob(struct spdk_blob_store *bs,
SPDK_CU_ASSERT_FATAL(b != NULL);
b->id = g_blobid++;
if (opts != NULL && opts->thin_provision) {
b->thin_provisioned = true;
}
TAILQ_INSERT_TAIL(&bs->blobs, b, link);
cb_fn(cb_arg, b->id, 0);
@ -433,7 +457,7 @@ lvs_init_unload_success(void)
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
CU_ASSERT(!TAILQ_EMPTY(&g_lvol_stores));
spdk_lvol_create(g_lvol_store, "lvol", 10, lvol_op_with_handle_complete, NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -481,7 +505,7 @@ lvs_init_destroy_success(void)
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, lvol_op_with_handle_complete, NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -683,7 +707,7 @@ lvol_create_destroy_success(void)
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, lvol_op_with_handle_complete, NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -728,11 +752,11 @@ lvol_create_fail(void)
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
g_lvol = NULL;
rc = spdk_lvol_create(NULL, "lvol", 10, lvol_op_with_handle_complete, NULL);
rc = spdk_lvol_create(NULL, "lvol", 10, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(rc != 0);
CU_ASSERT(g_lvol == NULL);
rc = spdk_lvol_create(g_lvol_store, "lvol", DEV_BUFFER_SIZE + 1,
rc = spdk_lvol_create(g_lvol_store, "lvol", DEV_BUFFER_SIZE + 1, false,
lvol_op_with_handle_complete, NULL);
CU_ASSERT(rc != 0);
CU_ASSERT(g_lvol == NULL);
@ -767,7 +791,7 @@ lvol_destroy_fail(void)
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, lvol_op_with_handle_complete, NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -806,7 +830,7 @@ lvol_close_fail(void)
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, lvol_op_with_handle_complete, NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -844,7 +868,7 @@ lvol_close_success(void)
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, lvol_op_with_handle_complete, NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -883,7 +907,7 @@ lvol_resize(void)
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, lvol_op_with_handle_complete, NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -1271,28 +1295,28 @@ lvol_names(void)
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
lvs = g_lvol_store;
rc = spdk_lvol_create(lvs, NULL, 1, lvol_op_with_handle_complete, NULL);
rc = spdk_lvol_create(lvs, NULL, 1, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(rc == -EINVAL);
rc = spdk_lvol_create(lvs, "", 1, lvol_op_with_handle_complete, NULL);
rc = spdk_lvol_create(lvs, "", 1, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(rc == -EINVAL);
memset(fullname, 'x', sizeof(fullname));
rc = spdk_lvol_create(lvs, fullname, 1, lvol_op_with_handle_complete, NULL);
rc = spdk_lvol_create(lvs, fullname, 1, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(rc == -EINVAL);
g_lvserrno = -1;
rc = spdk_lvol_create(lvs, "lvol", 1, lvol_op_with_handle_complete, NULL);
rc = spdk_lvol_create(lvs, "lvol", 1, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(rc == 0);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
lvol = g_lvol;
rc = spdk_lvol_create(lvs, "lvol", 1, lvol_op_with_handle_complete, NULL);
rc = spdk_lvol_create(lvs, "lvol", 1, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(rc == -EINVAL);
g_lvserrno = -1;
rc = spdk_lvol_create(lvs, "lvol2", 1, lvol_op_with_handle_complete, NULL);
rc = spdk_lvol_create(lvs, "lvol2", 1, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(rc == 0);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -1303,7 +1327,7 @@ lvol_names(void)
g_lvserrno = -1;
g_lvol = NULL;
rc = spdk_lvol_create(lvs, "lvol", 1, lvol_op_with_handle_complete, NULL);
rc = spdk_lvol_create(lvs, "lvol", 1, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(rc == 0);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -1342,7 +1366,7 @@ static void lvol_refcnt(void)
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, lvol_op_with_handle_complete, NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
@ -1383,6 +1407,58 @@ static void lvol_refcnt(void)
spdk_free_thread();
}
static void
lvol_create_thin_provisioned(void)
{
struct lvol_ut_bs_dev dev;
struct spdk_lvs_opts opts;
int rc = 0;
init_dev(&dev);
spdk_allocate_thread(_lvol_send_msg, NULL, NULL, NULL, NULL);
spdk_lvs_opts_init(&opts);
strncpy(opts.name, "lvs", sizeof(opts.name));
g_lvserrno = -1;
rc = spdk_lvs_init(&dev.bs_dev, &opts, lvol_store_op_with_handle_complete, NULL);
CU_ASSERT(rc == 0);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
spdk_lvol_create(g_lvol_store, "lvol", 10, false, lvol_op_with_handle_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
CU_ASSERT(g_lvol->blob->thin_provisioned == false);
spdk_lvol_close(g_lvol, close_cb, NULL);
CU_ASSERT(g_lvserrno == 0);
spdk_lvol_destroy(g_lvol, destroy_cb, NULL);
CU_ASSERT(g_lvserrno == 0);
spdk_lvol_create(g_lvol_store, "lvol", 10, true, lvol_op_with_handle_complete, NULL);
CU_ASSERT(g_lvserrno == 0);
SPDK_CU_ASSERT_FATAL(g_lvol != NULL);
CU_ASSERT(g_lvol->blob->thin_provisioned == true);
spdk_lvol_close(g_lvol, close_cb, NULL);
CU_ASSERT(g_lvserrno == 0);
spdk_lvol_destroy(g_lvol, destroy_cb, NULL);
CU_ASSERT(g_lvserrno == 0);
g_lvserrno = -1;
rc = spdk_lvs_unload(g_lvol_store, lvol_store_op_complete, NULL);
CU_ASSERT(rc == 0);
CU_ASSERT(g_lvserrno == 0);
g_lvol_store = NULL;
free_dev(&dev);
spdk_free_thread();
}
int main(int argc, char **argv)
{
@ -1418,7 +1494,8 @@ int main(int argc, char **argv)
CU_add_test(suite, "lvs_load", lvols_load) == NULL ||
CU_add_test(suite, "lvol_open", lvol_open) == NULL ||
CU_add_test(suite, "lvol_refcnt", lvol_refcnt) == NULL ||
CU_add_test(suite, "lvol_names", lvol_names) == NULL
CU_add_test(suite, "lvol_names", lvol_names) == NULL ||
CU_add_test(suite, "lvol_create_thin_provisioned", lvol_create_thin_provisioned) == NULL
) {
CU_cleanup_registry();
return CU_get_error();