aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/file-posix.c17
-rw-r--r--include/block/block.h1
2 files changed, 11 insertions, 7 deletions
diff --git a/block/file-posix.c b/block/file-posix.c
index 28b47d977b..9f83725fc4 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -651,12 +651,15 @@ static void raw_reopen_abort(BDRVReopenState *state)
state->opaque = NULL;
}
-static int hdev_get_max_transfer_length(int fd)
+static int hdev_get_max_transfer_length(BlockDriverState *bs, int fd)
{
#ifdef BLKSECTGET
- int max_sectors = 0;
- if (ioctl(fd, BLKSECTGET, &max_sectors) == 0) {
- return max_sectors;
+ int max_bytes = 0;
+ short max_sectors = 0;
+ if (bs->sg && ioctl(fd, BLKSECTGET, &max_bytes) == 0) {
+ return max_bytes;
+ } else if (!bs->sg && ioctl(fd, BLKSECTGET, &max_sectors) == 0) {
+ return max_sectors << BDRV_SECTOR_BITS;
} else {
return -errno;
}
@@ -672,9 +675,9 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
if (!fstat(s->fd, &st)) {
if (S_ISBLK(st.st_mode)) {
- int ret = hdev_get_max_transfer_length(s->fd);
- if (ret > 0 && ret <= BDRV_REQUEST_MAX_SECTORS) {
- bs->bl.max_transfer = pow2floor(ret << BDRV_SECTOR_BITS);
+ int ret = hdev_get_max_transfer_length(bs, s->fd);
+ if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
+ bs->bl.max_transfer = pow2floor(ret);
}
}
}
diff --git a/include/block/block.h b/include/block/block.h
index 8b0dcdaa70..4e81f2069b 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -116,6 +116,7 @@ typedef struct HDGeometry {
#define BDRV_REQUEST_MAX_SECTORS MIN(SIZE_MAX >> BDRV_SECTOR_BITS, \
INT_MAX >> BDRV_SECTOR_BITS)
+#define BDRV_REQUEST_MAX_BYTES (BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS)
/*
* Allocation status flags