[libvirt] [PATCH v2] storage: Fix iscsi-direct volume size for volumes > 4GiB

Jiri Denemark jdenemar at redhat.com
Thu Feb 28 15:10:05 UTC 2019


Both block_size and nb_block are unit32_t and multiplying them overflows
at 4GiB.

Moreover, the iscsi_*10_* APIs use 32bit number of blocks and thus they
can only address images up to 2TiB with 512B blocks. Let's use 64b
iscsi_*16_* APIs instead.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---

Notes:
    Version 2:
    - also fix volumes > 2TiB

 src/storage/storage_backend_iscsi_direct.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/storage/storage_backend_iscsi_direct.c b/src/storage/storage_backend_iscsi_direct.c
index 32ceb592d9..786663534d 100644
--- a/src/storage/storage_backend_iscsi_direct.c
+++ b/src/storage/storage_backend_iscsi_direct.c
@@ -245,7 +245,7 @@ static int
 virISCSIDirectGetVolumeCapacity(struct iscsi_context *iscsi,
                                 int lun,
                                 uint32_t *block_size,
-                                uint32_t *nb_block)
+                                uint64_t *nb_block)
 {
     struct scsi_task *task = NULL;
     struct scsi_inquiry_standard *inq = NULL;
@@ -267,12 +267,12 @@ virISCSIDirectGetVolumeCapacity(struct iscsi_context *iscsi,
     }
 
     if (inq->device_type == SCSI_INQUIRY_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS) {
-        struct scsi_readcapacity10 *rc10 = NULL;
+        struct scsi_readcapacity16 *rc16 = NULL;
 
         scsi_free_scsi_task(task);
         task = NULL;
 
-        if (!(task = iscsi_readcapacity10_sync(iscsi, lun, 0, 0)) ||
+        if (!(task = iscsi_readcapacity16_sync(iscsi, lun)) ||
             task->status != SCSI_STATUS_GOOD) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Failed to get capacity of lun: %s"),
@@ -280,15 +280,15 @@ virISCSIDirectGetVolumeCapacity(struct iscsi_context *iscsi,
             goto cleanup;
         }
 
-        if (!(rc10 = scsi_datain_unmarshall(task))) {
+        if (!(rc16 = scsi_datain_unmarshall(task))) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Failed to unmarshall reply: %s"),
                            iscsi_get_error(iscsi));
             goto cleanup;
         }
 
-        *block_size  = rc10->block_size;
-        *nb_block = rc10->lba;
+        *block_size  = rc16->block_length;
+        *nb_block = rc16->returned_lba;
 
     }
 
@@ -306,7 +306,7 @@ virISCSIDirectRefreshVol(virStoragePoolObjPtr pool,
 {
     virStoragePoolDefPtr def = virStoragePoolObjGetDef(pool);
     uint32_t block_size;
-    uint32_t nb_block;
+    uint64_t nb_block;
     VIR_AUTOPTR(virStorageVolDef) vol = NULL;
 
     if (virISCSIDirectTestUnitReady(iscsi, lun) < 0)
@@ -627,9 +627,9 @@ static int
 virStorageBackendISCSIDirectVolWipeZero(virStorageVolDefPtr vol,
                                         struct iscsi_context *iscsi)
 {
-    uint32_t lba = 0;
+    uint64_t lba = 0;
     uint32_t block_size;
-    uint32_t nb_block;
+    uint64_t nb_block;
     struct scsi_task *task = NULL;
     int lun = 0;
     int ret = -1;
@@ -647,14 +647,14 @@ virStorageBackendISCSIDirectVolWipeZero(virStorageVolDefPtr vol,
     while (lba < nb_block) {
         if (nb_block - lba > block_size * BLOCK_PER_PACKET) {
 
-            if (!(task = iscsi_write10_sync(iscsi, lun, lba, data,
+            if (!(task = iscsi_write16_sync(iscsi, lun, lba, data,
                                             block_size * BLOCK_PER_PACKET,
                                             block_size, 0, 0, 0, 0, 0)))
                 return -1;
             scsi_free_scsi_task(task);
             lba += BLOCK_PER_PACKET;
         } else {
-            if (!(task = iscsi_write10_sync(iscsi, lun, lba, data, block_size,
+            if (!(task = iscsi_write16_sync(iscsi, lun, lba, data, block_size,
                                         block_size, 0, 0, 0, 0, 0)))
                 return -1;
             scsi_free_scsi_task(task);
-- 
2.21.0




More information about the libvir-list mailing list