Commit e0d7428b authored by Atul Malakar's avatar Atul Malakar Committed by Konrad Sztyber
Browse files

lvol: Add custom metadata page size to lvstore



Added new --md_page_size parameter to bdev_lvol_create_lvstore RPC.
It facilitates user to pick a custom md_page_size, greater than
phys_blocklen of the underlying device.

This will allow functional testing of the large IU metadata changes
on 4K IU NVMe SSDs.

Change-Id: Ib1bc68ba4d5b8a7db7f2befc1f616b342c01bc0f
Signed-off-by: default avatarAtul Malakar <a.malakar@samsung.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/25304


Community-CI: Mellanox Build Bot
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Community CI Samsung <spdk.community.ci.samsung@gmail.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: default avatarJim Harris <jim.harris@nvidia.com>
parent 2dc4a231
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -10339,6 +10339,7 @@ lvs_name | Required | string | Name of the logical vol
cluster_sz                    | Optional | number      | Cluster size of the logical volume store in bytes (Default: 4MiB)
clear_method                  | Optional | string      | Change clear method for data region. Available: none, unmap (default), write_zeroes
num_md_pages_per_cluster_ratio| Optional | number      | Reserved metadata pages per cluster (Default: 100)
md_page_size                  | Optional | number      | Metadata page size of the logical volume store in bytes (Default: max(4KB, bdev phys blocklen)

The num_md_pages_per_cluster_ratio defines the amount of metadata to
allocate when the logical volume store is created. The default value
@@ -10371,6 +10372,7 @@ Example request:
    "lvs_name": "LVS0",
    "bdev_name": "Malloc0",
    "clear_method": "write_zeroes"
    "md_page_size": "4096"
  }
}
~~~
+4 −1
Original line number Diff line number Diff line
@@ -69,8 +69,11 @@ struct spdk_lvs_opts {
	 * is being loaded, the lvolstore will not support external snapshots.
	 */
	spdk_bs_esnap_dev_create esnap_bs_dev_create;

	/** Metadata page size */
	uint32_t                md_page_size;
} __attribute__((packed));
SPDK_STATIC_ASSERT(sizeof(struct spdk_lvs_opts) == 88, "Incorrect size");
SPDK_STATIC_ASSERT(sizeof(struct spdk_lvs_opts) == 92, "Incorrect size");

/**
 * Initialize an spdk_lvs_opts structure to the defaults.
+3 −1
Original line number Diff line number Diff line
@@ -647,12 +647,13 @@ lvs_opts_copy(const struct spdk_lvs_opts *src, struct spdk_lvs_opts *dst)
	SET_FIELD(num_md_pages_per_cluster_ratio);
	SET_FIELD(opts_size);
	SET_FIELD(esnap_bs_dev_create);
	SET_FIELD(md_page_size);

	dst->opts_size = src->opts_size;

	/* You should not remove this statement, but need to update the assert statement
	 * if you add a new field, and also add a corresponding SET_FIELD statement */
	SPDK_STATIC_ASSERT(sizeof(struct spdk_lvs_opts) == 88, "Incorrect size");
	SPDK_STATIC_ASSERT(sizeof(struct spdk_lvs_opts) == 92, "Incorrect size");

#undef FIELD_OK
#undef SET_FIELD
@@ -669,6 +670,7 @@ setup_lvs_opts(struct spdk_bs_opts *bs_opts, struct spdk_lvs_opts *o, uint32_t t
	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;
	bs_opts->md_page_size = o->md_page_size;
	bs_opts->esnap_bs_dev_create = o->esnap_bs_dev_create;
	bs_opts->esnap_ctx = esnap_ctx;
	snprintf(bs_opts->bstype.bstype, sizeof(bs_opts->bstype.bstype), "LVOLSTORE");
+31 −3
Original line number Diff line number Diff line
@@ -210,9 +210,9 @@ end:
}

int
vbdev_lvs_create(const char *base_bdev_name, const char *name, uint32_t cluster_sz,
vbdev_lvs_create_ext(const char *base_bdev_name, const char *name, uint32_t cluster_sz,
		     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)
		     uint32_t md_page_size, 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;
@@ -252,6 +252,17 @@ vbdev_lvs_create(const char *base_bdev_name, const char *name, uint32_t cluster_
	snprintf(opts.name, sizeof(opts.name), "%s", name);
	opts.esnap_bs_dev_create = vbdev_lvol_esnap_dev_create;

	if (md_page_size != 0 && (md_page_size < 4096 || md_page_size > 65536)) {
		SPDK_ERRLOG("Invalid metadata page size %" PRIu32 " (must be between 4096B and 65536B).\n",
			    md_page_size);
		return -EINVAL;
	}

	if (md_page_size != 0 && (!spdk_u32_is_pow2(md_page_size))) {
		SPDK_ERRLOG("Invalid metadata page size %" PRIu32 " (must be a power of 2.)\n", md_page_size);
		return -EINVAL;
	}

	lvs_req = calloc(1, sizeof(*lvs_req));
	if (!lvs_req) {
		SPDK_ERRLOG("Cannot alloc memory for vbdev lvol store request pointer\n");
@@ -266,6 +277,11 @@ vbdev_lvs_create(const char *base_bdev_name, const char *name, uint32_t cluster_
		return rc;
	}

	if (md_page_size > bs_dev->phys_blocklen) {
		SPDK_WARNLOG("Metadata page size is greater than physical block length\n");
	}

	opts.md_page_size = md_page_size;
	lvs_req->bs_dev = bs_dev;
	lvs_req->base_bdev = bs_dev->get_base_bdev(bs_dev);
	lvs_req->cb_fn = cb_fn;
@@ -281,6 +297,17 @@ vbdev_lvs_create(const char *base_bdev_name, const char *name, uint32_t cluster_
	return 0;
}

int
vbdev_lvs_create(const char *base_bdev_name, const char *name, uint32_t cluster_sz,
		 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)
{
	uint32_t md_page_size = 0;

	return vbdev_lvs_create_ext(base_bdev_name, name, cluster_sz, clear_method,
				    num_md_pages_per_cluster_ratio, md_page_size, cb_fn, cb_arg);
}

static void
_vbdev_lvs_rename_cb(void *cb_arg, int lvserrno)
{
@@ -1149,6 +1176,7 @@ _create_lvol_disk(struct spdk_lvol *lvol, bool destroy)
	bdev->ctxt = lvol;
	bdev->fn_table = &vbdev_lvol_fn_table;
	bdev->module = &g_lvol_if;
	bdev->phys_blocklen = lvol->lvol_store->bs_dev->phys_blocklen;

	/* Set default bdev reset waiting time. This value indicates how much
	 * time a reset should wait before forcing a reset down to the underlying
+3 −0
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ 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, uint32_t num_md_pages_per_cluster_ratio,
		     spdk_lvs_op_with_handle_complete cb_fn, void *cb_arg);
int vbdev_lvs_create_ext(const char *base_bdev_name, const char *name, uint32_t cluster_sz,
			 enum lvs_clear_method clear_method, uint32_t num_md_pages_per_cluster_ratio,
			 uint32_t md_page_size, 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);

Loading