blobstore: reserve space for growing blobstore
Reserve space for used_cluster bitmap. The reserved space is calculated according to the num_md_pages. The reserved space would be used when the blobstore is extended in the future. Add the num_md_pages_per_cluster_ratio parameter to the bdev_lvol_create_lvstore API. Then calculate the num_md_pages according to the num_md_pages_per_cluster_ratio and bdev total size, then pass the num_md_pages to the blobstore. Signed-off-by: Peng Yu <yupeng0921@gmail.com> Change-Id: I61a28a3c931227e0fd3e1ef6b145fc18a3657751 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9517 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com> Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
72c4255e9d
commit
88833020eb
10
CHANGELOG.md
10
CHANGELOG.md
@ -7,6 +7,16 @@
|
||||
Added new `ssl` based socket implementation, the code is located in module/sock/posix.
|
||||
For now we are using hard-coded PSK and only support TLS 1.3
|
||||
|
||||
### blobstore
|
||||
|
||||
Reserve space for used_cluster bitmap. The reserved space could be used for blobstore growing
|
||||
in the future.
|
||||
|
||||
### lvol
|
||||
|
||||
Add num_md_pages_per_cluster_ratio parameter to the bdev_lvol_create_lvstore RPC.
|
||||
Calculate num_md_pages from num_md_pages_per_cluster_ratio, and pass it to spdk_bs_opts.
|
||||
|
||||
## v22.05
|
||||
|
||||
### sock
|
||||
|
@ -45,6 +45,8 @@ struct spdk_lvs_opts {
|
||||
uint32_t cluster_sz;
|
||||
enum lvs_clear_method clear_method;
|
||||
char name[SPDK_LVS_NAME_MAX];
|
||||
/** num_md_pages_per_cluster_ratio = 100 means 1 page per cluster */
|
||||
uint32_t num_md_pages_per_cluster_ratio;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -4995,6 +4995,7 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
|
||||
uint64_t num_md_lba;
|
||||
uint64_t num_md_pages;
|
||||
uint64_t num_md_clusters;
|
||||
uint64_t max_used_cluster_mask_len;
|
||||
uint32_t i;
|
||||
struct spdk_bs_opts opts = {};
|
||||
int rc;
|
||||
@ -5101,7 +5102,16 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
|
||||
ctx->super->used_cluster_mask_len = spdk_divide_round_up(sizeof(struct spdk_bs_md_mask) +
|
||||
spdk_divide_round_up(bs->total_clusters, 8),
|
||||
SPDK_BS_PAGE_SIZE);
|
||||
num_md_pages += ctx->super->used_cluster_mask_len;
|
||||
/* The blobstore might be extended, then the used_cluster bitmap will need more space.
|
||||
* Here we calculate the max clusters we can support according to the
|
||||
* num_md_pages (bs->md_len).
|
||||
*/
|
||||
max_used_cluster_mask_len = spdk_divide_round_up(sizeof(struct spdk_bs_md_mask) +
|
||||
spdk_divide_round_up(bs->md_len, 8),
|
||||
SPDK_BS_PAGE_SIZE);
|
||||
max_used_cluster_mask_len = spdk_max(max_used_cluster_mask_len,
|
||||
ctx->super->used_cluster_mask_len);
|
||||
num_md_pages += max_used_cluster_mask_len;
|
||||
|
||||
/* The used_blobids mask requires 1 bit per metadata page, rounded
|
||||
* up to the nearest page, plus a header.
|
||||
|
@ -6,7 +6,7 @@
|
||||
SPDK_ROOT_DIR := $(abspath $(CURDIR)/../..)
|
||||
include $(SPDK_ROOT_DIR)/mk/spdk.common.mk
|
||||
|
||||
SO_VER := 6
|
||||
SO_VER := 7
|
||||
SO_MINOR := 0
|
||||
|
||||
C_SRCS = lvol.c
|
||||
|
@ -526,16 +526,18 @@ spdk_lvs_opts_init(struct spdk_lvs_opts *o)
|
||||
{
|
||||
o->cluster_sz = SPDK_LVS_OPTS_CLUSTER_SZ;
|
||||
o->clear_method = LVS_CLEAR_WITH_UNMAP;
|
||||
o->num_md_pages_per_cluster_ratio = 100;
|
||||
memset(o->name, 0, sizeof(o->name));
|
||||
}
|
||||
|
||||
static void
|
||||
setup_lvs_opts(struct spdk_bs_opts *bs_opts, struct spdk_lvs_opts *o)
|
||||
setup_lvs_opts(struct spdk_bs_opts *bs_opts, struct spdk_lvs_opts *o, uint32_t total_clusters)
|
||||
{
|
||||
assert(o != NULL);
|
||||
lvs_bs_opts_init(bs_opts);
|
||||
bs_opts->cluster_sz = o->cluster_sz;
|
||||
bs_opts->clear_method = (enum bs_clear_method)o->clear_method;
|
||||
bs_opts->num_md_pages = (o->num_md_pages_per_cluster_ratio * total_clusters) / 100;
|
||||
}
|
||||
|
||||
int
|
||||
@ -545,6 +547,7 @@ spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o,
|
||||
struct spdk_lvol_store *lvs;
|
||||
struct spdk_lvs_with_handle_req *lvs_req;
|
||||
struct spdk_bs_opts opts = {};
|
||||
uint32_t total_clusters;
|
||||
int rc;
|
||||
|
||||
if (bs_dev == NULL) {
|
||||
@ -557,7 +560,14 @@ spdk_lvs_init(struct spdk_bs_dev *bs_dev, struct spdk_lvs_opts *o,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
setup_lvs_opts(&opts, o);
|
||||
if (o->cluster_sz < bs_dev->blocklen) {
|
||||
SPDK_ERRLOG("Cluster size %" PRIu32 " is smaller than blocklen %" PRIu32 "\n",
|
||||
opts.cluster_sz, bs_dev->blocklen);
|
||||
return -EINVAL;
|
||||
}
|
||||
total_clusters = bs_dev->blockcnt / (o->cluster_sz / bs_dev->blocklen);
|
||||
|
||||
setup_lvs_opts(&opts, o, total_clusters);
|
||||
|
||||
if (strnlen(o->name, SPDK_LVS_NAME_MAX) == SPDK_LVS_NAME_MAX) {
|
||||
SPDK_ERRLOG("Name has no null terminator.\n");
|
||||
|
@ -199,7 +199,8 @@ end:
|
||||
|
||||
int
|
||||
vbdev_lvs_create(const char *base_bdev_name, const char *name, uint32_t cluster_sz,
|
||||
enum lvs_clear_method clear_method, spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
|
||||
enum lvs_clear_method clear_method, uint32_t num_md_pages_per_cluster_ratio,
|
||||
spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg)
|
||||
{
|
||||
struct spdk_bs_dev *bs_dev;
|
||||
struct spdk_lvs_with_handle_req *lvs_req;
|
||||
@ -221,6 +222,10 @@ vbdev_lvs_create(const char *base_bdev_name, const char *name, uint32_t cluster_
|
||||
opts.clear_method = clear_method;
|
||||
}
|
||||
|
||||
if (num_md_pages_per_cluster_ratio != 0) {
|
||||
opts.num_md_pages_per_cluster_ratio = num_md_pages_per_cluster_ratio;
|
||||
}
|
||||
|
||||
if (name == NULL) {
|
||||
SPDK_ERRLOG("missing name param\n");
|
||||
return -EINVAL;
|
||||
|
@ -26,7 +26,8 @@ struct lvol_bdev {
|
||||
};
|
||||
|
||||
int vbdev_lvs_create(const char *base_bdev_name, const char *name, uint32_t cluster_sz,
|
||||
enum lvs_clear_method clear_method, spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg);
|
||||
enum lvs_clear_method clear_method, uint32_t num_md_pages_per_cluster_ratio,
|
||||
spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg);
|
||||
void vbdev_lvs_destruct(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg);
|
||||
void vbdev_lvs_unload(struct spdk_lvol_store *lvs, spdk_lvs_op_complete cb_fn, void *cb_arg);
|
||||
|
||||
|
@ -17,6 +17,7 @@ struct rpc_bdev_lvol_create_lvstore {
|
||||
char *bdev_name;
|
||||
uint32_t cluster_sz;
|
||||
char *clear_method;
|
||||
uint32_t num_md_pages_per_cluster_ratio;
|
||||
};
|
||||
|
||||
static int
|
||||
@ -62,6 +63,7 @@ static const struct spdk_json_object_decoder rpc_bdev_lvol_create_lvstore_decode
|
||||
{"cluster_sz", offsetof(struct rpc_bdev_lvol_create_lvstore, cluster_sz), spdk_json_decode_uint32, true},
|
||||
{"lvs_name", offsetof(struct rpc_bdev_lvol_create_lvstore, lvs_name), spdk_json_decode_string},
|
||||
{"clear_method", offsetof(struct rpc_bdev_lvol_create_lvstore, clear_method), spdk_json_decode_string, true},
|
||||
{"num_md_pages_per_cluster_ratio", offsetof(struct rpc_bdev_lvol_create_lvstore, num_md_pages_per_cluster_ratio), spdk_json_decode_uint32, true},
|
||||
};
|
||||
|
||||
static void
|
||||
@ -120,7 +122,7 @@ rpc_bdev_lvol_create_lvstore(struct spdk_jsonrpc_request *request,
|
||||
}
|
||||
|
||||
rc = vbdev_lvs_create(req.bdev_name, req.lvs_name, req.cluster_sz, clear_method,
|
||||
rpc_lvol_store_construct_cb, request);
|
||||
req.num_md_pages_per_cluster_ratio, rpc_lvol_store_construct_cb, request);
|
||||
if (rc < 0) {
|
||||
spdk_jsonrpc_send_error_response(request, -rc, spdk_strerror(rc));
|
||||
goto cleanup;
|
||||
|
@ -306,6 +306,8 @@ spdk_bdev_create_bs_dev_ext(const char *bdev_name, spdk_bdev_event_cb_t event_cb
|
||||
|
||||
bs_dev = calloc(1, sizeof(*bs_dev));
|
||||
SPDK_CU_ASSERT_FATAL(bs_dev != NULL);
|
||||
bs_dev->blocklen = 4096;
|
||||
bs_dev->blockcnt = 128;
|
||||
bs_dev->destroy = bdev_blob_destroy;
|
||||
bs_dev->get_base_bdev = bdev_blob_get_base_bdev;
|
||||
|
||||
@ -317,6 +319,10 @@ spdk_bdev_create_bs_dev_ext(const char *bdev_name, spdk_bdev_event_cb_t event_cb
|
||||
void
|
||||
spdk_lvs_opts_init(struct spdk_lvs_opts *opts)
|
||||
{
|
||||
opts->cluster_sz = SPDK_LVS_OPTS_CLUSTER_SZ;
|
||||
opts->clear_method = LVS_CLEAR_WITH_UNMAP;
|
||||
opts->num_md_pages_per_cluster_ratio = 100;
|
||||
memset(opts->name, 0, sizeof(opts->name));
|
||||
}
|
||||
|
||||
int
|
||||
@ -717,8 +723,8 @@ ut_lvs_destroy(void)
|
||||
struct spdk_lvol_store *lvs;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
|
||||
@ -751,8 +757,8 @@ ut_lvol_init(void)
|
||||
int rc;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
|
||||
@ -786,8 +792,8 @@ ut_lvol_snapshot(void)
|
||||
struct spdk_lvol *lvol = NULL;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
|
||||
@ -836,8 +842,8 @@ ut_lvol_clone(void)
|
||||
struct spdk_lvol *clone = NULL;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
|
||||
@ -902,8 +908,8 @@ ut_lvol_hotremove(void)
|
||||
lvol_already_opened = false;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
|
||||
@ -996,8 +1002,8 @@ ut_lvol_rename(void)
|
||||
int rc;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
|
||||
@ -1063,7 +1069,7 @@ ut_bdev_finish(void)
|
||||
/* Scenario 1
|
||||
* Test unload of lvs with no lvols during bdev finish. */
|
||||
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP,
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
@ -1086,7 +1092,7 @@ ut_bdev_finish(void)
|
||||
* then start bdev finish. This should unload the remaining lvol and
|
||||
* lvol store. */
|
||||
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP,
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
@ -1134,8 +1140,8 @@ ut_lvol_resize(void)
|
||||
int rc = 0;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
|
||||
@ -1180,8 +1186,8 @@ ut_lvol_set_read_only(void)
|
||||
int rc = 0;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
|
||||
@ -1220,8 +1226,8 @@ ut_lvs_unload(void)
|
||||
struct spdk_lvol_store *lvs;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
|
||||
@ -1256,8 +1262,8 @@ ut_lvs_init(void)
|
||||
/* spdk_lvs_init() fails */
|
||||
lvol_store_initialize_fail = true;
|
||||
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc != 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
CU_ASSERT(g_lvol_store == NULL);
|
||||
@ -1267,8 +1273,8 @@ ut_lvs_init(void)
|
||||
/* spdk_lvs_init_cb() fails */
|
||||
lvol_store_initialize_cb_fail = true;
|
||||
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno != 0);
|
||||
CU_ASSERT(g_lvol_store == NULL);
|
||||
@ -1276,8 +1282,8 @@ ut_lvs_init(void)
|
||||
lvol_store_initialize_cb_fail = false;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
SPDK_CU_ASSERT_FATAL(g_lvol_store != NULL);
|
||||
@ -1287,8 +1293,8 @@ ut_lvs_init(void)
|
||||
g_lvol_store = NULL;
|
||||
|
||||
/* Bdev with lvol store already claimed */
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, lvol_store_op_with_handle_complete,
|
||||
NULL);
|
||||
rc = vbdev_lvs_create("bdev", "lvs", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc != 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
CU_ASSERT(g_lvol_store == NULL);
|
||||
@ -1436,7 +1442,7 @@ ut_lvs_rename(void)
|
||||
struct spdk_lvol_store *lvs;
|
||||
|
||||
/* Lvol store is successfully created */
|
||||
rc = vbdev_lvs_create("bdev", "old_lvs_name", 0, LVS_CLEAR_WITH_UNMAP,
|
||||
rc = vbdev_lvs_create("bdev", "old_lvs_name", 0, LVS_CLEAR_WITH_UNMAP, 0,
|
||||
lvol_store_op_with_handle_complete, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
CU_ASSERT(g_lvserrno == 0);
|
||||
|
Loading…
Reference in New Issue
Block a user