diff options
| author | Mike Christie <michaelc@cs.wisc.edu> | 2006-05-30 01:37:28 -0400 |
|---|---|---|
| committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-06-05 19:12:25 -0400 |
| commit | 3219e5294150aee7d389e19029f49b44fb6b5c9f (patch) | |
| tree | 44236fd9f2eb40d5622cadb126e9f2672b129486 | |
| parent | 040515f53c09047c76ad074dc6a280984dc84b04 (diff) | |
[SCSI] iscsi: fix writepsace race
We can race and misset the suspend bit if iscsi_write_space is
called then iscsi_send returns with a failure indicating
there is no space.
To handle this this patch returns a error upwards allowing xmitworker
to decide if we need to try and transmit again. For the no
write space case xmitworker will not retry, and instead
let iscsi_write_space queue it back up if needed (this relies
on the work queue code to properly requeue us if needed).
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
| -rw-r--r-- | drivers/scsi/iscsi_tcp.c | 182 | ||||
| -rw-r--r-- | drivers/scsi/libiscsi.c | 31 | ||||
| -rw-r--r-- | include/scsi/scsi_transport_iscsi.h | 8 |
3 files changed, 126 insertions, 95 deletions
diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 2abda804a924..7fa85937a99f 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c | |||
| @@ -1006,7 +1006,6 @@ iscsi_write_space(struct sock *sk) | |||
| 1006 | 1006 | ||
| 1007 | tcp_conn->old_write_space(sk); | 1007 | tcp_conn->old_write_space(sk); |
| 1008 | debug_tcp("iscsi_write_space: cid %d\n", conn->id); | 1008 | debug_tcp("iscsi_write_space: cid %d\n", conn->id); |
| 1009 | clear_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
| 1010 | scsi_queue_work(conn->session->host, &conn->xmitwork); | 1009 | scsi_queue_work(conn->session->host, &conn->xmitwork); |
| 1011 | } | 1010 | } |
| 1012 | 1011 | ||
| @@ -1056,7 +1055,7 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags) | |||
| 1056 | { | 1055 | { |
| 1057 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 1056 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
| 1058 | struct socket *sk = tcp_conn->sock; | 1057 | struct socket *sk = tcp_conn->sock; |
| 1059 | int offset = buf->sg.offset + buf->sent; | 1058 | int offset = buf->sg.offset + buf->sent, res; |
| 1060 | 1059 | ||
| 1061 | /* | 1060 | /* |
| 1062 | * if we got use_sg=0 or are sending something we kmallocd | 1061 | * if we got use_sg=0 or are sending something we kmallocd |
| @@ -1067,10 +1066,22 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags) | |||
| 1067 | * slab case. | 1066 | * slab case. |
| 1068 | */ | 1067 | */ |
| 1069 | if (buf->use_sendmsg) | 1068 | if (buf->use_sendmsg) |
| 1070 | return sock_no_sendpage(sk, buf->sg.page, offset, size, flags); | 1069 | res = sock_no_sendpage(sk, buf->sg.page, offset, size, flags); |
| 1071 | else | 1070 | else |
| 1072 | return tcp_conn->sendpage(sk, buf->sg.page, offset, size, | 1071 | res = tcp_conn->sendpage(sk, buf->sg.page, offset, size, flags); |
| 1073 | flags); | 1072 | |
| 1073 | if (res >= 0) { | ||
| 1074 | conn->txdata_octets += res; | ||
| 1075 | buf->sent += res; | ||
| 1076 | return res; | ||
| 1077 | } | ||
| 1078 | |||
| 1079 | tcp_conn->sendpage_failures_cnt++; | ||
| 1080 | if (res == -EAGAIN) | ||
| 1081 | res = -ENOBUFS; | ||
| 1082 | else | ||
| 1083 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | ||
| 1084 | return res; | ||
| 1074 | } | 1085 | } |
| 1075 | 1086 | ||
| 1076 | /** | 1087 | /** |
| @@ -1085,7 +1096,6 @@ iscsi_send(struct iscsi_conn *conn, struct iscsi_buf *buf, int size, int flags) | |||
| 1085 | static inline int | 1096 | static inline int |
| 1086 | iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) | 1097 | iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) |
| 1087 | { | 1098 | { |
| 1088 | struct iscsi_tcp_conn *tcp_conn; | ||
| 1089 | int flags = 0; /* MSG_DONTWAIT; */ | 1099 | int flags = 0; /* MSG_DONTWAIT; */ |
| 1090 | int res, size; | 1100 | int res, size; |
| 1091 | 1101 | ||
| @@ -1097,17 +1107,10 @@ iscsi_sendhdr(struct iscsi_conn *conn, struct iscsi_buf *buf, int datalen) | |||
| 1097 | res = iscsi_send(conn, buf, size, flags); | 1107 | res = iscsi_send(conn, buf, size, flags); |
| 1098 | debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res); | 1108 | debug_tcp("sendhdr %d bytes, sent %d res %d\n", size, buf->sent, res); |
| 1099 | if (res >= 0) { | 1109 | if (res >= 0) { |
| 1100 | conn->txdata_octets += res; | ||
| 1101 | buf->sent += res; | ||
| 1102 | if (size != res) | 1110 | if (size != res) |
| 1103 | return -EAGAIN; | 1111 | return -EAGAIN; |
| 1104 | return 0; | 1112 | return 0; |
| 1105 | } else if (res == -EAGAIN) { | 1113 | } |
| 1106 | tcp_conn = conn->dd_data; | ||
| 1107 | tcp_conn->sendpage_failures_cnt++; | ||
| 1108 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
| 1109 | } else if (res == -EPIPE) | ||
| 1110 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | ||
| 1111 | 1114 | ||
| 1112 | return res; | 1115 | return res; |
| 1113 | } | 1116 | } |
| @@ -1126,7 +1129,6 @@ static inline int | |||
| 1126 | iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, | 1129 | iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, |
| 1127 | int *count, int *sent) | 1130 | int *count, int *sent) |
| 1128 | { | 1131 | { |
| 1129 | struct iscsi_tcp_conn *tcp_conn; | ||
| 1130 | int flags = 0; /* MSG_DONTWAIT; */ | 1132 | int flags = 0; /* MSG_DONTWAIT; */ |
| 1131 | int res, size; | 1133 | int res, size; |
| 1132 | 1134 | ||
| @@ -1141,19 +1143,12 @@ iscsi_sendpage(struct iscsi_conn *conn, struct iscsi_buf *buf, | |||
| 1141 | debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n", | 1143 | debug_tcp("sendpage: %d bytes, sent %d left %d sent %d res %d\n", |
| 1142 | size, buf->sent, *count, *sent, res); | 1144 | size, buf->sent, *count, *sent, res); |
| 1143 | if (res >= 0) { | 1145 | if (res >= 0) { |
| 1144 | conn->txdata_octets += res; | ||
| 1145 | buf->sent += res; | ||
| 1146 | *count -= res; | 1146 | *count -= res; |
| 1147 | *sent += res; | 1147 | *sent += res; |
| 1148 | if (size != res) | 1148 | if (size != res) |
| 1149 | return -EAGAIN; | 1149 | return -EAGAIN; |
| 1150 | return 0; | 1150 | return 0; |
| 1151 | } else if (res == -EAGAIN) { | 1151 | } |
| 1152 | tcp_conn = conn->dd_data; | ||
| 1153 | tcp_conn->sendpage_failures_cnt++; | ||
| 1154 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | ||
| 1155 | } else if (res == -EPIPE) | ||
| 1156 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | ||
| 1157 | 1152 | ||
| 1158 | return res; | 1153 | return res; |
| 1159 | } | 1154 | } |
| @@ -1342,6 +1337,7 @@ static int | |||
| 1342 | iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) | 1337 | iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) |
| 1343 | { | 1338 | { |
| 1344 | struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; | 1339 | struct iscsi_tcp_mgmt_task *tcp_mtask = mtask->dd_data; |
| 1340 | int rc; | ||
| 1345 | 1341 | ||
| 1346 | debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n", | 1342 | debug_scsi("mtask deq [cid %d state %x itt 0x%x]\n", |
| 1347 | conn->id, tcp_mtask->xmstate, mtask->itt); | 1343 | conn->id, tcp_mtask->xmstate, mtask->itt); |
| @@ -1355,12 +1351,13 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) | |||
| 1355 | conn->hdrdgst_en) | 1351 | conn->hdrdgst_en) |
| 1356 | iscsi_hdr_digest(conn, &tcp_mtask->headbuf, | 1352 | iscsi_hdr_digest(conn, &tcp_mtask->headbuf, |
| 1357 | (u8*)tcp_mtask->hdrext); | 1353 | (u8*)tcp_mtask->hdrext); |
| 1358 | if (iscsi_sendhdr(conn, &tcp_mtask->headbuf, | 1354 | rc = iscsi_sendhdr(conn, &tcp_mtask->headbuf, |
| 1359 | mtask->data_count)) { | 1355 | mtask->data_count); |
| 1356 | if (rc) { | ||
| 1360 | tcp_mtask->xmstate |= XMSTATE_IMM_HDR; | 1357 | tcp_mtask->xmstate |= XMSTATE_IMM_HDR; |
| 1361 | if (mtask->data_count) | 1358 | if (mtask->data_count) |
| 1362 | tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA; | 1359 | tcp_mtask->xmstate &= ~XMSTATE_IMM_DATA; |
| 1363 | return -EAGAIN; | 1360 | return rc; |
| 1364 | } | 1361 | } |
| 1365 | } | 1362 | } |
| 1366 | 1363 | ||
| @@ -1371,10 +1368,13 @@ iscsi_tcp_mtask_xmit(struct iscsi_conn *conn, struct iscsi_mgmt_task *mtask) | |||
| 1371 | * Virtual buffer could be spreaded across multiple pages... | 1368 | * Virtual buffer could be spreaded across multiple pages... |
| 1372 | */ | 1369 | */ |
| 1373 | do { | 1370 | do { |
| 1374 | if (iscsi_sendpage(conn, &tcp_mtask->sendbuf, | 1371 | int rc; |
| 1375 | &mtask->data_count, &tcp_mtask->sent)) { | 1372 | |
| 1373 | rc = iscsi_sendpage(conn, &tcp_mtask->sendbuf, | ||
| 1374 | &mtask->data_count, &tcp_mtask->sent); | ||
| 1375 | if (rc) { | ||
| 1376 | tcp_mtask->xmstate |= XMSTATE_IMM_DATA; | 1376 | tcp_mtask->xmstate |= XMSTATE_IMM_DATA; |
| 1377 | return -EAGAIN; | 1377 | return rc; |
| 1378 | } | 1378 | } |
| 1379 | } while (mtask->data_count); | 1379 | } while (mtask->data_count); |
| 1380 | } | 1380 | } |
| @@ -1396,16 +1396,19 @@ static inline int | |||
| 1396 | handle_xmstate_r_hdr(struct iscsi_conn *conn, | 1396 | handle_xmstate_r_hdr(struct iscsi_conn *conn, |
| 1397 | struct iscsi_tcp_cmd_task *tcp_ctask) | 1397 | struct iscsi_tcp_cmd_task *tcp_ctask) |
| 1398 | { | 1398 | { |
| 1399 | int rc; | ||
| 1400 | |||
| 1399 | tcp_ctask->xmstate &= ~XMSTATE_R_HDR; | 1401 | tcp_ctask->xmstate &= ~XMSTATE_R_HDR; |
| 1400 | if (conn->hdrdgst_en) | 1402 | if (conn->hdrdgst_en) |
| 1401 | iscsi_hdr_digest(conn, &tcp_ctask->headbuf, | 1403 | iscsi_hdr_digest(conn, &tcp_ctask->headbuf, |
| 1402 | (u8*)tcp_ctask->hdrext); | 1404 | (u8*)tcp_ctask->hdrext); |
| 1403 | if (!iscsi_sendhdr(conn, &tcp_ctask->headbuf, 0)) { | 1405 | rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, 0); |
| 1406 | if (!rc) { | ||
| 1404 | BUG_ON(tcp_ctask->xmstate != XMSTATE_IDLE); | 1407 | BUG_ON(tcp_ctask->xmstate != XMSTATE_IDLE); |
| 1405 | return 0; /* wait for Data-In */ | 1408 | return 0; /* wait for Data-In */ |
| 1406 | } | 1409 | } |
| 1407 | tcp_ctask->xmstate |= XMSTATE_R_HDR; | 1410 | tcp_ctask->xmstate |= XMSTATE_R_HDR; |
| 1408 | return -EAGAIN; | 1411 | return rc; |
| 1409 | } | 1412 | } |
| 1410 | 1413 | ||
| 1411 | static inline int | 1414 | static inline int |
| @@ -1413,16 +1416,16 @@ handle_xmstate_w_hdr(struct iscsi_conn *conn, | |||
| 1413 | struct iscsi_cmd_task *ctask) | 1416 | struct iscsi_cmd_task *ctask) |
| 1414 | { | 1417 | { |
| 1415 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1418 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
| 1419 | int rc; | ||
| 1416 | 1420 | ||
| 1417 | tcp_ctask->xmstate &= ~XMSTATE_W_HDR; | 1421 | tcp_ctask->xmstate &= ~XMSTATE_W_HDR; |
| 1418 | if (conn->hdrdgst_en) | 1422 | if (conn->hdrdgst_en) |
| 1419 | iscsi_hdr_digest(conn, &tcp_ctask->headbuf, | 1423 | iscsi_hdr_digest(conn, &tcp_ctask->headbuf, |
| 1420 | (u8*)tcp_ctask->hdrext); | 1424 | (u8*)tcp_ctask->hdrext); |
| 1421 | if (iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count)) { | 1425 | rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->imm_count); |
| 1426 | if (rc) | ||
| 1422 | tcp_ctask->xmstate |= XMSTATE_W_HDR; | 1427 | tcp_ctask->xmstate |= XMSTATE_W_HDR; |
| 1423 | return -EAGAIN; | 1428 | return rc; |
| 1424 | } | ||
| 1425 | return 0; | ||
| 1426 | } | 1429 | } |
| 1427 | 1430 | ||
| 1428 | static inline int | 1431 | static inline int |
| @@ -1430,17 +1433,19 @@ handle_xmstate_data_digest(struct iscsi_conn *conn, | |||
| 1430 | struct iscsi_cmd_task *ctask) | 1433 | struct iscsi_cmd_task *ctask) |
| 1431 | { | 1434 | { |
| 1432 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1435 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
| 1436 | int rc; | ||
| 1433 | 1437 | ||
| 1434 | tcp_ctask->xmstate &= ~XMSTATE_DATA_DIGEST; | 1438 | tcp_ctask->xmstate &= ~XMSTATE_DATA_DIGEST; |
| 1435 | debug_tcp("resent data digest 0x%x\n", tcp_ctask->datadigest); | 1439 | debug_tcp("resent data digest 0x%x\n", tcp_ctask->datadigest); |
| 1436 | if (iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, | 1440 | rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, |
| 1437 | &tcp_ctask->datadigest, 0)) { | 1441 | &tcp_ctask->datadigest, 0); |
| 1442 | if (rc) { | ||
| 1438 | tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST; | 1443 | tcp_ctask->xmstate |= XMSTATE_DATA_DIGEST; |
| 1439 | debug_tcp("resent data digest 0x%x fail!\n", | 1444 | debug_tcp("resent data digest 0x%x fail!\n", |
| 1440 | tcp_ctask->datadigest); | 1445 | tcp_ctask->datadigest); |
| 1441 | return -EAGAIN; | ||
| 1442 | } | 1446 | } |
| 1443 | return 0; | 1447 | |
| 1448 | return rc; | ||
| 1444 | } | 1449 | } |
| 1445 | 1450 | ||
| 1446 | static inline int | 1451 | static inline int |
| @@ -1448,6 +1453,7 @@ handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1448 | { | 1453 | { |
| 1449 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1454 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
| 1450 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 1455 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
| 1456 | int rc; | ||
| 1451 | 1457 | ||
| 1452 | BUG_ON(!ctask->imm_count); | 1458 | BUG_ON(!ctask->imm_count); |
| 1453 | tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA; | 1459 | tcp_ctask->xmstate &= ~XMSTATE_IMM_DATA; |
| @@ -1458,8 +1464,9 @@ handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1458 | } | 1464 | } |
| 1459 | 1465 | ||
| 1460 | for (;;) { | 1466 | for (;;) { |
| 1461 | if (iscsi_sendpage(conn, &tcp_ctask->sendbuf, &ctask->imm_count, | 1467 | rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, |
| 1462 | &tcp_ctask->sent)) { | 1468 | &ctask->imm_count, &tcp_ctask->sent); |
| 1469 | if (rc) { | ||
| 1463 | tcp_ctask->xmstate |= XMSTATE_IMM_DATA; | 1470 | tcp_ctask->xmstate |= XMSTATE_IMM_DATA; |
| 1464 | if (conn->datadgst_en) { | 1471 | if (conn->datadgst_en) { |
| 1465 | crypto_digest_final(tcp_conn->data_tx_tfm, | 1472 | crypto_digest_final(tcp_conn->data_tx_tfm, |
| @@ -1467,7 +1474,7 @@ handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1467 | debug_tcp("tx imm sendpage fail 0x%x\n", | 1474 | debug_tcp("tx imm sendpage fail 0x%x\n", |
| 1468 | tcp_ctask->datadigest); | 1475 | tcp_ctask->datadigest); |
| 1469 | } | 1476 | } |
| 1470 | return -EAGAIN; | 1477 | return rc; |
| 1471 | } | 1478 | } |
| 1472 | if (conn->datadgst_en) | 1479 | if (conn->datadgst_en) |
| 1473 | crypto_digest_update(tcp_conn->data_tx_tfm, | 1480 | crypto_digest_update(tcp_conn->data_tx_tfm, |
| @@ -1480,11 +1487,12 @@ handle_xmstate_imm_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1480 | } | 1487 | } |
| 1481 | 1488 | ||
| 1482 | if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { | 1489 | if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { |
| 1483 | if (iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, | 1490 | rc = iscsi_digest_final_send(conn, ctask, &tcp_ctask->immbuf, |
| 1484 | &tcp_ctask->immdigest, 1)) { | 1491 | &tcp_ctask->immdigest, 1); |
| 1492 | if (rc) { | ||
| 1485 | debug_tcp("sending imm digest 0x%x fail!\n", | 1493 | debug_tcp("sending imm digest 0x%x fail!\n", |
| 1486 | tcp_ctask->immdigest); | 1494 | tcp_ctask->immdigest); |
| 1487 | return -EAGAIN; | 1495 | return rc; |
| 1488 | } | 1496 | } |
| 1489 | debug_tcp("sending imm digest 0x%x\n", tcp_ctask->immdigest); | 1497 | debug_tcp("sending imm digest 0x%x\n", tcp_ctask->immdigest); |
| 1490 | } | 1498 | } |
| @@ -1497,6 +1505,7 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1497 | { | 1505 | { |
| 1498 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1506 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
| 1499 | struct iscsi_data_task *dtask; | 1507 | struct iscsi_data_task *dtask; |
| 1508 | int rc; | ||
| 1500 | 1509 | ||
| 1501 | tcp_ctask->xmstate |= XMSTATE_UNS_DATA; | 1510 | tcp_ctask->xmstate |= XMSTATE_UNS_DATA; |
| 1502 | if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { | 1511 | if (tcp_ctask->xmstate & XMSTATE_UNS_INIT) { |
| @@ -1507,10 +1516,12 @@ handle_xmstate_uns_hdr(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1507 | (u8*)dtask->hdrext); | 1516 | (u8*)dtask->hdrext); |
| 1508 | tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT; | 1517 | tcp_ctask->xmstate &= ~XMSTATE_UNS_INIT; |
| 1509 | } | 1518 | } |
| 1510 | if (iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count)) { | 1519 | |
| 1520 | rc = iscsi_sendhdr(conn, &tcp_ctask->headbuf, ctask->data_count); | ||
| 1521 | if (rc) { | ||
| 1511 | tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; | 1522 | tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; |
| 1512 | tcp_ctask->xmstate |= XMSTATE_UNS_HDR; | 1523 | tcp_ctask->xmstate |= XMSTATE_UNS_HDR; |
| 1513 | return -EAGAIN; | 1524 | return rc; |
| 1514 | } | 1525 | } |
| 1515 | 1526 | ||
| 1516 | debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n", | 1527 | debug_scsi("uns dout [itt 0x%x dlen %d sent %d]\n", |
| @@ -1524,6 +1535,7 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1524 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1535 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
| 1525 | struct iscsi_data_task *dtask = tcp_ctask->dtask; | 1536 | struct iscsi_data_task *dtask = tcp_ctask->dtask; |
| 1526 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 1537 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
| 1538 | int rc; | ||
| 1527 | 1539 | ||
| 1528 | BUG_ON(!ctask->data_count); | 1540 | BUG_ON(!ctask->data_count); |
| 1529 | tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; | 1541 | tcp_ctask->xmstate &= ~XMSTATE_UNS_DATA; |
| @@ -1536,8 +1548,9 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1536 | for (;;) { | 1548 | for (;;) { |
| 1537 | int start = tcp_ctask->sent; | 1549 | int start = tcp_ctask->sent; |
| 1538 | 1550 | ||
| 1539 | if (iscsi_sendpage(conn, &tcp_ctask->sendbuf, | 1551 | rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, |
| 1540 | &ctask->data_count, &tcp_ctask->sent)) { | 1552 | &ctask->data_count, &tcp_ctask->sent); |
| 1553 | if (rc) { | ||
| 1541 | ctask->unsol_count -= tcp_ctask->sent - start; | 1554 | ctask->unsol_count -= tcp_ctask->sent - start; |
| 1542 | tcp_ctask->xmstate |= XMSTATE_UNS_DATA; | 1555 | tcp_ctask->xmstate |= XMSTATE_UNS_DATA; |
| 1543 | /* will continue with this ctask later.. */ | 1556 | /* will continue with this ctask later.. */ |
| @@ -1547,7 +1560,7 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1547 | debug_tcp("tx uns data fail 0x%x\n", | 1560 | debug_tcp("tx uns data fail 0x%x\n", |
| 1548 | dtask->digest); | 1561 | dtask->digest); |
| 1549 | } | 1562 | } |
| 1550 | return -EAGAIN; | 1563 | return rc; |
| 1551 | } | 1564 | } |
| 1552 | 1565 | ||
| 1553 | BUG_ON(tcp_ctask->sent > ctask->total_length); | 1566 | BUG_ON(tcp_ctask->sent > ctask->total_length); |
| @@ -1574,12 +1587,13 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1574 | */ | 1587 | */ |
| 1575 | if (ctask->unsol_count) { | 1588 | if (ctask->unsol_count) { |
| 1576 | if (conn->datadgst_en) { | 1589 | if (conn->datadgst_en) { |
| 1577 | if (iscsi_digest_final_send(conn, ctask, | 1590 | rc = iscsi_digest_final_send(conn, ctask, |
| 1578 | &dtask->digestbuf, | 1591 | &dtask->digestbuf, |
| 1579 | &dtask->digest, 1)) { | 1592 | &dtask->digest, 1); |
| 1593 | if (rc) { | ||
| 1580 | debug_tcp("send uns digest 0x%x fail\n", | 1594 | debug_tcp("send uns digest 0x%x fail\n", |
| 1581 | dtask->digest); | 1595 | dtask->digest); |
| 1582 | return -EAGAIN; | 1596 | return rc; |
| 1583 | } | 1597 | } |
| 1584 | debug_tcp("sending uns digest 0x%x, more uns\n", | 1598 | debug_tcp("sending uns digest 0x%x, more uns\n", |
| 1585 | dtask->digest); | 1599 | dtask->digest); |
| @@ -1589,12 +1603,13 @@ handle_xmstate_uns_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1589 | } | 1603 | } |
| 1590 | 1604 | ||
| 1591 | if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { | 1605 | if (conn->datadgst_en && !(tcp_ctask->xmstate & XMSTATE_W_PAD)) { |
| 1592 | if (iscsi_digest_final_send(conn, ctask, | 1606 | rc = iscsi_digest_final_send(conn, ctask, |
| 1593 | &dtask->digestbuf, | 1607 | &dtask->digestbuf, |
| 1594 | &dtask->digest, 1)) { | 1608 | &dtask->digest, 1); |
| 1609 | if (rc) { | ||
| 1595 | debug_tcp("send last uns digest 0x%x fail\n", | 1610 | debug_tcp("send last uns digest 0x%x fail\n", |
| 1596 | dtask->digest); | 1611 | dtask->digest); |
| 1597 | return -EAGAIN; | 1612 | return rc; |
| 1598 | } | 1613 | } |
| 1599 | debug_tcp("sending uns digest 0x%x\n",dtask->digest); | 1614 | debug_tcp("sending uns digest 0x%x\n",dtask->digest); |
| 1600 | } | 1615 | } |
| @@ -1610,7 +1625,7 @@ handle_xmstate_sol_data(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1610 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1625 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
| 1611 | struct iscsi_r2t_info *r2t = tcp_ctask->r2t; | 1626 | struct iscsi_r2t_info *r2t = tcp_ctask->r2t; |
| 1612 | struct iscsi_data_task *dtask = &r2t->dtask; | 1627 | struct iscsi_data_task *dtask = &r2t->dtask; |
| 1613 | int left; | 1628 | int left, rc; |
| 1614 | 1629 | ||
| 1615 | tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; | 1630 | tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; |
| 1616 | tcp_ctask->dtask = dtask; | 1631 | tcp_ctask->dtask = dtask; |
| @@ -1626,7 +1641,8 @@ solicit_again: | |||
| 1626 | if (!r2t->data_count) | 1641 | if (!r2t->data_count) |
| 1627 | goto data_out_done; | 1642 | goto data_out_done; |
| 1628 | 1643 | ||
| 1629 | if (iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent)) { | 1644 | rc = iscsi_sendpage(conn, &r2t->sendbuf, &r2t->data_count, &r2t->sent); |
| 1645 | if (rc) { | ||
| 1630 | tcp_ctask->xmstate |= XMSTATE_SOL_DATA; | 1646 | tcp_ctask->xmstate |= XMSTATE_SOL_DATA; |
| 1631 | /* will continue with this ctask later.. */ | 1647 | /* will continue with this ctask later.. */ |
| 1632 | if (conn->datadgst_en) { | 1648 | if (conn->datadgst_en) { |
| @@ -1634,7 +1650,7 @@ solicit_again: | |||
| 1634 | (u8 *)&dtask->digest); | 1650 | (u8 *)&dtask->digest); |
| 1635 | debug_tcp("r2t data send fail 0x%x\n", dtask->digest); | 1651 | debug_tcp("r2t data send fail 0x%x\n", dtask->digest); |
| 1636 | } | 1652 | } |
| 1637 | return -EAGAIN; | 1653 | return rc; |
| 1638 | } | 1654 | } |
| 1639 | 1655 | ||
| 1640 | BUG_ON(r2t->data_count < 0); | 1656 | BUG_ON(r2t->data_count < 0); |
| @@ -1661,12 +1677,13 @@ data_out_done: | |||
| 1661 | left = r2t->data_length - r2t->sent; | 1677 | left = r2t->data_length - r2t->sent; |
| 1662 | if (left) { | 1678 | if (left) { |
| 1663 | if (conn->datadgst_en) { | 1679 | if (conn->datadgst_en) { |
| 1664 | if (iscsi_digest_final_send(conn, ctask, | 1680 | rc = iscsi_digest_final_send(conn, ctask, |
| 1665 | &dtask->digestbuf, | 1681 | &dtask->digestbuf, |
| 1666 | &dtask->digest, 1)) { | 1682 | &dtask->digest, 1); |
| 1683 | if (rc) { | ||
| 1667 | debug_tcp("send r2t data digest 0x%x" | 1684 | debug_tcp("send r2t data digest 0x%x" |
| 1668 | "fail\n", dtask->digest); | 1685 | "fail\n", dtask->digest); |
| 1669 | return -EAGAIN; | 1686 | return rc; |
| 1670 | } | 1687 | } |
| 1671 | debug_tcp("r2t data send digest 0x%x\n", | 1688 | debug_tcp("r2t data send digest 0x%x\n", |
| 1672 | dtask->digest); | 1689 | dtask->digest); |
| @@ -1683,11 +1700,12 @@ data_out_done: | |||
| 1683 | */ | 1700 | */ |
| 1684 | BUG_ON(tcp_ctask->r2t_data_count - r2t->data_length < 0); | 1701 | BUG_ON(tcp_ctask->r2t_data_count - r2t->data_length < 0); |
| 1685 | if (conn->datadgst_en) { | 1702 | if (conn->datadgst_en) { |
| 1686 | if (iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, | 1703 | rc = iscsi_digest_final_send(conn, ctask, &dtask->digestbuf, |
| 1687 | &dtask->digest, 1)) { | 1704 | &dtask->digest, 1); |
| 1705 | if (rc) { | ||
| 1688 | debug_tcp("send last r2t data digest 0x%x" | 1706 | debug_tcp("send last r2t data digest 0x%x" |
| 1689 | "fail\n", dtask->digest); | 1707 | "fail\n", dtask->digest); |
| 1690 | return -EAGAIN; | 1708 | return rc; |
| 1691 | } | 1709 | } |
| 1692 | debug_tcp("r2t done dout digest 0x%x\n", dtask->digest); | 1710 | debug_tcp("r2t done dout digest 0x%x\n", dtask->digest); |
| 1693 | } | 1711 | } |
| @@ -1713,15 +1731,16 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1713 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; | 1731 | struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data; |
| 1714 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; | 1732 | struct iscsi_tcp_conn *tcp_conn = conn->dd_data; |
| 1715 | struct iscsi_data_task *dtask = tcp_ctask->dtask; | 1733 | struct iscsi_data_task *dtask = tcp_ctask->dtask; |
| 1716 | int sent; | 1734 | int sent, rc; |
| 1717 | 1735 | ||
| 1718 | tcp_ctask->xmstate &= ~XMSTATE_W_PAD; | 1736 | tcp_ctask->xmstate &= ~XMSTATE_W_PAD; |
| 1719 | iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, | 1737 | iscsi_buf_init_iov(&tcp_ctask->sendbuf, (char*)&tcp_ctask->pad, |
| 1720 | tcp_ctask->pad_count); | 1738 | tcp_ctask->pad_count); |
| 1721 | if (iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count, | 1739 | rc = iscsi_sendpage(conn, &tcp_ctask->sendbuf, &tcp_ctask->pad_count, |
| 1722 | &sent)) { | 1740 | &sent); |
| 1741 | if (rc) { | ||
| 1723 | tcp_ctask->xmstate |= XMSTATE_W_PAD; | 1742 | tcp_ctask->xmstate |= XMSTATE_W_PAD; |
| 1724 | return -EAGAIN; | 1743 | return rc; |
| 1725 | } | 1744 | } |
| 1726 | 1745 | ||
| 1727 | if (conn->datadgst_en) { | 1746 | if (conn->datadgst_en) { |
| @@ -1729,22 +1748,24 @@ handle_xmstate_w_pad(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1729 | &tcp_ctask->sendbuf.sg, 1); | 1748 | &tcp_ctask->sendbuf.sg, 1); |
| 1730 | /* imm data? */ | 1749 | /* imm data? */ |
| 1731 | if (!dtask) { | 1750 | if (!dtask) { |
| 1732 | if (iscsi_digest_final_send(conn, ctask, | 1751 | rc = iscsi_digest_final_send(conn, ctask, |
| 1733 | &tcp_ctask->immbuf, | 1752 | &tcp_ctask->immbuf, |
| 1734 | &tcp_ctask->immdigest, 1)) { | 1753 | &tcp_ctask->immdigest, 1); |
| 1754 | if (rc) { | ||
| 1735 | debug_tcp("send padding digest 0x%x" | 1755 | debug_tcp("send padding digest 0x%x" |
| 1736 | "fail!\n", tcp_ctask->immdigest); | 1756 | "fail!\n", tcp_ctask->immdigest); |
| 1737 | return -EAGAIN; | 1757 | return rc; |
| 1738 | } | 1758 | } |
| 1739 | debug_tcp("done with padding, digest 0x%x\n", | 1759 | debug_tcp("done with padding, digest 0x%x\n", |
| 1740 | tcp_ctask->datadigest); | 1760 | tcp_ctask->datadigest); |
| 1741 | } else { | 1761 | } else { |
| 1742 | if (iscsi_digest_final_send(conn, ctask, | 1762 | rc = iscsi_digest_final_send(conn, ctask, |
| 1743 | &dtask->digestbuf, | 1763 | &dtask->digestbuf, |
| 1744 | &dtask->digest, 1)) { | 1764 | &dtask->digest, 1); |
| 1765 | if (rc) { | ||
| 1745 | debug_tcp("send padding digest 0x%x" | 1766 | debug_tcp("send padding digest 0x%x" |
| 1746 | "fail\n", dtask->digest); | 1767 | "fail\n", dtask->digest); |
| 1747 | return -EAGAIN; | 1768 | return rc; |
| 1748 | } | 1769 | } |
| 1749 | debug_tcp("done with padding, digest 0x%x\n", | 1770 | debug_tcp("done with padding, digest 0x%x\n", |
| 1750 | dtask->digest); | 1771 | dtask->digest); |
| @@ -1769,10 +1790,8 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask) | |||
| 1769 | if (ctask->mtask) | 1790 | if (ctask->mtask) |
| 1770 | return rc; | 1791 | return rc; |
| 1771 | 1792 | ||
| 1772 | if (tcp_ctask->xmstate & XMSTATE_R_HDR) { | 1793 | if (tcp_ctask->xmstate & XMSTATE_R_HDR) |
| 1773 | rc = handle_xmstate_r_hdr(conn, tcp_ctask); | 1794 | return handle_xmstate_r_hdr(conn, tcp_ctask); |
| 1774 | return rc; | ||
| 1775 | } | ||
| 1776 | 1795 | ||
| 1777 | if (tcp_ctask->xmstate & XMSTATE_W_HDR) { | 1796 | if (tcp_ctask->xmstate & XMSTATE_W_HDR) { |
| 1778 | rc = handle_xmstate_w_hdr(conn, ctask); | 1797 | rc = handle_xmstate_w_hdr(conn, ctask); |
| @@ -1824,10 +1843,11 @@ solicit_head_again: | |||
| 1824 | if (conn->hdrdgst_en) | 1843 | if (conn->hdrdgst_en) |
| 1825 | iscsi_hdr_digest(conn, &r2t->headbuf, | 1844 | iscsi_hdr_digest(conn, &r2t->headbuf, |
| 1826 | (u8*)r2t->dtask.hdrext); | 1845 | (u8*)r2t->dtask.hdrext); |
| 1827 | if (iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count)) { | 1846 | rc = iscsi_sendhdr(conn, &r2t->headbuf, r2t->data_count); |
| 1847 | if (rc) { | ||
| 1828 | tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; | 1848 | tcp_ctask->xmstate &= ~XMSTATE_SOL_DATA; |
| 1829 | tcp_ctask->xmstate |= XMSTATE_SOL_HDR; | 1849 | tcp_ctask->xmstate |= XMSTATE_SOL_HDR; |
| 1830 | return -EAGAIN; | 1850 | return rc; |
| 1831 | } | 1851 | } |
| 1832 | 1852 | ||
| 1833 | debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n", | 1853 | debug_scsi("sol dout [dsn %d itt 0x%x dlen %d sent %d]\n", |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 256b87a85978..2673a11a9495 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -513,10 +513,11 @@ EXPORT_SYMBOL_GPL(iscsi_conn_failure); | |||
| 513 | static int iscsi_data_xmit(struct iscsi_conn *conn) | 513 | static int iscsi_data_xmit(struct iscsi_conn *conn) |
| 514 | { | 514 | { |
| 515 | struct iscsi_transport *tt; | 515 | struct iscsi_transport *tt; |
| 516 | int rc = 0; | ||
| 516 | 517 | ||
| 517 | if (unlikely(conn->suspend_tx)) { | 518 | if (unlikely(conn->suspend_tx)) { |
| 518 | debug_scsi("conn %d Tx suspended!\n", conn->id); | 519 | debug_scsi("conn %d Tx suspended!\n", conn->id); |
| 519 | return 0; | 520 | return -ENODATA; |
| 520 | } | 521 | } |
| 521 | tt = conn->session->tt; | 522 | tt = conn->session->tt; |
| 522 | 523 | ||
| @@ -536,13 +537,15 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
| 536 | BUG_ON(conn->ctask && conn->mtask); | 537 | BUG_ON(conn->ctask && conn->mtask); |
| 537 | 538 | ||
| 538 | if (conn->ctask) { | 539 | if (conn->ctask) { |
| 539 | if (tt->xmit_cmd_task(conn, conn->ctask)) | 540 | rc = tt->xmit_cmd_task(conn, conn->ctask); |
| 541 | if (rc) | ||
| 540 | goto again; | 542 | goto again; |
| 541 | /* done with this in-progress ctask */ | 543 | /* done with this in-progress ctask */ |
| 542 | conn->ctask = NULL; | 544 | conn->ctask = NULL; |
| 543 | } | 545 | } |
| 544 | if (conn->mtask) { | 546 | if (conn->mtask) { |
| 545 | if (tt->xmit_mgmt_task(conn, conn->mtask)) | 547 | rc = tt->xmit_mgmt_task(conn, conn->mtask); |
| 548 | if (rc) | ||
| 546 | goto again; | 549 | goto again; |
| 547 | /* done with this in-progress mtask */ | 550 | /* done with this in-progress mtask */ |
| 548 | conn->mtask = NULL; | 551 | conn->mtask = NULL; |
| @@ -556,7 +559,8 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
| 556 | list_add_tail(&conn->mtask->running, | 559 | list_add_tail(&conn->mtask->running, |
| 557 | &conn->mgmt_run_list); | 560 | &conn->mgmt_run_list); |
| 558 | spin_unlock_bh(&conn->session->lock); | 561 | spin_unlock_bh(&conn->session->lock); |
| 559 | if (tt->xmit_mgmt_task(conn, conn->mtask)) | 562 | rc = tt->xmit_mgmt_task(conn, conn->mtask); |
| 563 | if (rc) | ||
| 560 | goto again; | 564 | goto again; |
| 561 | } | 565 | } |
| 562 | /* done with this mtask */ | 566 | /* done with this mtask */ |
| @@ -574,7 +578,8 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
| 574 | if (list_empty(&conn->ctask->running)) | 578 | if (list_empty(&conn->ctask->running)) |
| 575 | list_add_tail(&conn->ctask->running, &conn->run_list); | 579 | list_add_tail(&conn->ctask->running, &conn->run_list); |
| 576 | spin_unlock_bh(&conn->session->lock); | 580 | spin_unlock_bh(&conn->session->lock); |
| 577 | if (tt->xmit_cmd_task(conn, conn->ctask)) | 581 | rc = tt->xmit_cmd_task(conn, conn->ctask); |
| 582 | if (rc) | ||
| 578 | goto again; | 583 | goto again; |
| 579 | } | 584 | } |
| 580 | /* done with this ctask */ | 585 | /* done with this ctask */ |
| @@ -588,32 +593,34 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) | |||
| 588 | list_add_tail(&conn->mtask->running, | 593 | list_add_tail(&conn->mtask->running, |
| 589 | &conn->mgmt_run_list); | 594 | &conn->mgmt_run_list); |
| 590 | spin_unlock_bh(&conn->session->lock); | 595 | spin_unlock_bh(&conn->session->lock); |
| 591 | if (tt->xmit_mgmt_task(conn, conn->mtask)) | 596 | rc = tt->xmit_mgmt_task(conn, conn->mtask); |
| 597 | if (rc) | ||
| 592 | goto again; | 598 | goto again; |
| 593 | } | 599 | } |
| 594 | /* done with this mtask */ | 600 | /* done with this mtask */ |
| 595 | conn->mtask = NULL; | 601 | conn->mtask = NULL; |
| 596 | } | 602 | } |
| 597 | 603 | ||
| 598 | return 0; | 604 | return -ENODATA; |
| 599 | 605 | ||
| 600 | again: | 606 | again: |
| 601 | if (unlikely(conn->suspend_tx)) | 607 | if (unlikely(conn->suspend_tx)) |
| 602 | return 0; | 608 | return -ENODATA; |
| 603 | 609 | ||
| 604 | return -EAGAIN; | 610 | return rc; |
| 605 | } | 611 | } |
| 606 | 612 | ||
| 607 | static void iscsi_xmitworker(void *data) | 613 | static void iscsi_xmitworker(void *data) |
| 608 | { | 614 | { |
| 609 | struct iscsi_conn *conn = data; | 615 | struct iscsi_conn *conn = data; |
| 610 | 616 | int rc; | |
| 611 | /* | 617 | /* |
| 612 | * serialize Xmit worker on a per-connection basis. | 618 | * serialize Xmit worker on a per-connection basis. |
| 613 | */ | 619 | */ |
| 614 | mutex_lock(&conn->xmitmutex); | 620 | mutex_lock(&conn->xmitmutex); |
| 615 | if (iscsi_data_xmit(conn)) | 621 | do { |
| 616 | scsi_queue_work(conn->session->host, &conn->xmitwork); | 622 | rc = iscsi_data_xmit(conn); |
| 623 | } while (rc >= 0 || rc == -EAGAIN); | ||
| 617 | mutex_unlock(&conn->xmitmutex); | 624 | mutex_unlock(&conn->xmitmutex); |
| 618 | } | 625 | } |
| 619 | 626 | ||
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 92129b97d31e..b684426a5900 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h | |||
| @@ -57,8 +57,12 @@ struct iscsi_mgmt_task; | |||
| 57 | * Called from queuecommand with session lock held. | 57 | * Called from queuecommand with session lock held. |
| 58 | * @init_mgmt_task: Initialize a iscsi_mgmt_task and any internal structs. | 58 | * @init_mgmt_task: Initialize a iscsi_mgmt_task and any internal structs. |
| 59 | * Called from iscsi_conn_send_generic with xmitmutex. | 59 | * Called from iscsi_conn_send_generic with xmitmutex. |
| 60 | * @xmit_cmd_task: requests LLD to transfer cmd task | 60 | * @xmit_cmd_task: Requests LLD to transfer cmd task. Returns 0 or the |
| 61 | * @xmit_mgmt_task: requests LLD to transfer mgmt task | 61 | * the number of bytes transferred on success, and -Exyz |
| 62 | * value on error. | ||
| 63 | * @xmit_mgmt_task: Requests LLD to transfer mgmt task. Returns 0 or the | ||
| 64 | * the number of bytes transferred on success, and -Exyz | ||
| 65 | * value on error. | ||
| 62 | * @cleanup_cmd_task: requests LLD to fail cmd task. Called with xmitmutex | 66 | * @cleanup_cmd_task: requests LLD to fail cmd task. Called with xmitmutex |
| 63 | * and session->lock after the connection has been | 67 | * and session->lock after the connection has been |
| 64 | * suspended and terminated during recovery. If called | 68 | * suspended and terminated during recovery. If called |
