Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit e4f4e80

Browse files
Sagi GrimbergNicholas Bellinger
authored andcommitted
iscsi/iser-target: Support multi-sequence sendtargets text response
In case sendtargets response is larger than initiator MRDSL, we send a partial sendtargets response (setting F=0, C=1, TTT!=0xffffffff), accept a consecutive empty text message and send the rest of the payload. In case we are done, we set F=1, C=0, TTT=0xffffffff. We do that by storing the sendtargets response bytes done under the session. This patch also makes iscsit_find_cmd_from_itt public for isert. (Re-add cmd->maxcmdsn_inc and clear in iscsit_build_text_rsp - nab) Signed-off-by: Sagi Grimberg <[email protected]> Signed-off-by: Nicholas Bellinger <[email protected]>
1 parent 11378cd commit e4f4e80

File tree

5 files changed

+82
-26
lines changed

5 files changed

+82
-26
lines changed

drivers/infiniband/ulp/isert/ib_isert.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,9 +1436,15 @@ isert_rx_opcode(struct isert_conn *isert_conn, struct iser_rx_desc *rx_desc,
14361436
ret = iscsit_handle_logout_cmd(conn, cmd, (unsigned char *)hdr);
14371437
break;
14381438
case ISCSI_OP_TEXT:
1439-
cmd = isert_allocate_cmd(conn);
1440-
if (!cmd)
1441-
break;
1439+
if (be32_to_cpu(hdr->ttt) != 0xFFFFFFFF) {
1440+
cmd = iscsit_find_cmd_from_itt(conn, hdr->itt);
1441+
if (!cmd)
1442+
break;
1443+
} else {
1444+
cmd = isert_allocate_cmd(conn);
1445+
if (!cmd)
1446+
break;
1447+
}
14421448

14431449
isert_cmd = iscsit_priv_cmd(cmd);
14441450
ret = isert_handle_text_cmd(isert_conn, isert_cmd, cmd,
@@ -1660,6 +1666,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err)
16601666
struct isert_conn *isert_conn = isert_cmd->conn;
16611667
struct iscsi_conn *conn = isert_conn->conn;
16621668
struct isert_device *device = isert_conn->conn_device;
1669+
struct iscsi_text_rsp *hdr;
16631670

16641671
isert_dbg("Cmd %p\n", isert_cmd);
16651672

@@ -1700,6 +1707,11 @@ isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err)
17001707
case ISCSI_OP_REJECT:
17011708
case ISCSI_OP_NOOP_OUT:
17021709
case ISCSI_OP_TEXT:
1710+
hdr = (struct iscsi_text_rsp *)&isert_cmd->tx_desc.iscsi_header;
1711+
/* If the continue bit is on, keep the command alive */
1712+
if (hdr->flags & ISCSI_FLAG_TEXT_CONTINUE)
1713+
break;
1714+
17031715
spin_lock_bh(&conn->cmd_lock);
17041716
if (!list_empty(&cmd->i_conn_node))
17051717
list_del_init(&cmd->i_conn_node);

drivers/target/iscsi/iscsi_target.c

Lines changed: 65 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1994,6 +1994,7 @@ iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
19941994
cmd->cmd_sn = be32_to_cpu(hdr->cmdsn);
19951995
cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn);
19961996
cmd->data_direction = DMA_NONE;
1997+
cmd->text_in_ptr = NULL;
19971998

19981999
return 0;
19992000
}
@@ -2007,9 +2008,13 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
20072008
int cmdsn_ret;
20082009

