Index: /trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp
===================================================================
--- /trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp	(revision 23593)
+++ /trunk/src/VBox/Devices/Storage/ISCSIHDDCore.cpp	(revision 23594)
@@ -108,5 +108,6 @@
 
 
-/** Maximum PDU payload size we can handle in one piece. */
+/** Maximum PDU payload size we can handle in one piece. Greater or equal than
+ * s_iscsiConfigDefaultWriteSplit. */
 #define ISCSI_DATA_LENGTH_MAX _256K
 
@@ -280,4 +281,8 @@
     /** Length of the secret for authenticating the Initiator. */
     size_t              cbTargetSecret;
+    /** Limit for iSCSI writes, essentially limiting the amount of data
+     * written in a single write. This is negotiated with the target, so
+     * the actual size might be smaller. */
+    uint32_t            cbWriteSplit;
     /** Initiator session identifier. */
     uint64_t            ISID;
@@ -424,4 +429,7 @@
 static const char *s_iscsiConfigDefaultTimeout = "10000";
 
+/** Default write split value, less or equal to ISCSI_DATA_LENGTH_MAX. */
+static const char *s_iscsiConfigDefaultWriteSplit = "262144";
+
 /** Default host IP stack. */
 static const char *s_iscsiConfigDefaultHostIPStack = "1";
@@ -439,4 +447,5 @@
     { "TargetUsername",     NULL,                               VDCFGVALUETYPE_STRING,  VD_CFGKEY_EXPERT },
     { "TargetSecret",       NULL,                               VDCFGVALUETYPE_BYTES,   VD_CFGKEY_EXPERT },
+    { "WriteSplit",         s_iscsiConfigDefaultWriteSplit,     VDCFGVALUETYPE_INTEGER, VD_CFGKEY_EXPERT },
     { "Timeout",            s_iscsiConfigDefaultTimeout,        VDCFGVALUETYPE_INTEGER, VD_CFGKEY_EXPERT },
     { "HostIPStack",        s_iscsiConfigDefaultHostIPStack,    VDCFGVALUETYPE_INTEGER, VD_CFGKEY_EXPERT },
@@ -838,5 +847,5 @@
     bool fParameterNeg = true;;
     pImage->cbRecvDataLength = ISCSI_DATA_LENGTH_MAX;
-    pImage->cbSendDataLength = ISCSI_DATA_LENGTH_MAX;
+    pImage->cbSendDataLength = RT_MIN(ISCSI_DATA_LENGTH_MAX, pImage->cbWriteSplit);
     char szMaxDataLength[16];
     RTStrPrintf(szMaxDataLength, sizeof(szMaxDataLength), "%u", ISCSI_DATA_LENGTH_MAX);
@@ -2215,7 +2224,10 @@
     char *pszLUN = NULL, *pszLUNInitial = NULL;
     bool fLunEncoded = false;
+    uint32_t uWriteSplitDef = 0;
     uint32_t uTimeoutDef = 0;
     uint64_t uHostIPTmp = 0;
     bool fHostIPDef = 0;
+    rc = RTStrToUInt32Full(s_iscsiConfigDefaultWriteSplit, 0, &uWriteSplitDef);
+    AssertRC(rc);
     rc = RTStrToUInt32Full(s_iscsiConfigDefaultTimeout, 0, &uTimeoutDef);
     AssertRC(rc);
@@ -2271,5 +2283,5 @@
     if (!VDCFGAreKeysValid(pImage->pInterfaceConfigCallbacks,
                            pImage->pInterfaceConfig->pvUser,
-                           "TargetName\0InitiatorName\0LUN\0TargetAddress\0InitiatorUsername\0InitiatorSecret\0TargetUsername\0TargetSecret\0Timeout\0HostIPStack\0"))
+                           "TargetName\0InitiatorName\0LUN\0TargetAddress\0InitiatorUsername\0InitiatorSecret\0TargetUsername\0TargetSecret\0WriteSplit\0Timeout\0HostIPStack\0"))
     {
         rc = iscsiError(pImage, VERR_VD_ISCSI_UNKNOWN_CFG_VALUES, RT_SRC_POS, N_("iSCSI: configuration error: unknown configuration keys present"));
@@ -2389,4 +2401,13 @@
     {
         rc = iscsiError(pImage, rc, RT_SRC_POS, N_("iSCSI: configuration error: failed to read TargetSecret as byte string"));
+        goto out;
+    }
+    rc = VDCFGQueryU32Def(pImage->pInterfaceConfigCallbacks,
+                          pImage->pInterfaceConfig->pvUser,
+                          "WriteSplit", &pImage->cbWriteSplit,
+                          uWriteSplitDef);
+    if (RT_FAILURE(rc))
+    {
+        rc = iscsiError(pImage, rc, RT_SRC_POS, N_("iSCSI: configuration error: failed to read WriteSplit as U32"));
         goto out;
     }
