diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2006-08-31 18:09:24 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-09-02 14:37:04 -0400 |
commit | ffd0436ed2e5a741c8d30062b489b989acf0a526 (patch) | |
tree | 037433a76a116c67d3f074c5a83305be8241a8e5 /drivers/scsi/iscsi_tcp.c | |
parent | e5b3cd42960a10c1bc3701d4f00767463c88ec9d (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.c | 30 |
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 | ||
1267 | static void | ||
1268 | iscsi_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*)); |