20092010
if (!text_in) {
2010-
pr_err("Unable to locate text_in buffer for sendtargets"
2011-
" discovery\n");
2012-
goto reject;
2011+
cmd->targ_xfer_tag = be32_to_cpu(hdr->ttt);
2012+
if (cmd->targ_xfer_tag == 0xFFFFFFFF) {
2013+
pr_err("Unable to locate text_in buffer for sendtargets"
2014+
" discovery\n");
2015+
goto reject;
2016+
}
2017+
goto empty_sendtargets;
20132018
}
20142019
if (strncmp("SendTargets", text_in, 11) != 0) {
20152020
pr_err("Received Text Data that is not"
@@ -2036,6 +2041,7 @@ iscsit_process_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
20362041
list_add_tail(&cmd->i_conn_node, &conn->conn_cmd_list);
20372042
spin_unlock_bh(&conn->cmd_lock);
20382043

2044+
empty_sendtargets:
20392045
iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
20402046

20412047
if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
@@ -3385,7 +3391,8 @@ static bool iscsit_check_inaddr_any(struct iscsi_np *np)
33853391

33863392
static int
33873393
iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
3388-
enum iscsit_transport_type network_transport)
3394+
enum iscsit_transport_type network_transport,
3395+
int skip_bytes, bool *completed)
33893396
{
33903397
char *payload = NULL;
33913398
struct iscsi_conn *conn = cmd->conn;
@@ -3476,9 +3483,16 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
34763483
end_of_buf = 1;
34773484
goto eob;
34783485
}
3479-
memcpy(payload + payload_len, buf, len);
3480-
payload_len += len;
3481-
target_name_printed = 1;
3486+
3487+
if (skip_bytes && len <= skip_bytes) {
3488+
skip_bytes -= len;
3489+
} else {
3490+
memcpy(payload + payload_len, buf, len);
3491+
payload_len += len;
3492+
target_name_printed = 1;
3493+
if (len > skip_bytes)
3494+
skip_bytes = 0;
3495+
}
34823496
}
34833497

34843498
len = sprintf(buf, "TargetAddress="
@@ -3494,15 +3508,24 @@ iscsit_build_sendtargets_response(struct iscsi_cmd *cmd,
34943508
end_of_buf = 1;
34953509
goto eob;
34963510
}
3497-
memcpy(payload + payload_len, buf, len);
3498-
payload_len += len;
3511+
3512+
if (skip_bytes && len <= skip_bytes) {
3513+
skip_bytes -= len;
3514+
} else {
3515+
memcpy(payload + payload_len, buf, len);
3516+
payload_len += len;
3517+
if (len > skip_bytes)
3518+
skip_bytes = 0;
3519+
}
34993520
}
35003521
spin_unlock(&tpg->tpg_np_lock);
35013522
}
35023523
spin_unlock(&tiqn->tiqn_tpg_lock);
35033524
eob:
3504-
if (end_of_buf)
3525+
if (end_of_buf) {
3526+
*completed = false;
35053527
break;
3528+
}
35063529

