aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/iscsi_tcp.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-08-31 18:09:24 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-02 14:37:04 -0400
commitffd0436ed2e5a741c8d30062b489b989acf0a526 (patch)
tree037433a76a116c67d3f074c5a83305be8241a8e5 /drivers/scsi/iscsi_tcp.c
parente5b3cd42960a10c1bc3701d4f00767463c88ec9d (diff)
[SCSI] libiscsi, iscsi_tcp, iscsi_iser: check that burst lengths are valid.
iSCSI RFC states that the first burst length must be smaller than the max burst length. We currently assume targets will be good, but that may not be the case, so this patch adds a check. This patch also moves the unsol data out offset to the lib so the LLDs do not have to track it. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/iscsi_tcp.c')
-rw-r--r--drivers/scsi/iscsi_tcp.c30
1 files changed, 7 insertions, 23 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 058f094f945a..a97a3a4e99eb 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -1264,19 +1264,6 @@ iscsi_solicit_data_cont(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
1264 r2t->data_count); 1264 r2t->data_count);
1265} 1265}
1266 1266
1267static void
1268iscsi_unsolicit_data_init(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1269{
1270 struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
1271 struct iscsi_data_task *dtask;
1272
1273 dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask;
1274 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr,
1275 tcp_ctask->r2t_data_count);
1276 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr,
1277 sizeof(struct iscsi_hdr));
1278}
1279
1280/** 1267/**
1281 * iscsi_tcp_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands 1268 * iscsi_tcp_cmd_init - Initialize iSCSI SCSI_READ or SCSI_WRITE commands
1282 * @conn: iscsi connection 1269 * @conn: iscsi connection
@@ -1326,14 +1313,11 @@ iscsi_tcp_cmd_init(struct iscsi_cmd_task *ctask)
1326 if (ctask->unsol_count) 1313 if (ctask->unsol_count)
1327 tcp_ctask->xmstate |= XMSTATE_UNS_HDR | 1314 tcp_ctask->xmstate |= XMSTATE_UNS_HDR |
1328 XMSTATE_UNS_INIT; 1315 XMSTATE_UNS_INIT;
1329 tcp_ctask->r2t_data_count = ctask->total_length -
1330 ctask->imm_count -
1331 ctask->unsol_count;
1332 1316
1333 debug_scsi("cmd [itt 0x%x total %d imm %d imm_data %d " 1317 debug_scsi("cmd [itt 0x%x total %d imm_data %d "
1334 "r2t_data %d]\n", 1318 "unsol count %d, unsol offset %d]\n",
1335 ctask->itt, ctask->total_length, ctask->imm_count, 1319 ctask->itt, ctask->total_length, ctask->imm_count,
1336 ctask->unsol_count, tcp_ctask->r2t_data_count); 1320 ctask->unsol_count, ctask->unsol_offset);
1337 } else 1321 } else
1338 tcp_ctask->xmstate = XMSTATE_R_HDR; 1322 tcp_ctask->xmstate = XMSTATE_R_HDR;
1339 1323
@@ -1531,8 +1515,10 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
1531 1515
1532 tcp_ctask->xmstate |= XMSTATE_UNS_DATA; 1516 tcp_ctask->xmstate |= XMSTATE_UNS_DATA;
1533 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { 1517 if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) {
1534 iscsi_unsolicit_data_init(conn, ctask); 1518 dtask = tcp_ctask->dtask = &tcp_ctask->unsol_dtask;
1535 dtask = tcp_ctask->dtask; 1519 iscsi_prep_unsolicit_data_pdu(ctask, &dtask->hdr);
1520 iscsi_buf_init_iov(&tcp_ctask->headbuf, (char*)&dtask->hdr,
1521 sizeof(struct iscsi_hdr));
1536 if (conn->hdrdgst_en) 1522 if (conn->hdrdgst_en)
1537 iscsi_hdr_digest(conn, &tcp_ctask->headbuf, 1523 iscsi_hdr_digest(conn, &tcp_ctask->headbuf,
1538 (u8*)dtask->hdrext); 1524 (u8*)dtask->hdrext);
@@ -1720,7 +1706,6 @@ data_out_done:
1720 * Done with this R2T. Check if there are more 1706 * Done with this R2T. Check if there are more
1721 * outstanding R2Ts ready to be processed. 1707 * outstanding R2Ts ready to be processed.
1722 */ 1708 */
1723 BUG_ON(tcp_ctask->r2t_data_count - r2t->data_length < 0);
1724 if (conn->datadgst_en) { 1709 if (conn->datadgst_en) {
1725 rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, 1710 rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf,
1726 &dtask->digest, 1); 1711 &dtask->digest, 1);
@@ -1732,7 +1717,6 @@ data_out_done:
1732 debug_tcp("r2t done dout digest 0x%x\n", dtask->digest); 1717 debug_tcp("r2t done dout digest 0x%x\n", dtask->digest);
1733 } 1718 }
1734 1719
1735 tcp_ctask->r2t_data_count -= r2t->data_length;
1736 tcp_ctask->r2t = NULL; 1720 tcp_ctask->r2t = NULL;
1737 spin_lock_bh(&session->lock); 1721 spin_lock_bh(&session->lock);
1738 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*)); 1722 __kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t, sizeof(void*));