diff --git a/module/bdev/uring/bdev_uring.c b/module/bdev/uring/bdev_uring.c index e17baaaaa..06e32bc36 100644 --- a/module/bdev/uring/bdev_uring.c +++ b/module/bdev/uring/bdev_uring.c @@ -410,10 +410,10 @@ bdev_uring_group_destroy_cb(void *io_device, void *ctx_buf) } struct spdk_bdev * -create_uring_bdev(const char *name, const char *filename) +create_uring_bdev(const char *name, const char *filename, uint32_t block_size) { struct bdev_uring *uring; - uint32_t block_size; + uint32_t detected_block_size; uint64_t bdev_size; int rc; @@ -444,10 +444,25 @@ create_uring_bdev(const char *name, const char *filename) uring->bdev.write_cache = 1; - block_size = spdk_fd_get_blocklen(uring->fd); + detected_block_size = spdk_fd_get_blocklen(uring->fd); if (block_size == 0) { - SPDK_ERRLOG("Block size could not be auto-detected\n"); - goto error_return; + /* User did not specify block size - use autodetected block size. */ + if (detected_block_size == 0) { + SPDK_ERRLOG("Block size could not be auto-detected\n"); + goto error_return; + } + block_size = detected_block_size; + } else { + if (block_size < detected_block_size) { + SPDK_ERRLOG("Specified block size %" PRIu32 " is smaller than " + "auto-detected block size %" PRIu32 "\n", + block_size, detected_block_size); + goto error_return; + } else if (detected_block_size != 0 && block_size != detected_block_size) { + SPDK_WARNLOG("Specified block size %" PRIu32 " does not match " + "auto-detected block size %" PRIu32 "\n", + block_size, detected_block_size); + } } if (block_size < 512) { @@ -548,6 +563,9 @@ bdev_uring_init(void) while (true) { const char *file; const char *name; + const char *block_size_str; + uint32_t block_size = 0; + long int tmp; file = spdk_conf_section_get_nmval(sp, "URING", i, 0); if (!file) { @@ -561,7 +579,18 @@ bdev_uring_init(void) continue; } - bdev = create_uring_bdev(name, file); + block_size_str = spdk_conf_section_get_nmval(sp, "URING", i, 2); + if (block_size_str) { + tmp = spdk_strtol(block_size_str, 10); + if (tmp < 0) { + SPDK_ERRLOG("Invalid block size for URING bdev with file %s\n", file); + i++; + continue; + } + block_size = (uint32_t)tmp; + } + + bdev = create_uring_bdev(name, file, block_size); if (!bdev) { SPDK_ERRLOG("Unable to create URING bdev from file %s\n", file); i++; diff --git a/module/bdev/uring/bdev_uring.h b/module/bdev/uring/bdev_uring.h index fb3a653c8..a35681832 100644 --- a/module/bdev/uring/bdev_uring.h +++ b/module/bdev/uring/bdev_uring.h @@ -43,7 +43,7 @@ typedef void (*spdk_delete_uring_complete)(void *cb_arg, int bdeverrno); -struct spdk_bdev *create_uring_bdev(const char *name, const char *filename); +struct spdk_bdev *create_uring_bdev(const char *name, const char *filename, uint32_t block_size); void delete_uring_bdev(struct spdk_bdev *bdev, spdk_delete_uring_complete cb_fn, void *cb_arg); diff --git a/module/bdev/uring/bdev_uring_rpc.c b/module/bdev/uring/bdev_uring_rpc.c index b221c68c0..045c53b6c 100644 --- a/module/bdev/uring/bdev_uring_rpc.c +++ b/module/bdev/uring/bdev_uring_rpc.c @@ -41,6 +41,7 @@ struct rpc_create_uring { char *name; char *filename; + uint32_t block_size; }; /* Free the allocated memory resource after the RPC handling. */ @@ -55,6 +56,7 @@ free_rpc_create_uring(struct rpc_create_uring *r) static const struct spdk_json_object_decoder rpc_create_uring_decoders[] = { {"name", offsetof(struct rpc_create_uring, name), spdk_json_decode_string}, {"filename", offsetof(struct rpc_create_uring, filename), spdk_json_decode_string}, + {"block_size", offsetof(struct rpc_create_uring, block_size), spdk_json_decode_uint32, true}, }; /* Decode the parameters for this RPC method and properly create the uring @@ -77,7 +79,7 @@ spdk_rpc_bdev_uring_create(struct spdk_jsonrpc_request *request, goto cleanup; } - bdev = create_uring_bdev(req.name, req.filename); + bdev = create_uring_bdev(req.name, req.filename, req.block_size); if (!bdev) { SPDK_ERRLOG("Unable to create URING bdev from file %s\n", req.filename); spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR, diff --git a/scripts/rpc.py b/scripts/rpc.py index d0ed007fb..5c9f25a0e 100755 --- a/scripts/rpc.py +++ b/scripts/rpc.py @@ -329,11 +329,13 @@ if __name__ == "__main__": def bdev_uring_create(args): print_json(rpc.bdev.bdev_uring_create(args.client, filename=args.filename, - name=args.name)) + name=args.name, + block_size=args.block_size)) p = subparsers.add_parser('bdev_uring_create', help='Create a bdev with io_uring backend') p.add_argument('filename', help='Path to device or file (ex: /dev/nvme0n1)') p.add_argument('name', help='bdev name') + p.add_argument('block_size', help='Block size for this bdev', type=int, nargs='?', default=0) p.set_defaults(func=bdev_uring_create) def bdev_uring_delete(args): diff --git a/scripts/rpc/bdev.py b/scripts/rpc/bdev.py index bcc1a7257..ef1822a1b 100644 --- a/scripts/rpc/bdev.py +++ b/scripts/rpc/bdev.py @@ -321,12 +321,13 @@ def bdev_aio_delete(client, name): return client.call('bdev_aio_delete', params) -def bdev_uring_create(client, filename, name): +def bdev_uring_create(client, filename, name, block_size=None): """Create a bdev with Linux io_uring backend. Args: filename: path to device or file (ex: /dev/nvme0n1) name: name of bdev + block_size: block size of device (optional; autodetected if omitted) Returns: Name of created bdev. @@ -334,6 +335,9 @@ def bdev_uring_create(client, filename, name): params = {'name': name, 'filename': filename} + if block_size: + params['block_size'] = block_size + return client.call('bdev_uring_create', params)