~yolanda.robla/ubuntu/saucy/ipxe/ftbfs

« back to all changes in this revision

Viewing changes to debian/patches/iscsi-send-padding-inline.patch

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2012-09-06 21:46:54 UTC
  • Revision ID: package-import@ubuntu.com-20120906214654-yay0va8kbzfp99ei
Tags: 1.0.0+git-3.55f6c88-0ubuntu5
* Fix input/output errors when using ipxe to boot from iSCSI storage
  (LP: #1045923).
  - d/p/iscsi-{report-reponse,send-padding-inline}.patch: Cherry picked
    patches from upstream VCS which resolve two issues with iSCSI protocol
    handling.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From 1d293776ea290ae1f4d1228f3278030facf97a4b Mon Sep 17 00:00:00 2001
 
2
From: Michael Brown <mcb30@ipxe.org>
 
3
Date: Thu, 1 Mar 2012 16:26:38 +0000
 
4
Subject: [PATCH] [iscsi] Send any padding inline with the data segment
 
5
 
 
6
Some iSCSI targets respond to a PDU before receiving the padding
 
7
bytes.  If the target responds quickly enough, this can cause iPXE to
 
8
start processing a new TX PDU before the padding bytes have been sent,
 
9
which results in a protocol violation.
 
10
 
 
11
Fix by always transmitting the padding bytes along with the data
 
12
segment.
 
13
 
 
14
Originally-fixed-by: Shyam Iyer <shyam_iyer@dell.com>
 
15
Signed-off-by: Michael Brown <mcb30@ipxe.org>
 
16
---
 
17
 src/include/ipxe/iscsi.h |    2 --
 
18
 src/net/tcp/iscsi.c      |   37 +++++++++----------------------------
 
19
 2 files changed, 9 insertions(+), 30 deletions(-)
 
20
 
 
21
diff --git a/src/include/ipxe/iscsi.h b/src/include/ipxe/iscsi.h
 
22
index 5d3d73b..b4de793 100644
 
23
--- a/src/include/ipxe/iscsi.h
 
24
+++ b/src/include/ipxe/iscsi.h
 
25
@@ -515,8 +515,6 @@ enum iscsi_tx_state {
 
26
        ISCSI_TX_AHS,
 
27
        /** Sending the data segment */
 
28
        ISCSI_TX_DATA,
 
29
-       /** Sending the data segment padding */
 
30
-       ISCSI_TX_DATA_PADDING,
 
31
 };
 
32
 
 
33
 /** State of an iSCSI RX engine */
 
34
diff --git a/src/net/tcp/iscsi.c b/src/net/tcp/iscsi.c
 
35
index fa1bb39..9eaf3cc 100644
 
36
--- a/src/net/tcp/iscsi.c
 
37
+++ b/src/net/tcp/iscsi.c
 
38
@@ -570,20 +570,23 @@ static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
 
39
        struct io_buffer *iobuf;
 
40
        unsigned long offset;
 
41
        size_t len;
 
42
+       size_t pad_len;
 
43
 
 
44
        offset = ntohl ( data_out->offset );
 
45
        len = ISCSI_DATA_LEN ( data_out->lengths );
 
46
+       pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths );
 
47
 
 
48
        assert ( iscsi->command != NULL );
 
49
        assert ( iscsi->command->data_out );
 
50
        assert ( ( offset + len ) <= iscsi->command->data_out_len );
 
51
 
 
52
-       iobuf = xfer_alloc_iob ( &iscsi->socket, len );
 
53
+       iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
 
54
        if ( ! iobuf )
 
55
                return -ENOMEM;
 
56
        
 
57
        copy_from_user ( iob_put ( iobuf, len ),
 
58
                         iscsi->command->data_out, offset, len );
 
59
+       memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
 
60
 
 
61
        return xfer_deliver_iob ( &iscsi->socket, iobuf );
 
62
 }
 
63
@@ -801,13 +804,17 @@ static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
 
64
        struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request;
 
65
        struct io_buffer *iobuf;
 
66
        size_t len;
 
67
+       size_t pad_len;
 
68
 
 
69
        len = ISCSI_DATA_LEN ( request->lengths );
 
70
-       iobuf = xfer_alloc_iob ( &iscsi->socket, len );
 
71
+       pad_len = ISCSI_DATA_PAD_LEN ( request->lengths );
 
72
+       iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
 
73
        if ( ! iobuf )
 
74
                return -ENOMEM;
 
75
        iob_put ( iobuf, len );
 
76
        iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
 
77
+       memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
 
78
+
 
79
        return xfer_deliver_iob ( &iscsi->socket, iobuf );
 
80
 }
 
81
 
 
82
@@ -1416,27 +1423,6 @@ static int iscsi_tx_data ( struct iscsi_session *iscsi ) {
 
83
 }
 
84
 
 
85
 /**
 
86
- * Transmit data padding of an iSCSI PDU
 
87
- *
 
88
- * @v iscsi            iSCSI session
 
89
- * @ret rc             Return status code
 
90
- * 
 
91
- * Handle transmission of any data padding in a PDU data segment.
 
92
- * iscsi::tx_bhs will be valid when this is called.
 
93
- */
 
94
-static int iscsi_tx_data_padding ( struct iscsi_session *iscsi ) {
 
95
-       static const char pad[] = { '\0', '\0', '\0' };
 
96
-       struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
 
97
-       size_t pad_len;
 
98
-       
 
99
-       pad_len = ISCSI_DATA_PAD_LEN ( common->lengths );
 
100
-       if ( ! pad_len )
 
101
-               return 0;
 
102
-
 
103
-       return xfer_deliver_raw ( &iscsi->socket, pad, pad_len );
 
104
-}
 
105
-
 
106
-/**
 
107
  * Complete iSCSI PDU transmission
 
108
  *
 
109
  * @v iscsi            iSCSI session
 
110
@@ -1494,11 +1480,6 @@ static void iscsi_tx_step ( struct iscsi_session *iscsi ) {
 
111
                case ISCSI_TX_DATA:
 
112
                        tx = iscsi_tx_data;
 
113
                        tx_len = ISCSI_DATA_LEN ( common->lengths );
 
114
-                       next_state = ISCSI_TX_DATA_PADDING;
 
115
-                       break;
 
116
-               case ISCSI_TX_DATA_PADDING:
 
117
-                       tx = iscsi_tx_data_padding;
 
118
-                       tx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
 
119
                        next_state = ISCSI_TX_IDLE;
 
120
                        break;
 
121
                case ISCSI_TX_IDLE:
 
122
-- 
 
123
1.7.10
 
124