Commit 67117940 authored by Daniel Verkamp's avatar Daniel Verkamp Committed by Jim Harris
Browse files

bdev/aio: allow user to override block size



Add a file-backed AIO bdev to test it out.

Change-Id: Ifdf206bbdf6cae9379fdc02c80755e96a7198bce
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/373673


Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent b5176ded
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -10,6 +10,10 @@ spdk_bdev_unmap() was modified to take an offset and a length in bytes as
arguments instead of requiring the user to provide an array of SCSI
unmap descriptors. This limits unmaps to a single contiguous range.

### Linux AIO bdev

The AIO bdev now allows the user to override the auto-detected block size.

## v17.07: Build system improvements, userspace vhost-blk target, and GPT bdev

### Build System
+3 −1
Original line number Diff line number Diff line
@@ -67,11 +67,13 @@ Configuration file syntax:

~~~
[AIO]
  # AIO <file name> <bdev name>
  # AIO <file name> <bdev name> [<block size>]
  # The file name is the backing device
  # The bdev name can be referenced from elsewhere in the configuration file.
  # Block size may be omitted to automatically detect the block size of a disk.
  AIO /dev/sdb AIO0
  AIO /dev/sdc AIO1
  AIO /tmp/myfile AIO2 4096
~~~

This exports 2 aio block devices, named AIO0 and AIO1.
+3 −1
Original line number Diff line number Diff line
@@ -135,12 +135,14 @@
# Users must change this section to match the /dev/sdX devices to be
# exported as iSCSI LUNs. The devices are accessed using Linux AIO.
# The format is:
# AIO <file name> <bdev name>
# AIO <file name> <bdev name> [<block size>]
# The file name is the backing device
# The bdev name can be referenced from elsewhere in the configuration file.
# Block size may be omitted to automatically detect the block size of a disk.
[AIO]
  AIO /dev/sdb AIO0
  AIO /dev/sdc AIO1
  AIO /tmp/myfile AIO2 4096

# The Split virtual block device slices block devices into multiple smaller bdevs.
[Split]
+2 −0
Original line number Diff line number Diff line
@@ -46,9 +46,11 @@
# AIO <file name> <bdev name>
# The file name is the backing device
# The bdev name can be referenced from elsewhere in the configuration file.
# Block size may be omitted to automatically detect the block size of a disk.
[AIO]
  AIO /dev/sdb AIO0
  AIO /dev/sdc AIO1
  AIO /tmp/myfile AIO2 4096

# Define NVMf protocol global options
[Nvmf]
+58 −6
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include "spdk/env.h"
#include "spdk/fd.h"
#include "spdk/io_channel.h"
#include "spdk/util.h"

#include "spdk_internal/log.h"

@@ -62,11 +63,15 @@ bdev_aio_open(struct file_disk *disk)
	int fd;

	fd = open(disk->file, O_RDWR | O_DIRECT);
	if (fd < 0) {
		/* Try without O_DIRECT for non-disk files */
		fd = open(disk->file, O_RDWR);
		if (fd < 0) {
			perror("open");
			disk->fd = -1;
			return -1;
		}
	}

	disk->fd = fd;

@@ -331,9 +336,10 @@ static void aio_free_disk(struct file_disk *fdisk)
}

struct spdk_bdev *
create_aio_disk(const char *name, const char *fname)
create_aio_disk(const char *name, const char *fname, uint32_t block_size)
{
	struct file_disk *fdisk;
	uint32_t detected_block_size;

	fdisk = calloc(sizeof(*fdisk), 1);
	if (!fdisk) {
@@ -359,7 +365,46 @@ create_aio_disk(const char *name, const char *fname)

	fdisk->disk.need_aligned_buffer = 1;
	fdisk->disk.write_cache = 1;
	fdisk->disk.blocklen = spdk_fd_get_blocklen(fdisk->fd);

	detected_block_size = spdk_fd_get_blocklen(fdisk->fd);
	if (block_size == 0) {
		/* 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) {
		SPDK_ERRLOG("Invalid block size %" PRIu32 " (must be at least 512).\n", block_size);
		goto error_return;
	}

	if (!spdk_u32_is_pow2(block_size)) {
		SPDK_ERRLOG("Invalid block size %" PRIu32 " (must be a power of 2.)\n", block_size);
		goto error_return;
	}

	fdisk->disk.blocklen = block_size;

	if (fdisk->size % fdisk->disk.blocklen != 0) {
		SPDK_ERRLOG("Disk size %" PRIu64 " is not a multiple of block size %" PRIu32 "\n",
			    fdisk->size, fdisk->disk.blocklen);
		goto error_return;
	}

	fdisk->disk.blockcnt = fdisk->size / fdisk->disk.blocklen;
	fdisk->disk.ctxt = fdisk;

@@ -392,6 +437,8 @@ bdev_aio_initialize(void)
	while (true) {
		const char *file;
		const char *name;
		const char *block_size_str;
		uint32_t block_size = 0;

		file = spdk_conf_section_get_nmval(sp, "AIO", i, 0);
		if (!file) {
@@ -405,7 +452,12 @@ bdev_aio_initialize(void)
			continue;
		}

		bdev = create_aio_disk(name, file);
		block_size_str = spdk_conf_section_get_nmval(sp, "AIO", i, 2);
		if (block_size_str) {
			block_size = atoi(block_size_str);
		}

		bdev = create_aio_disk(name, file, block_size);
		if (!bdev) {
			SPDK_ERRLOG("Unable to create AIO bdev from file %s\n", file);
			i++;
Loading