From 7f50da15bc1c0ef1705d7df58be6d4e48f637b0d Mon Sep 17 00:00:00 2001 From: "Panfil, Wojciech" Date: Tue, 14 Feb 2023 06:21:56 -0500 Subject: [PATCH] null_bdev: Add physical block size optional argument In the past we didn't use the distinction between logical block size and physical block size in null bdev. Now we can optionally set the physical block size to be different then logical block size. It's useful for testing NVMe 512e Advanced Format scenarios. Change-Id: Ib3713af9a4d0ce7fd322170b4d87100cfc91a103 Signed-off-by: Panfil, Wojciech Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/16792 Tested-by: SPDK CI Jenkins Reviewed-by: Konrad Sztyber Reviewed-by: Jacek Kalwas Reviewed-by: Tomasz Zawadzki --- module/bdev/null/bdev_null.c | 2 ++ module/bdev/null/bdev_null.h | 1 + module/bdev/null/bdev_null_rpc.c | 8 ++++++++ python/spdk/rpc/bdev.py | 5 ++++- scripts/rpc.py | 2 ++ 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/module/bdev/null/bdev_null.c b/module/bdev/null/bdev_null.c index 4e4752e58..85049c66c 100644 --- a/module/bdev/null/bdev_null.c +++ b/module/bdev/null/bdev_null.c @@ -201,6 +201,7 @@ bdev_null_write_config_json(struct spdk_bdev *bdev, struct spdk_json_write_ctx * spdk_json_write_named_string(w, "name", bdev->name); spdk_json_write_named_uint64(w, "num_blocks", bdev->blockcnt); spdk_json_write_named_uint32(w, "block_size", bdev->blocklen); + spdk_json_write_named_uint32(w, "physical_block_size", bdev->phys_blocklen); spdk_json_write_named_uint32(w, "md_size", bdev->md_len); spdk_json_write_named_uint32(w, "dif_type", bdev->dif_type); spdk_json_write_named_bool(w, "dif_is_head_of_md", bdev->dif_is_head_of_md); @@ -270,6 +271,7 @@ bdev_null_create(struct spdk_bdev **bdev, const struct spdk_null_bdev_opts *opts null_disk->bdev.write_cache = 0; null_disk->bdev.blocklen = opts->block_size; + null_disk->bdev.phys_blocklen = opts->physical_block_size; null_disk->bdev.blockcnt = opts->num_blocks; null_disk->bdev.md_len = opts->md_size; null_disk->bdev.md_interleave = opts->md_interleave; diff --git a/module/bdev/null/bdev_null.h b/module/bdev/null/bdev_null.h index d539c71ad..d1e58ebfb 100644 --- a/module/bdev/null/bdev_null.h +++ b/module/bdev/null/bdev_null.h @@ -18,6 +18,7 @@ struct spdk_null_bdev_opts { const struct spdk_uuid *uuid; uint64_t num_blocks; uint32_t block_size; + uint32_t physical_block_size; uint32_t md_size; bool md_interleave; enum spdk_dif_type dif_type; diff --git a/module/bdev/null/bdev_null_rpc.c b/module/bdev/null/bdev_null_rpc.c index 685203048..91b49b77d 100644 --- a/module/bdev/null/bdev_null_rpc.c +++ b/module/bdev/null/bdev_null_rpc.c @@ -16,6 +16,7 @@ struct rpc_construct_null { char *uuid; uint64_t num_blocks; uint32_t block_size; + uint32_t physical_block_size; uint32_t md_size; int32_t dif_type; bool dif_is_head_of_md; @@ -33,6 +34,7 @@ static const struct spdk_json_object_decoder rpc_construct_null_decoders[] = { {"uuid", offsetof(struct rpc_construct_null, uuid), spdk_json_decode_string, true}, {"num_blocks", offsetof(struct rpc_construct_null, num_blocks), spdk_json_decode_uint64}, {"block_size", offsetof(struct rpc_construct_null, block_size), spdk_json_decode_uint32}, + {"physical_block_size", offsetof(struct rpc_construct_null, physical_block_size), spdk_json_decode_uint32, true}, {"md_size", offsetof(struct rpc_construct_null, md_size), spdk_json_decode_uint32, true}, {"dif_type", offsetof(struct rpc_construct_null, dif_type), spdk_json_decode_int32, true}, {"dif_is_head_of_md", offsetof(struct rpc_construct_null, dif_is_head_of_md), spdk_json_decode_bool, true}, @@ -72,6 +74,11 @@ rpc_bdev_null_create(struct spdk_jsonrpc_request *request, goto cleanup; } + if (req.physical_block_size % 512 != 0) { + spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, + "Physical block size %u is not a multiple of 512", req.physical_block_size); + } + if (req.num_blocks == 0) { spdk_jsonrpc_send_error_response(request, -EINVAL, "Disk num_blocks must be greater than 0"); @@ -102,6 +109,7 @@ rpc_bdev_null_create(struct spdk_jsonrpc_request *request, opts.uuid = uuid; opts.num_blocks = req.num_blocks; opts.block_size = req.block_size; + opts.physical_block_size = req.physical_block_size; opts.md_size = req.md_size; opts.md_interleave = true; opts.dif_type = req.dif_type; diff --git a/python/spdk/rpc/bdev.py b/python/spdk/rpc/bdev.py index bbbfcbe24..f3721c093 100644 --- a/python/spdk/rpc/bdev.py +++ b/python/spdk/rpc/bdev.py @@ -315,7 +315,7 @@ def bdev_malloc_delete(client, name): return client.call('bdev_malloc_delete', params) -def bdev_null_create(client, num_blocks, block_size, name, uuid=None, md_size=None, +def bdev_null_create(client, num_blocks, block_size, name, physical_block_size=None, uuid=None, md_size=None, dif_type=None, dif_is_head_of_md=None): """Construct a null block device. @@ -323,6 +323,7 @@ def bdev_null_create(client, num_blocks, block_size, name, uuid=None, md_size=No num_blocks: size of block device in blocks block_size: block size of device; data part size must be a power of 2 and at least 512 name: name of block device + physical_block_size: physical block size of the device; data part size must be a power of 2 and at least 512 (optional) uuid: UUID of block device (optional) md_size: metadata size of device (optional) dif_type: protection information type (optional) @@ -333,6 +334,8 @@ def bdev_null_create(client, num_blocks, block_size, name, uuid=None, md_size=No """ params = {'name': name, 'num_blocks': num_blocks, 'block_size': block_size} + if physical_block_size: + params['physical_block_size'] = physical_block_size if uuid: params['uuid'] = uuid if md_size: diff --git a/scripts/rpc.py b/scripts/rpc.py index 4e6b9da4a..8f01925e8 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -421,6 +421,7 @@ if __name__ == "__main__": print_json(rpc.bdev.bdev_null_create(args.client, num_blocks=num_blocks, block_size=args.block_size, + physical_block_size=args.physical_block_size, name=args.name, uuid=args.uuid, md_size=args.md_size, @@ -433,6 +434,7 @@ if __name__ == "__main__": p.add_argument('total_size', help='Size of null bdev in MB (int > 0). Includes only data blocks.', type=int) p.add_argument('block_size', help='Block size for this bdev.' 'Should be a sum of block size and metadata size if --md-size is used.', type=int) + p.add_argument('-p', '--physical-block-size', help='Physical block size for this bdev.', type=int) p.add_argument('-m', '--md-size', type=int, help='Metadata size for this bdev. Default=0.') p.add_argument('-t', '--dif-type', type=int, choices=[0, 1, 2, 3],