aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target/iscsi/iscsi_target_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/target/iscsi/iscsi_target_util.c')
-rw-r--r--drivers/target/iscsi/iscsi_target_util.c274
1 files changed, 22 insertions, 252 deletions
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index a1acb016790..f00137f377b 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -243,7 +243,7 @@ struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr(
243 if (!cmd->tmr_req) { 243 if (!cmd->tmr_req) {
244 pr_err("Unable to allocate memory for" 244 pr_err("Unable to allocate memory for"
245 " Task Management command!\n"); 245 " Task Management command!\n");
246 return NULL; 246 goto out;
247 } 247 }
248 /* 248 /*
249 * TASK_REASSIGN for ERL=2 / connection stays inside of 249 * TASK_REASSIGN for ERL=2 / connection stays inside of
@@ -298,8 +298,6 @@ struct iscsi_cmd *iscsit_allocate_se_cmd_for_tmr(
298 return cmd; 298 return cmd;
299out: 299out:
300 iscsit_release_cmd(cmd); 300 iscsit_release_cmd(cmd);
301 if (se_cmd)
302 transport_free_se_cmd(se_cmd);
303 return NULL; 301 return NULL;
304} 302}
305 303
@@ -877,40 +875,6 @@ void iscsit_inc_session_usage_count(struct iscsi_session *sess)
877} 875}
878 876
879/* 877/*
880 * Used before iscsi_do[rx,tx]_data() to determine iov and [rx,tx]_marker
881 * array counts needed for sync and steering.
882 */
883static int iscsit_determine_sync_and_steering_counts(
884 struct iscsi_conn *conn,
885 struct iscsi_data_count *count)
886{
887 u32 length = count->data_length;
888 u32 marker, markint;
889
890 count->sync_and_steering = 1;
891
892 marker = (count->type == ISCSI_RX_DATA) ?
893 conn->of_marker : conn->if_marker;
894 markint = (count->type == ISCSI_RX_DATA) ?
895 (conn->conn_ops->OFMarkInt * 4) :
896 (conn->conn_ops->IFMarkInt * 4);
897 count->ss_iov_count = count->iov_count;
898
899 while (length > 0) {
900 if (length >= marker) {
901 count->ss_iov_count += 3;
902 count->ss_marker_count += 2;
903
904 length -= marker;
905 marker = markint;
906 } else
907 length = 0;
908 }
909
910 return 0;
911}
912
913/*
914 * Setup conn->if_marker and conn->of_marker values based upon 878 * Setup conn->if_marker and conn->of_marker values based upon
915 * the initial marker-less interval. (see iSCSI v19 A.2) 879 * the initial marker-less interval. (see iSCSI v19 A.2)
916 */ 880 */
@@ -1292,7 +1256,7 @@ int iscsit_fe_sendpage_sg(
1292 struct kvec iov; 1256 struct kvec iov;
1293 u32 tx_hdr_size, data_len; 1257 u32 tx_hdr_size, data_len;
1294 u32 offset = cmd->first_data_sg_off; 1258 u32 offset = cmd->first_data_sg_off;
1295 int tx_sent; 1259 int tx_sent, iov_off;
1296 1260
1297send_hdr: 1261send_hdr:
1298 tx_hdr_size = ISCSI_HDR_LEN; 1262 tx_hdr_size = ISCSI_HDR_LEN;
@@ -1312,9 +1276,19 @@ send_hdr:
1312 } 1276 }
1313 1277
1314 data_len = cmd->tx_size - tx_hdr_size - cmd->padding; 1278 data_len = cmd->tx_size - tx_hdr_size - cmd->padding;
1315 if (conn->conn_ops->DataDigest) 1279 /*
1280 * Set iov_off used by padding and data digest tx_data() calls below
1281 * in order to determine proper offset into cmd->iov_data[]
1282 */
1283 if (conn->conn_ops->DataDigest) {
1316 data_len -= ISCSI_CRC_LEN; 1284 data_len -= ISCSI_CRC_LEN;
1317 1285 if (cmd->padding)
1286 iov_off = (cmd->iov_data_count - 2);
1287 else
1288 iov_off = (cmd->iov_data_count - 1);
1289 } else {
1290 iov_off = (cmd->iov_data_count - 1);
1291 }
1318 /* 1292 /*
1319 * Perform sendpage() for each page in the scatterlist 1293 * Perform sendpage() for each page in the scatterlist
1320 */ 1294 */
@@ -1343,8 +1317,7 @@ send_pg:
1343 1317
1344send_padding: 1318send_padding:
1345 if (cmd->padding) { 1319 if (cmd->padding) {
1346 struct kvec *iov_p = 1320 struct kvec *iov_p = &cmd->iov_data[iov_off++];
1347 &cmd->iov_data[cmd->iov_data_count-1];
1348 1321
1349 tx_sent = tx_data(conn, iov_p, 1, cmd->padding); 1322 tx_sent = tx_data(conn, iov_p, 1, cmd->padding);
1350 if (cmd->padding != tx_sent) { 1323 if (cmd->padding != tx_sent) {
@@ -1358,8 +1331,7 @@ send_padding:
1358 1331
1359send_datacrc: 1332send_datacrc:
1360 if (conn->conn_ops->DataDigest) { 1333 if (conn->conn_ops->DataDigest) {
1361 struct kvec *iov_d = 1334 struct kvec *iov_d = &cmd->iov_data[iov_off];
1362 &cmd->iov_data[cmd->iov_data_count];
1363 1335
1364 tx_sent = tx_data(conn, iov_d, 1, ISCSI_CRC_LEN); 1336 tx_sent = tx_data(conn, iov_d, 1, ISCSI_CRC_LEN);
1365 if (ISCSI_CRC_LEN != tx_sent) { 1337 if (ISCSI_CRC_LEN != tx_sent) {
@@ -1433,8 +1405,7 @@ static int iscsit_do_rx_data(
1433 struct iscsi_data_count *count) 1405 struct iscsi_data_count *count)
1434{ 1406{
1435 int data = count->data_length, rx_loop = 0, total_rx = 0, iov_len; 1407 int data = count->data_length, rx_loop = 0, total_rx = 0, iov_len;
1436 u32 rx_marker_val[count->ss_marker_count], rx_marker_iov = 0; 1408 struct kvec *iov_p;
1437 struct kvec iov[count->ss_iov_count], *iov_p;
1438 struct msghdr msg; 1409 struct msghdr msg;
1439 1410
1440 if (!conn || !conn->sock || !conn->conn_ops) 1411 if (!conn || !conn->sock || !conn->conn_ops)
@@ -1442,93 +1413,8 @@ static int iscsit_do_rx_data(
1442 1413
1443 memset(&msg, 0, sizeof(struct msghdr)); 1414 memset(&msg, 0, sizeof(struct msghdr));
1444 1415
1445 if (count->sync_and_steering) { 1416 iov_p = count->iov;
1446 int size = 0; 1417 iov_len = count->iov_count;
1447 u32 i, orig_iov_count = 0;
1448 u32 orig_iov_len = 0, orig_iov_loc = 0;
1449 u32 iov_count = 0, per_iov_bytes = 0;
1450 u32 *rx_marker, old_rx_marker = 0;
1451 struct kvec *iov_record;
1452
1453 memset(&rx_marker_val, 0,
1454 count->ss_marker_count * sizeof(u32));
1455 memset(&iov, 0, count->ss_iov_count * sizeof(struct kvec));
1456
1457 iov_record = count->iov;
1458 orig_iov_count = count->iov_count;
1459 rx_marker = &conn->of_marker;
1460
1461 i = 0;
1462 size = data;
1463 orig_iov_len = iov_record[orig_iov_loc].iov_len;
1464 while (size > 0) {
1465 pr_debug("rx_data: #1 orig_iov_len %u,"
1466 " orig_iov_loc %u\n", orig_iov_len, orig_iov_loc);
1467 pr_debug("rx_data: #2 rx_marker %u, size"
1468 " %u\n", *rx_marker, size);
1469
1470 if (orig_iov_len >= *rx_marker) {
1471 iov[iov_count].iov_len = *rx_marker;
1472 iov[iov_count++].iov_base =
1473 (iov_record[orig_iov_loc].iov_base +
1474 per_iov_bytes);
1475
1476 iov[iov_count].iov_len = (MARKER_SIZE / 2);
1477 iov[iov_count++].iov_base =
1478 &rx_marker_val[rx_marker_iov++];
1479 iov[iov_count].iov_len = (MARKER_SIZE / 2);
1480 iov[iov_count++].iov_base =
1481 &rx_marker_val[rx_marker_iov++];
1482 old_rx_marker = *rx_marker;
1483
1484 /*
1485 * OFMarkInt is in 32-bit words.
1486 */
1487 *rx_marker = (conn->conn_ops->OFMarkInt * 4);
1488 size -= old_rx_marker;
1489 orig_iov_len -= old_rx_marker;
1490 per_iov_bytes += old_rx_marker;
1491
1492 pr_debug("rx_data: #3 new_rx_marker"
1493 " %u, size %u\n", *rx_marker, size);
1494 } else {
1495 iov[iov_count].iov_len = orig_iov_len;
1496 iov[iov_count++].iov_base =
1497 (iov_record[orig_iov_loc].iov_base +
1498 per_iov_bytes);
1499
1500 per_iov_bytes = 0;
1501 *rx_marker -= orig_iov_len;
1502 size -= orig_iov_len;
1503
1504 if (size)
1505 orig_iov_len =
1506 iov_record[++orig_iov_loc].iov_len;
1507
1508 pr_debug("rx_data: #4 new_rx_marker"
1509 " %u, size %u\n", *rx_marker, size);
1510 }
1511 }
1512 data += (rx_marker_iov * (MARKER_SIZE / 2));
1513
1514 iov_p = &iov[0];
1515 iov_len = iov_count;
1516
1517 if (iov_count > count->ss_iov_count) {
1518 pr_err("iov_count: %d, count->ss_iov_count:"
1519 " %d\n", iov_count, count->ss_iov_count);
1520 return -1;
1521 }
1522 if (rx_marker_iov > count->ss_marker_count) {
1523 pr_err("rx_marker_iov: %d, count->ss_marker"
1524 "_count: %d\n", rx_marker_iov,
1525 count->ss_marker_count);
1526 return -1;
1527 }
1528 } else {
1529 iov_p = count->iov;
1530 iov_len = count->iov_count;
1531 }
1532 1418
1533 while (total_rx < data) { 1419 while (total_rx < data) {
1534 rx_loop = kernel_recvmsg(conn->sock, &msg, iov_p, iov_len, 1420 rx_loop = kernel_recvmsg(conn->sock, &msg, iov_p, iov_len,
@@ -1543,16 +1429,6 @@ static int iscsit_do_rx_data(
1543 rx_loop, total_rx, data); 1429 rx_loop, total_rx, data);
1544 } 1430 }
1545 1431
1546 if (count->sync_and_steering) {
1547 int j;
1548 for (j = 0; j < rx_marker_iov; j++) {
1549 pr_debug("rx_data: #5 j: %d, offset: %d\n",
1550 j, rx_marker_val[j]);
1551 conn->of_marker_offset = rx_marker_val[j];
1552 }
1553 total_rx -= (rx_marker_iov * (MARKER_SIZE / 2));
1554 }
1555
1556 return total_rx; 1432 return total_rx;
1557} 1433}
1558 1434
@@ -1561,8 +1437,7 @@ static int iscsit_do_tx_data(
1561 struct iscsi_data_count *count) 1437 struct iscsi_data_count *count)
1562{ 1438{
1563 int data = count->data_length, total_tx = 0, tx_loop = 0, iov_len; 1439 int data = count->data_length, total_tx = 0, tx_loop = 0, iov_len;
1564 u32 tx_marker_val[count->ss_marker_count], tx_marker_iov = 0; 1440 struct kvec *iov_p;
1565 struct kvec iov[count->ss_iov_count], *iov_p;
1566 struct msghdr msg; 1441 struct msghdr msg;
1567 1442
1568 if (!conn || !conn->sock || !conn->conn_ops) 1443 if (!conn || !conn->sock || !conn->conn_ops)
@@ -1575,98 +1450,8 @@ static int iscsit_do_tx_data(
1575 1450
1576 memset(&msg, 0, sizeof(struct msghdr)); 1451 memset(&msg, 0, sizeof(struct msghdr));
1577 1452
1578 if (count->sync_and_steering) { 1453 iov_p = count->iov;
1579 int size = 0; 1454 iov_len = count->iov_count;
1580 u32 i, orig_iov_count = 0;
1581 u32 orig_iov_len = 0, orig_iov_loc = 0;
1582 u32 iov_count = 0, per_iov_bytes = 0;
1583 u32 *tx_marker, old_tx_marker = 0;
1584 struct kvec *iov_record;
1585
1586 memset(&tx_marker_val, 0,
1587 count->ss_marker_count * sizeof(u32));
1588 memset(&iov, 0, count->ss_iov_count * sizeof(struct kvec));
1589
1590 iov_record = count->iov;
1591 orig_iov_count = count->iov_count;
1592 tx_marker = &conn->if_marker;
1593
1594 i = 0;
1595 size = data;
1596 orig_iov_len = iov_record[orig_iov_loc].iov_len;
1597 while (size > 0) {
1598 pr_debug("tx_data: #1 orig_iov_len %u,"
1599 " orig_iov_loc %u\n", orig_iov_len, orig_iov_loc);
1600 pr_debug("tx_data: #2 tx_marker %u, size"
1601 " %u\n", *tx_marker, size);
1602
1603 if (orig_iov_len >= *tx_marker) {
1604 iov[iov_count].iov_len = *tx_marker;
1605 iov[iov_count++].iov_base =
1606 (iov_record[orig_iov_loc].iov_base +
1607 per_iov_bytes);
1608
1609 tx_marker_val[tx_marker_iov] =
1610 (size - *tx_marker);
1611 iov[iov_count].iov_len = (MARKER_SIZE / 2);
1612 iov[iov_count++].iov_base =
1613 &tx_marker_val[tx_marker_iov++];
1614 iov[iov_count].iov_len = (MARKER_SIZE / 2);
1615 iov[iov_count++].iov_base =
1616 &tx_marker_val[tx_marker_iov++];
1617 old_tx_marker = *tx_marker;
1618
1619 /*
1620 * IFMarkInt is in 32-bit words.
1621 */
1622 *tx_marker = (conn->conn_ops->IFMarkInt * 4);
1623 size -= old_tx_marker;
1624 orig_iov_len -= old_tx_marker;
1625 per_iov_bytes += old_tx_marker;
1626
1627 pr_debug("tx_data: #3 new_tx_marker"
1628 " %u, size %u\n", *tx_marker, size);
1629 pr_debug("tx_data: #4 offset %u\n",
1630 tx_marker_val[tx_marker_iov-1]);
1631 } else {
1632 iov[iov_count].iov_len = orig_iov_len;
1633 iov[iov_count++].iov_base
1634 = (iov_record[orig_iov_loc].iov_base +
1635 per_iov_bytes);
1636
1637 per_iov_bytes = 0;
1638 *tx_marker -= orig_iov_len;
1639 size -= orig_iov_len;
1640
1641 if (size)
1642 orig_iov_len =
1643 iov_record[++orig_iov_loc].iov_len;
1644
1645 pr_debug("tx_data: #5 new_tx_marker"
1646 " %u, size %u\n", *tx_marker, size);
1647 }
1648 }
1649
1650 data += (tx_marker_iov * (MARKER_SIZE / 2));
1651
1652 iov_p = &iov[0];
1653 iov_len = iov_count;
1654
1655 if (iov_count > count->ss_iov_count) {
1656 pr_err("iov_count: %d, count->ss_iov_count:"
1657 " %d\n", iov_count, count->ss_iov_count);
1658 return -1;
1659 }
1660 if (tx_marker_iov > count->ss_marker_count) {
1661 pr_err("tx_marker_iov: %d, count->ss_marker"
1662 "_count: %d\n", tx_marker_iov,
1663 count->ss_marker_count);
1664 return -1;
1665 }
1666 } else {
1667 iov_p = count->iov;
1668 iov_len = count->iov_count;
1669 }
1670 1455
1671 while (total_tx < data) { 1456 while (total_tx < data) {
1672 tx_loop = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len, 1457 tx_loop = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len,
@@ -1681,9 +1466,6 @@ static int iscsit_do_tx_data(
1681 tx_loop, total_tx, data); 1466 tx_loop, total_tx, data);
1682 } 1467 }
1683 1468
1684 if (count->sync_and_steering)
1685 total_tx -= (tx_marker_iov * (MARKER_SIZE / 2));
1686
1687 return total_tx; 1469 return total_tx;
1688} 1470}
1689 1471
@@ -1704,12 +1486,6 @@ int rx_data(
1704 c.data_length = data; 1486 c.data_length = data;
1705 c.type = ISCSI_RX_DATA; 1487 c.type = ISCSI_RX_DATA;
1706 1488
1707 if (conn->conn_ops->OFMarker &&
1708 (conn->conn_state >= TARG_CONN_STATE_LOGGED_IN)) {
1709 if (iscsit_determine_sync_and_steering_counts(conn, &c) < 0)
1710 return -1;
1711 }
1712
1713 return iscsit_do_rx_data(conn, &c); 1489 return iscsit_do_rx_data(conn, &c);
1714} 1490}
1715 1491
@@ -1730,12 +1506,6 @@ int tx_data(
1730 c.data_length = data; 1506 c.data_length = data;
1731 c.type = ISCSI_TX_DATA; 1507 c.type = ISCSI_TX_DATA;
1732 1508
1733 if (conn->conn_ops->IFMarker &&
1734 (conn->conn_state >= TARG_CONN_STATE_LOGGED_IN)) {
1735 if (iscsit_determine_sync_and_steering_counts(conn, &c) < 0)
1736 return -1;
1737 }
1738
1739 return iscsit_do_tx_data(conn, &c); 1509 return iscsit_do_tx_data(conn, &c);
1740} 1510}
1741 1511