[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 33/69] block: Add driver methods to probe blocksizes
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PULL 33/69] block: Add driver methods to probe blocksizes and geometry |
Date: |
Fri, 27 Feb 2015 18:18:31 +0000 |
From: Ekaterina Tumanova <address@hidden>
Introduce driver methods of defining disk blocksizes (physical and
logical) and hard drive geometry.
Methods are only implemented for "host_device". For "raw" devices
driver calls child's method.
For now geometry detection will only work for DASD devices. To check
that a local check_for_dasd function was introduced. It calls BIODASDINFO2
ioctl and returns its rc.
Blocksizes detection function will probe sizes for DASD devices.
Signed-off-by: Ekaterina Tumanova <address@hidden>
Reviewed-by: Markus Armbruster <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
Message-id: address@hidden
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
block/raw-posix.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
block/raw_bsd.c | 12 +++++++
2 files changed, 115 insertions(+)
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 34d403d..3263d2b 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -56,6 +56,10 @@
#include <linux/cdrom.h>
#include <linux/fd.h>
#include <linux/fs.h>
+#include <linux/hdreg.h>
+#ifdef __s390__
+#include <asm/dasd.h>
+#endif
#ifndef FS_NOCOW_FL
#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
#endif
@@ -251,6 +255,23 @@ static int probe_logical_blocksize(int fd, unsigned int
*sector_size_p)
return success ? 0 : -errno;
}
+/**
+ * Get physical block size of @fd.
+ * On success, store it in @blk_size and return 0.
+ * On failure, return -errno.
+ */
+static int probe_physical_blocksize(int fd, unsigned int *blk_size)
+{
+#ifdef BLKPBSZGET
+ if (ioctl(fd, BLKPBSZGET, blk_size) < 0) {
+ return -errno;
+ }
+ return 0;
+#else
+ return -ENOTSUP;
+#endif
+}
+
static void raw_probe_alignment(BlockDriverState *bs, int fd, Error **errp)
{
BDRVRawState *s = bs->opaque;
@@ -674,6 +695,86 @@ static void raw_refresh_limits(BlockDriverState *bs, Error
**errp)
bs->bl.opt_mem_alignment = s->buf_align;
}
+static int check_for_dasd(int fd)
+{
+#ifdef BIODASDINFO2
+ struct dasd_information2_t info = {0};
+
+ return ioctl(fd, BIODASDINFO2, &info);
+#else
+ return -1;
+#endif
+}
+
+/**
+ * Try to get @bs's logical and physical block size.
+ * On success, store them in @bsz and return zero.
+ * On failure, return negative errno.
+ */
+static int hdev_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz)
+{
+ BDRVRawState *s = bs->opaque;
+ int ret;
+
+ /* If DASD, get blocksizes */
+ if (check_for_dasd(s->fd) < 0) {
+ return -ENOTSUP;
+ }
+ ret = probe_logical_blocksize(s->fd, &bsz->log);
+ if (ret < 0) {
+ return ret;
+ }
+ return probe_physical_blocksize(s->fd, &bsz->phys);
+}
+
+/**
+ * Try to get @bs's geometry: cyls, heads, sectors.
+ * On success, store them in @geo and return 0.
+ * On failure return -errno.
+ * (Allows block driver to assign default geometry values that guest sees)
+ */
+#ifdef __linux__
+static int hdev_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
+{
+ BDRVRawState *s = bs->opaque;
+ struct hd_geometry ioctl_geo = {0};
+ uint32_t blksize;
+
+ /* If DASD, get its geometry */
+ if (check_for_dasd(s->fd) < 0) {
+ return -ENOTSUP;
+ }
+ if (ioctl(s->fd, HDIO_GETGEO, &ioctl_geo) < 0) {
+ return -errno;
+ }
+ /* HDIO_GETGEO may return success even though geo contains zeros
+ (e.g. certain multipath setups) */
+ if (!ioctl_geo.heads || !ioctl_geo.sectors || !ioctl_geo.cylinders) {
+ return -ENOTSUP;
+ }
+ /* Do not return a geometry for partition */
+ if (ioctl_geo.start != 0) {
+ return -ENOTSUP;
+ }
+ geo->heads = ioctl_geo.heads;
+ geo->sectors = ioctl_geo.sectors;
+ if (!probe_physical_blocksize(s->fd, &blksize)) {
+ /* overwrite cyls: HDIO_GETGEO result is incorrect for big drives */
+ geo->cylinders = bdrv_nb_sectors(bs) / (blksize / BDRV_SECTOR_SIZE)
+ / (geo->heads * geo->sectors);
+ return 0;
+ }
+ geo->cylinders = ioctl_geo.cylinders;
+
+ return 0;
+}
+#else /* __linux__ */
+static int hdev_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
+{
+ return -ENOTSUP;
+}
+#endif
+
static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb)
{
int ret;
@@ -2215,6 +2316,8 @@ 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_probe_geometry = hdev_probe_geometry,
.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 05b02c7..e3d2d04 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -235,6 +235,16 @@ static int raw_probe(const uint8_t *buf, int buf_size,
const char *filename)
return 1;
}
+static int raw_probe_blocksizes(BlockDriverState *bs, BlockSizes *bsz)
+{
+ return bdrv_probe_blocksizes(bs->file, bsz);
+}
+
+static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)
+{
+ return bdrv_probe_geometry(bs->file, geo);
+}
+
BlockDriver bdrv_raw = {
.format_name = "raw",
.bdrv_probe = &raw_probe,
@@ -252,6 +262,8 @@ 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_probe_geometry = &raw_probe_geometry,
.bdrv_is_inserted = &raw_is_inserted,
.bdrv_media_changed = &raw_media_changed,
.bdrv_eject = &raw_eject,
--
2.1.0
- [Qemu-devel] [PULL 24/69] qcow2: Open images with refcount order != 4, (continued)
- [Qemu-devel] [PULL 24/69] qcow2: Open images with refcount order != 4, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 26/69] qcow2: Use symbolic macros in qcow2_amend_options, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 23/69] qcow2: More helpers for refcount modification, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 25/69] qcow2: refcount_order parameter for qcow2_create2, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 28/69] qcow2: Allow creation with refcount order != 4, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 29/69] iotests: Add test for different refcount widths, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 27/69] iotests: Prepare for refcount_bits option, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 31/69] block: add bdrv functions for geometry and blocksize, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 30/69] blkdebug: fix "once" rule, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 34/69] block-backend: Add wrappers for blocksizes and geometry probing, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 33/69] block: Add driver methods to probe blocksizes and geometry,
Stefan Hajnoczi <=
- [Qemu-devel] [PULL 39/69] ide: do not use BMDMA in restart callback, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 36/69] ide: start extracting ide_restart_dma out of bmdma_restart_dma, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 37/69] ide: prepare to move restart to common code, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 38/69] ide: introduce ide_register_restart_cb, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 40/69] ide: pass IDEBus to the restart_cb, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 42/69] ide: remove restart_cb callback, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 41/69] ide: move restart callback to common code, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 32/69] raw-posix: Factor block size detection out of raw_probe_alignment(), Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 43/69] ide: replace set_unit callback with more IDEBus state, Stefan Hajnoczi, 2015/02/27
- [Qemu-devel] [PULL 44/69] ide: place initial state of the current request to IDEBus, Stefan Hajnoczi, 2015/02/27