From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37809) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XC6VK-0005S4-Ct for qemu-devel@nongnu.org; Tue, 29 Jul 2014 08:27:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XC6V8-00068g-C3 for qemu-devel@nongnu.org; Tue, 29 Jul 2014 08:27:42 -0400 Received: from e06smtp10.uk.ibm.com ([195.75.94.106]:37386) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XC6V8-00067v-3A for qemu-devel@nongnu.org; Tue, 29 Jul 2014 08:27:30 -0400 Received: from /spool/local by e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 29 Jul 2014 13:27:29 +0100 Received: from b06cxnps3075.portsmouth.uk.ibm.com (d06relay10.portsmouth.uk.ibm.com [9.149.109.195]) by d06dlp03.portsmouth.uk.ibm.com (Postfix) with ESMTP id 431431B08040 for ; Tue, 29 Jul 2014 13:28:13 +0100 (BST) Received: from d06av01.portsmouth.uk.ibm.com (d06av01.portsmouth.uk.ibm.com [9.149.37.212]) by b06cxnps3075.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s6TCRRo635848252 for ; Tue, 29 Jul 2014 12:27:27 GMT Received: from d06av01.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av01.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s6TCRQ8R005741 for ; Tue, 29 Jul 2014 06:27:26 -0600 From: Ekaterina Tumanova Date: Tue, 29 Jul 2014 14:27:18 +0200 Message-Id: <1406636839-11946-4-git-send-email-tumanova@linux.vnet.ibm.com> In-Reply-To: <1406636839-11946-1-git-send-email-tumanova@linux.vnet.ibm.com> References: <1406636839-11946-1-git-send-email-tumanova@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 3/4] blocksize: Add driver method to get the blocksizes List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Public KVM Mailing List Cc: cornelia.huck@de.ibm.com, dahi@linux.vnet.ibm.com, Ekaterina Tumanova , borntraeger@de.ibm.com This patch introduces a new method of defining the physical and logical blocksizes for "raw" and "host_device" drivers. It uses various ioctls to determine the logical and physical blocksizes. For detecting the logical size it uses ioctl calls, that were previously coded in raw_probe_alignment (now moved into separate function probe_logical_blocksize). For detecting the physical blocksize it uses BLKPBSZGET ioctl. For "raw" devices driver calls the child's method. Signed-off-by: Ekaterina Tumanova Reviewed-by: David Hildenbrand Acked-by: Cornelia Huck --- block/raw-posix.c | 69 ++++++++++++++++++++++++++++++++++++++++--------------- block/raw_bsd.c | 14 +++++++++++ 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/block/raw-posix.c b/block/raw-posix.c index 8e9758e..6e0d80c 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -221,50 +221,70 @@ static int raw_normalize_devicepath(const char **filename) } #endif -static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp) +static unsigned int probe_logical_blocksize(BlockDriverState *bs, int fd) { - BDRVRawState *s = bs->opaque; - char *buf; - unsigned int sector_size; - - /* For /dev/sg devices the alignment is not really used. - With buffered I/O, we don't have any restrictions. */ - if (bs->sg || !(s->open_flags & O_DIRECT)) { - bs->request_alignment = 1; - s->buf_align = 1; - return; - } + unsigned int sector_size = 0; /* Try a few ioctls to get the right size */ - bs->request_alignment = 0; - s->buf_align = 0; - #ifdef BLKSSZGET if (ioctl(fd, BLKSSZGET, §or_size) >= 0) { - bs->request_alignment = sector_size; + return sector_size; } #endif #ifdef DKIOCGETBLOCKSIZE if (ioctl(fd, DKIOCGETBLOCKSIZE, §or_size) >= 0) { - bs->request_alignment = sector_size; + return sector_size; } #endif #ifdef DIOCGSECTORSIZE if (ioctl(fd, DIOCGSECTORSIZE, §or_size) >= 0) { - bs->request_alignment = sector_size; + return sector_size; } #endif #ifdef CONFIG_XFS if (s->is_xfs) { struct dioattr da; if (xfsctl(NULL, fd, XFS_IOC_DIOINFO, &da) >= 0) { - bs->request_alignment = da.d_miniosz; + sector_size = da.d_miniosz; /* The kernel returns wrong information for d_mem */ /* s->buf_align = da.d_mem; */ + return sector_size; } } #endif + return 0; +} + +static unsigned int probe_physical_blocksize(BlockDriverState *bs, int fd) +{ + unsigned int blk_size = 0; +#ifdef BLKPBSZGET + if (ioctl(fd, BLKPBSZGET, &blk_size) >= 0) { + return blk_size; + } +#endif + + return 0; +} + +static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp) +{ + BDRVRawState *s = bs->opaque; + char *buf; + + /* For /dev/sg devices the alignment is not really used. + With buffered I/O, we don't have any restrictions. */ + if (bs->sg || !(s->open_flags & O_DIRECT)) { + bs->request_alignment = 1; + s->buf_align = 1; + return; + } + + s->buf_align = 0; + /* Let's try to use the logical blocksize for the alignment. */ + bs->request_alignment = probe_logical_blocksize(bs, fd); + /* If we could not get the sizes so far, we can only guess them */ if (!s->buf_align) { size_t align; @@ -642,6 +662,16 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) bs->bl.opt_mem_alignment = s->buf_align; } +static int hdev_probe_blocksizes(BlockDriverState *bs) +{ + BDRVRawState *s = bs->opaque; + + bs->logical_block_size = probe_logical_blocksize(bs, s->fd); + bs->physical_block_size = probe_physical_blocksize(bs, s->fd); + + return 0; +} + static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb) { int ret; @@ -2009,6 +2039,7 @@ static BlockDriver bdrv_host_device = { .bdrv_get_info = raw_get_info, .bdrv_get_allocated_file_size = raw_get_allocated_file_size, + .bdrv_probe_blocksizes = hdev_probe_blocksizes, .bdrv_detach_aio_context = raw_detach_aio_context, .bdrv_attach_aio_context = raw_attach_aio_context, diff --git a/block/raw_bsd.c b/block/raw_bsd.c index f82f4c2..ae400a6 100644 --- a/block/raw_bsd.c +++ b/block/raw_bsd.c @@ -173,6 +173,19 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename) return 1; } +static int raw_probe_blocksizes(BlockDriverState *bs) +{ + int ret; + + ret = bdrv_probe_blocksizes(bs->file); + if (ret == 0) { + bs->logical_block_size = bs->file->logical_block_size; + bs->physical_block_size = bs->file->physical_block_size; + } + + return ret; +} + static BlockDriver bdrv_raw = { .format_name = "raw", .bdrv_probe = &raw_probe, @@ -190,6 +203,7 @@ static BlockDriver bdrv_raw = { .has_variable_length = true, .bdrv_get_info = &raw_get_info, .bdrv_refresh_limits = &raw_refresh_limits, + .bdrv_probe_blocksizes = &raw_probe_blocksizes, .bdrv_is_inserted = &raw_is_inserted, .bdrv_media_changed = &raw_media_changed, .bdrv_eject = &raw_eject, -- 1.8.5.5