35073530
if (cmd->cmd_flags & IFC_SENDTARGETS_SINGLE)
35083531
break;
@@ -3520,13 +3543,23 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
35203543
enum iscsit_transport_type network_transport)
35213544
{
35223545
int text_length, padding;
3546+
bool completed = true;
35233547

3524-
text_length = iscsit_build_sendtargets_response(cmd, network_transport);
3548+
text_length = iscsit_build_sendtargets_response(cmd, network_transport,
3549+
cmd->read_data_done,
3550+
&completed);
35253551
if (text_length < 0)
35263552
return text_length;
35273553

3554+
if (completed) {
3555+
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
3556+
} else {
3557+
hdr->flags |= ISCSI_FLAG_TEXT_CONTINUE;
3558+
cmd->read_data_done += text_length;
3559+
if (cmd->targ_xfer_tag == 0xFFFFFFFF)
3560+
cmd->targ_xfer_tag = session_get_next_ttt(conn->sess);
3561+
}
35283562
hdr->opcode = ISCSI_OP_TEXT_RSP;
3529-
hdr->flags |= ISCSI_FLAG_CMD_FINAL;
35303563
padding = ((-text_length) & 3);
35313564
hton24(hdr->dlength, text_length);
35323565
hdr->itt = cmd->init_task_tag;
@@ -3535,21 +3568,25 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn,
35353568
hdr->statsn = cpu_to_be32(cmd->stat_sn);
35363569

35373570
iscsit_increment_maxcmdsn(cmd, conn->sess);
3571+
/*
3572+
* Reset maxcmdsn_inc in multi-part text payload exchanges to
3573+
* correctly increment MaxCmdSN for each response answering a
3574+
* non immediate text request with a valid CmdSN.
3575+
*/
3576+
cmd->maxcmdsn_inc = 0;
35383577
hdr->exp_cmdsn = cpu_to_be32(conn->sess->exp_cmd_sn);
35393578
hdr->max_cmdsn = cpu_to_be32(conn->sess->max_cmd_sn);
35403579

3541-
pr_debug("Built Text Response: ITT: 0x%08x, StatSN: 0x%08x,"
3542-
" Length: %u, CID: %hu\n", cmd->init_task_tag, cmd->stat_sn,
3543-
text_length, conn->cid);
3580+
pr_debug("Built Text Response: ITT: 0x%08x, TTT: 0x%08x, StatSN: 0x%08x,"
3581+
" Length: %u, CID: %hu F: %d C: %d\n", cmd->init_task_tag,
3582+
cmd->targ_xfer_tag, cmd->stat_sn, text_length, conn->cid,
3583+
!!(hdr->flags & ISCSI_FLAG_CMD_FINAL),
3584+
!!(hdr->flags & ISCSI_FLAG_TEXT_CONTINUE));
35443585

35453586
return text_length + padding;
35463587
}
35473588
EXPORT_SYMBOL(iscsit_build_text_rsp);
35483589

3549-
/*
3550-
* FIXME: Add support for F_BIT and C_BIT when the length is longer than
3551-
* MaxRecvDataSegmentLength.
3552-
*/
35533590
static int iscsit_send_text_rsp(
35543591
struct iscsi_cmd *cmd,
35553592
struct iscsi_conn *conn)
@@ -4013,9 +4050,15 @@ static int iscsi_target_rx_opcode(struct iscsi_conn *conn, unsigned char *buf)
40134050
ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf);
40144051
break;
40154052
case ISCSI_OP_TEXT:
4016-
cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
4017-
if (!cmd)
4018-
goto reject;
4053+
if (hdr->ttt != cpu_to_be32(0xFFFFFFFF)) {
4054+
cmd = iscsit_find_cmd_from_itt(conn, hdr->itt);
4055+
if (!cmd)
4056+
goto reject;
4057+
} else {
4058+
cmd = iscsit_allocate_cmd(conn, TASK_INTERRUPTIBLE);
4059+
if (!cmd)
4060+
goto reject;
4061+
}
40194062

40204063
ret = iscsit_handle_text_cmd(conn, cmd, buf);
40214064
break;

drivers/target/iscsi/iscsi_target_util.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,7 @@ struct iscsi_cmd *iscsit_find_cmd_from_itt(
390390
init_task_tag, conn->cid);
391391
return NULL;
392392
}
393+
EXPORT_SYMBOL(iscsit_find_cmd_from_itt);
393394

394395
struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(
395396
struct iscsi_conn *conn,

drivers/target/iscsi/iscsi_target_util.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32);
1616
extern int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
1717
unsigned char * ,__be32 cmdsn);
1818
extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *);
19-
extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t);
2019
extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *,
2120
itt_t, u32);
2221
extern struct iscsi_cmd *iscsit_find_cmd_from_ttt(struct iscsi_conn *, u32);

include/target/iscsi/iscsi_target_core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,4 +893,5 @@ static inline u32 session_get_next_ttt(struct iscsi_session *session)
893893
return ttt;
894894
}
895895

896+
extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t);
896897
#endif /* ISCSI_TARGET_CORE_H */

0 commit comments

Comments
 (0)