提交 f8e1f533 编写于 作者: P Paolo Bonzini

scsi-disk: provide maximum transfer length

The QEMU block layer has a limit of INT_MAX bytes per transfer.

Expose it in the block limits VPD page for both regular transfers
and WRITE SAME.
Reported-by: NMing Lei <ming.lei@canonical.com>
Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
上级 3c55fe2a
...@@ -49,6 +49,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0) ...@@ -49,6 +49,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
#define DEFAULT_DISCARD_GRANULARITY 4096 #define DEFAULT_DISCARD_GRANULARITY 4096
#define DEFAULT_MAX_UNMAP_SIZE (1 << 30) /* 1 GB */ #define DEFAULT_MAX_UNMAP_SIZE (1 << 30) /* 1 GB */
#define DEFAULT_MAX_IO_SIZE INT_MAX /* 2 GB - 1 block */
typedef struct SCSIDiskState SCSIDiskState; typedef struct SCSIDiskState SCSIDiskState;
...@@ -79,6 +80,7 @@ struct SCSIDiskState ...@@ -79,6 +80,7 @@ struct SCSIDiskState
uint64_t port_wwn; uint64_t port_wwn;
uint16_t port_index; uint16_t port_index;
uint64_t max_unmap_size; uint64_t max_unmap_size;
uint64_t max_io_size;
QEMUBH *bh; QEMUBH *bh;
char *version; char *version;
char *serial; char *serial;
...@@ -635,6 +637,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) ...@@ -635,6 +637,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
s->qdev.conf.opt_io_size / s->qdev.blocksize; s->qdev.conf.opt_io_size / s->qdev.blocksize;
unsigned int max_unmap_sectors = unsigned int max_unmap_sectors =
s->max_unmap_size / s->qdev.blocksize; s->max_unmap_size / s->qdev.blocksize;
unsigned int max_io_sectors =
s->max_io_size / s->qdev.blocksize;
if (s->qdev.type == TYPE_ROM) { if (s->qdev.type == TYPE_ROM) {
DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n", DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
...@@ -651,6 +655,12 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) ...@@ -651,6 +655,12 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
outbuf[6] = (min_io_size >> 8) & 0xff; outbuf[6] = (min_io_size >> 8) & 0xff;
outbuf[7] = min_io_size & 0xff; outbuf[7] = min_io_size & 0xff;
/* maximum transfer length */
outbuf[8] = (max_io_sectors >> 24) & 0xff;
outbuf[9] = (max_io_sectors >> 16) & 0xff;
outbuf[10] = (max_io_sectors >> 8) & 0xff;
outbuf[11] = max_io_sectors & 0xff;
/* optimal transfer length */ /* optimal transfer length */
outbuf[12] = (opt_io_size >> 24) & 0xff; outbuf[12] = (opt_io_size >> 24) & 0xff;
outbuf[13] = (opt_io_size >> 16) & 0xff; outbuf[13] = (opt_io_size >> 16) & 0xff;
...@@ -674,6 +684,17 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) ...@@ -674,6 +684,17 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
outbuf[29] = (unmap_sectors >> 16) & 0xff; outbuf[29] = (unmap_sectors >> 16) & 0xff;
outbuf[30] = (unmap_sectors >> 8) & 0xff; outbuf[30] = (unmap_sectors >> 8) & 0xff;
outbuf[31] = unmap_sectors & 0xff; outbuf[31] = unmap_sectors & 0xff;
/* max write same size */
outbuf[36] = 0;
outbuf[37] = 0;
outbuf[38] = 0;
outbuf[39] = 0;
outbuf[40] = (max_io_sectors >> 24) & 0xff;
outbuf[41] = (max_io_sectors >> 16) & 0xff;
outbuf[42] = (max_io_sectors >> 8) & 0xff;
outbuf[43] = max_io_sectors & 0xff;
break; break;
} }
case 0xb2: /* thin provisioning */ case 0xb2: /* thin provisioning */
...@@ -2579,6 +2600,8 @@ static Property scsi_hd_properties[] = { ...@@ -2579,6 +2600,8 @@ static Property scsi_hd_properties[] = {
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0), DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size, DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
DEFAULT_MAX_UNMAP_SIZE), DEFAULT_MAX_UNMAP_SIZE),
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
DEFAULT_MAX_IO_SIZE),
DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf), DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };
...@@ -2625,6 +2648,8 @@ static Property scsi_cd_properties[] = { ...@@ -2625,6 +2648,8 @@ static Property scsi_cd_properties[] = {
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0), DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, port_wwn, 0), DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, port_wwn, 0),
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0), DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
DEFAULT_MAX_IO_SIZE),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };
...@@ -2690,6 +2715,8 @@ static Property scsi_disk_properties[] = { ...@@ -2690,6 +2715,8 @@ static Property scsi_disk_properties[] = {
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0), DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size, DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
DEFAULT_MAX_UNMAP_SIZE), DEFAULT_MAX_UNMAP_SIZE),
DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
DEFAULT_MAX_IO_SIZE),
DEFINE_PROP_END_OF_LIST(), DEFINE_PROP_END_OF_LIST(),
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册