diff --git a/CHANGELOG.md b/CHANGELOG.md index 1013a56d8..5e0cc48f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,10 @@ can only be deleted. Metadata support has been added to Null bdev module. +### rpc + +Added optional parameter '--md-size'to 'construct_null_bdev' RPC method. + ## v19.07: ### ftl diff --git a/doc/jsonrpc.md b/doc/jsonrpc.md index 0d5b35ddf..c87178254 100644 --- a/doc/jsonrpc.md +++ b/doc/jsonrpc.md @@ -1243,6 +1243,7 @@ name | Optional | string | Bdev name to use block_size | Required | number | Block size in bytes num_blocks | Required | number | Number of blocks uuid | Optional | string | UUID of new bdev +md_size | Optional | number | Metadata size in bytes ### Result @@ -1255,10 +1256,11 @@ Example request: ~~~ { "params": { - "block_size": 4096, + "block_size": 4104, "num_blocks": 16384, "name": "Null0", - "uuid": "2b6601ba-eada-44fb-9a83-a20eb9eb9e90" + "uuid": "2b6601ba-eada-44fb-9a83-a20eb9eb9e90", + "md_size": 8 }, "jsonrpc": "2.0", "method": "construct_null_bdev", diff --git a/module/bdev/null/bdev_null.c b/module/bdev/null/bdev_null.c index 5e10b67dc..0f60ac208 100644 --- a/module/bdev/null/bdev_null.c +++ b/module/bdev/null/bdev_null.c @@ -156,6 +156,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, "md_size", bdev->md_len); spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), &bdev->uuid); spdk_json_write_named_string(w, "uuid", uuid_str); spdk_json_write_object_end(w); diff --git a/module/bdev/null/bdev_null_rpc.c b/module/bdev/null/bdev_null_rpc.c index 46cc39589..44583bfb0 100644 --- a/module/bdev/null/bdev_null_rpc.c +++ b/module/bdev/null/bdev_null_rpc.c @@ -44,6 +44,7 @@ struct rpc_construct_null { char *uuid; uint64_t num_blocks; uint32_t block_size; + uint32_t md_size; }; static void @@ -58,6 +59,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}, + {"md_size", offsetof(struct rpc_construct_null, md_size), spdk_json_decode_uint32, true}, }; static void @@ -70,6 +72,7 @@ spdk_rpc_construct_null_bdev(struct spdk_jsonrpc_request *request, struct spdk_uuid decoded_uuid; struct spdk_bdev *bdev; struct spdk_null_bdev_opts opts = {}; + uint32_t data_block_size; int rc = 0; if (spdk_json_decode_object(params, rpc_construct_null_decoders, @@ -81,9 +84,15 @@ spdk_rpc_construct_null_bdev(struct spdk_jsonrpc_request *request, goto cleanup; } - if (req.block_size % 512 != 0) { + if (req.block_size < req.md_size) { spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, - "Block size %u is not a multiple of 512", req.block_size); + "Interleaved metadata size can not be greater than block size"); + goto cleanup; + } + data_block_size = req.block_size - req.md_size; + if (data_block_size % 512 != 0) { + spdk_jsonrpc_send_error_response_fmt(request, -EINVAL, + "Data block size %u is not a multiple of 512", req.block_size); goto cleanup; } @@ -106,6 +115,8 @@ spdk_rpc_construct_null_bdev(struct spdk_jsonrpc_request *request, opts.uuid = uuid; opts.num_blocks = req.num_blocks; opts.block_size = req.block_size; + opts.md_size = req.md_size; + opts.md_interleave = true; rc = create_null_bdev(&bdev, &opts); if (rc) { spdk_jsonrpc_send_error_response(request, rc, spdk_strerror(-rc)); diff --git a/scripts/rpc.py b/scripts/rpc.py index e45b9f933..4f5ed15b1 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -260,7 +260,8 @@ if __name__ == "__main__": num_blocks=num_blocks, block_size=args.block_size, name=args.name, - uuid=args.uuid)) + uuid=args.uuid, + md_size=args.md_size)) p = subparsers.add_parser('construct_null_bdev', help='Add a bdev with null backend') @@ -269,6 +270,8 @@ if __name__ == "__main__": p.add_argument( 'total_size', help='Size of null bdev in MB (int > 0)', type=int) p.add_argument('block_size', help='Block size for this bdev', type=int) + p.add_argument('-m', '--md-size', type=int, + help='Metadata size for this bdev. Default 0') p.set_defaults(func=construct_null_bdev) def delete_null_bdev(args): diff --git a/scripts/rpc/bdev.py b/scripts/rpc/bdev.py index 7303e1340..13416518b 100644 --- a/scripts/rpc/bdev.py +++ b/scripts/rpc/bdev.py @@ -189,14 +189,15 @@ def delete_malloc_bdev(client, name): return client.call('delete_malloc_bdev', params) -def construct_null_bdev(client, num_blocks, block_size, name, uuid=None): +def construct_null_bdev(client, num_blocks, block_size, name, uuid=None, md_size=None): """Construct a null block device. Args: num_blocks: size of block device in blocks - block_size: block size of device; must be a power of 2 and at least 512 + block_size: block size of device; data part size must be a power of 2 and at least 512 name: name of block device uuid: UUID of block device (optional) + md_size: metadata size of device (optional) Returns: Name of created block device. @@ -205,6 +206,8 @@ def construct_null_bdev(client, num_blocks, block_size, name, uuid=None): 'block_size': block_size} if uuid: params['uuid'] = uuid + if md_size: + params['md_size'] = md_size return client.call('construct_null_bdev', params)