@@ -1004,8 +1004,10 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
1004
1004
unsigned char * buf )
1005
1005
{
1006
1006
int data_direction , payload_length ;
1007
+ struct iscsi_ecdb_ahdr * ecdb_ahdr ;
1007
1008
struct iscsi_scsi_req * hdr ;
1008
1009
int iscsi_task_attr ;
1010
+ unsigned char * cdb ;
1009
1011
int sam_task_attr ;
1010
1012
1011
1013
atomic_long_inc (& conn -> sess -> cmd_pdus );
@@ -1106,6 +1108,27 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
1106
1108
ISCSI_REASON_BOOKMARK_INVALID , buf );
1107
1109
}
1108
1110
1111
+ cdb = hdr -> cdb ;
1112
+
1113
+ if (hdr -> hlength ) {
1114
+ ecdb_ahdr = (struct iscsi_ecdb_ahdr * ) (hdr + 1 );
1115
+ if (ecdb_ahdr -> ahstype != ISCSI_AHSTYPE_CDB ) {
1116
+ pr_err ("Additional Header Segment type %d not supported!\n" ,
1117
+ ecdb_ahdr -> ahstype );
1118
+ return iscsit_add_reject_cmd (cmd ,
1119
+ ISCSI_REASON_CMD_NOT_SUPPORTED , buf );
1120
+ }
1121
+
1122
+ cdb = kmalloc (be16_to_cpu (ecdb_ahdr -> ahslength ) + 15 ,
1123
+ GFP_KERNEL );
1124
+ if (cdb == NULL )
1125
+ return iscsit_add_reject_cmd (cmd ,
1126
+ ISCSI_REASON_BOOKMARK_NO_RESOURCES , buf );
1127
+ memcpy (cdb , hdr -> cdb , ISCSI_CDB_SIZE );
1128
+ memcpy (cdb + ISCSI_CDB_SIZE , ecdb_ahdr -> ecdb ,
1129
+ be16_to_cpu (ecdb_ahdr -> ahslength ) - 1 );
1130
+ }
1131
+
1109
1132
data_direction = (hdr -> flags & ISCSI_FLAG_CMD_WRITE ) ? DMA_TO_DEVICE :
1110
1133
(hdr -> flags & ISCSI_FLAG_CMD_READ ) ? DMA_FROM_DEVICE :
1111
1134
DMA_NONE ;
@@ -1153,9 +1176,12 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
1153
1176
struct iscsi_datain_req * dr ;
1154
1177
1155
1178
dr = iscsit_allocate_datain_req ();
1156
- if (!dr )
1179
+ if (!dr ) {
1180
+ if (cdb != hdr -> cdb )
1181
+ kfree (cdb );
1157
1182
return iscsit_add_reject_cmd (cmd ,
1158
1183
ISCSI_REASON_BOOKMARK_NO_RESOURCES , buf );
1184
+ }
1159
1185
1160
1186
iscsit_attach_datain_req (cmd , dr );
1161
1187
}
@@ -1176,9 +1202,12 @@ int iscsit_setup_scsi_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd,
1176
1202
target_get_sess_cmd (& cmd -> se_cmd , true);
1177
1203
1178
1204
cmd -> se_cmd .tag = (__force u32 )cmd -> init_task_tag ;
1179
- cmd -> sense_reason = target_cmd_init_cdb (& cmd -> se_cmd , hdr -> cdb ,
1205
+ cmd -> sense_reason = target_cmd_init_cdb (& cmd -> se_cmd , cdb ,
1180
1206
GFP_KERNEL );
1181
1207
1208
+ if (cdb != hdr -> cdb )
1209
+ kfree (cdb );
1210
+
1182
1211
if (cmd -> sense_reason ) {
1183
1212
if (cmd -> sense_reason == TCM_OUT_OF_RESOURCES ) {
1184
1213
return iscsit_add_reject_cmd (cmd ,
@@ -4036,8 +4065,9 @@ static bool iscsi_target_check_conn_state(struct iscsit_conn *conn)
4036
4065
static void iscsit_get_rx_pdu (struct iscsit_conn * conn )
4037
4066
{
4038
4067
int ret ;
4039
- u8 * buffer , opcode ;
4068
+ u8 * buffer , * tmp_buf , opcode ;
4040
4069
u32 checksum = 0 , digest = 0 ;
4070
+ struct iscsi_hdr * hdr ;
4041
4071
struct kvec iov ;
4042
4072
4043
4073
buffer = kcalloc (ISCSI_HDR_LEN , sizeof (* buffer ), GFP_KERNEL );
@@ -4062,6 +4092,25 @@ static void iscsit_get_rx_pdu(struct iscsit_conn *conn)
4062
4092
break ;
4063
4093
}
4064
4094
4095
+ hdr = (struct iscsi_hdr * ) buffer ;
4096
+ if (hdr -> hlength ) {
4097
+ iov .iov_len = hdr -> hlength * 4 ;
4098
+ tmp_buf = krealloc (buffer ,
4099
+ ISCSI_HDR_LEN + iov .iov_len ,
4100
+ GFP_KERNEL );
4101
+ if (!tmp_buf )
4102
+ break ;
4103
+
4104
+ buffer = tmp_buf ;
4105
+ iov .iov_base = & buffer [ISCSI_HDR_LEN ];
4106
+
4107
+ ret = rx_data (conn , & iov , 1 , iov .iov_len );
4108
+ if (ret != iov .iov_len ) {
4109
+ iscsit_rx_thread_wait_for_tcp (conn );
4110
+ break ;
4111
+ }
4112
+ }
4113
+
4065
4114
if (conn -> conn_ops -> HeaderDigest ) {
4066
4115
iov .iov_base = & digest ;
4067
4116
iov .iov_len = ISCSI_CRC_LEN ;
0 commit comments