@@ -34,6 +34,7 @@
#ifdef __linux__
#include <linux/hdreg.h>
+#include <linux/fs.h>
#endif
#ifdef CONFIG_BSD
@@ -2053,6 +2054,27 @@ static int guess_disk_lchs(BlockDriverState *bs,
return -1;
}
+void bdrv_guess_blocksizes(BlockConf *conf)
+{
+#ifdef __linux__
+ int block_size;
+
+ if (bdrv_ioctl(conf->bs, BLKSSZGET, &block_size) == 0) {
+ conf->logical_block_size = (uint16_t) block_size;
+ } else {
+ conf->logical_block_size = BDRV_SECTOR_SIZE;
+ }
+ if (bdrv_ioctl(conf->bs, BLKPBSZGET, &block_size) == 0) {
+ conf->physical_block_size = (uint16_t) block_size;
+ } else {
+ conf->physical_block_size = BDRV_SECTOR_SIZE;
+ }
+#else
+ conf->logical_block_size = BDRV_SECTOR_SIZE;
+ conf->physical_block_size = BDRV_SECTOR_SIZE;
+#endif
+}
+
void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
{
int translation, lba_detected = 0;
@@ -429,6 +429,7 @@ typedef struct BlockConf {
uint32_t opt_io_size;
int32_t bootindex;
uint32_t discard_granularity;
+ uint32_t use_host_sizes;
} BlockConf;
static inline unsigned int get_physical_block_exp(BlockConf *conf)
@@ -444,7 +445,9 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
return exp;
}
-#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \
+void bdrv_guess_blocksizes(BlockConf *conf);
+
+#define DEFINE_BLOCK_PROPERTIES(_state, _conf, _use_host_sizes) \
DEFINE_PROP_DRIVE("drive", _state, _conf.bs), \
DEFINE_PROP_BLOCKSIZE("logical_block_size", _state, \
_conf.logical_block_size, 512), \
@@ -454,7 +457,8 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \
DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1), \
DEFINE_PROP_UINT32("discard_granularity", _state, \
- _conf.discard_granularity, 0)
-
+ _conf.discard_granularity, 0), \
+ DEFINE_PROP_UINT32("use_host_sizes", _state, \
+ _conf.use_host_sizes, _use_host_sizes)
#endif
@@ -172,7 +172,7 @@ static int ide_drive_initfn(IDEDevice *dev)
}
#define DEFINE_IDE_DEV_PROPERTIES() \
- DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf), \
+ DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf, 0), \
DEFINE_PROP_STRING("ver", IDEDrive, dev.version), \
DEFINE_PROP_HEX64("wwn", IDEDrive, dev.wwn, 0), \
DEFINE_PROP_STRING("serial", IDEDrive, dev.serial),\
@@ -390,7 +390,7 @@ static TypeInfo s390_virtio_net = {
};
static Property s390_virtio_blk_properties[] = {
- DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block),
+ DEFINE_BLOCK_PROPERTIES(VirtIOS390Device, block, 1),
DEFINE_PROP_STRING("serial", VirtIOS390Device, block_serial),
DEFINE_PROP_END_OF_LIST(),
};
@@ -1912,7 +1912,7 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
#endif
#define DEFINE_SCSI_DISK_PROPERTIES() \
- DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf), \
+ DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf, 0), \
DEFINE_PROP_STRING("ver", SCSIDiskState, version), \
DEFINE_PROP_STRING("serial", SCSIDiskState, serial)
@@ -482,7 +482,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
}
static Property scsi_generic_properties[] = {
- DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf),
+ DEFINE_BLOCK_PROPERTIES(SCSIDevice, conf, 0),
DEFINE_PROP_END_OF_LIST(),
};
@@ -637,7 +637,7 @@ static const VMStateDescription vmstate_usb_msd = {
};
static Property msd_properties[] = {
- DEFINE_BLOCK_PROPERTIES(MSDState, conf),
+ DEFINE_BLOCK_PROPERTIES(MSDState, conf, 0),
DEFINE_PROP_STRING("serial", MSDState, serial),
DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
DEFINE_PROP_END_OF_LIST(),
@@ -612,6 +612,9 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
s->vdev.reset = virtio_blk_reset;
s->bs = conf->bs;
s->conf = conf;
+ if (s->conf->use_host_sizes) {
+ bdrv_guess_blocksizes(s->conf);
+ }
s->serial = *serial;
s->rq = NULL;
s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
@@ -814,7 +814,7 @@ static int virtio_balloon_exit_pci(PCIDevice *pci_dev)
static Property virtio_blk_properties[] = {
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
- DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
+ DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block, 0),
DEFINE_PROP_STRING("serial", VirtIOPCIProxy, block_serial),
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),