diff options
Diffstat (limited to 'drivers/target/iscsi/iscsi_target.c')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 90 |
1 files changed, 46 insertions, 44 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 38e44b9abf0f..d70e9119e906 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -805,14 +805,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
805 | int iscsi_task_attr; | 805 | int iscsi_task_attr; |
806 | int sam_task_attr; | 806 | int sam_task_attr; |
807 | 807 | ||
808 | spin_lock_bh(&conn->sess->session_stats_lock); | 808 | atomic_long_inc(&conn->sess->cmd_pdus); |
809 | conn->sess->cmd_pdus++; | ||
810 | if (conn->sess->se_sess->se_node_acl) { | ||
811 | spin_lock(&conn->sess->se_sess->se_node_acl->stats_lock); | ||
812 | conn->sess->se_sess->se_node_acl->num_cmds++; | ||
813 | spin_unlock(&conn->sess->se_sess->se_node_acl->stats_lock); | ||
814 | } | ||
815 | spin_unlock_bh(&conn->sess->session_stats_lock); | ||
816 | 809 | ||
817 | hdr = (struct iscsi_scsi_req *) buf; | 810 | hdr = (struct iscsi_scsi_req *) buf; |
818 | payload_length = ntoh24(hdr->dlength); | 811 | payload_length = ntoh24(hdr->dlength); |
@@ -1254,20 +1247,12 @@ iscsit_check_dataout_hdr(struct iscsi_conn *conn, unsigned char *buf, | |||
1254 | int rc; | 1247 | int rc; |
1255 | 1248 | ||
1256 | if (!payload_length) { | 1249 | if (!payload_length) { |
1257 | pr_err("DataOUT payload is ZERO, protocol error.\n"); | 1250 | pr_warn("DataOUT payload is ZERO, ignoring.\n"); |
1258 | return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, | 1251 | return 0; |
1259 | buf); | ||
1260 | } | 1252 | } |
1261 | 1253 | ||
1262 | /* iSCSI write */ | 1254 | /* iSCSI write */ |
1263 | spin_lock_bh(&conn->sess->session_stats_lock); | 1255 | atomic_long_add(payload_length, &conn->sess->rx_data_octets); |
1264 | conn->sess->rx_data_octets += payload_length; | ||
1265 | if (conn->sess->se_sess->se_node_acl) { | ||
1266 | spin_lock(&conn->sess->se_sess->se_node_acl->stats_lock); | ||
1267 | conn->sess->se_sess->se_node_acl->write_bytes += payload_length; | ||
1268 | spin_unlock(&conn->sess->se_sess->se_node_acl->stats_lock); | ||
1269 | } | ||
1270 | spin_unlock_bh(&conn->sess->session_stats_lock); | ||
1271 | 1256 | ||
1272 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { | 1257 | if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) { |
1273 | pr_err("DataSegmentLength: %u is greater than" | 1258 | pr_err("DataSegmentLength: %u is greater than" |
@@ -1486,7 +1471,7 @@ EXPORT_SYMBOL(iscsit_check_dataout_payload); | |||
1486 | 1471 | ||
1487 | static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) | 1472 | static int iscsit_handle_data_out(struct iscsi_conn *conn, unsigned char *buf) |
1488 | { | 1473 | { |
1489 | struct iscsi_cmd *cmd; | 1474 | struct iscsi_cmd *cmd = NULL; |
1490 | struct iscsi_data *hdr = (struct iscsi_data *)buf; | 1475 | struct iscsi_data *hdr = (struct iscsi_data *)buf; |
1491 | int rc; | 1476 | int rc; |
1492 | bool data_crc_failed = false; | 1477 | bool data_crc_failed = false; |
@@ -1954,6 +1939,13 @@ iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
1954 | (unsigned char *)hdr); | 1939 | (unsigned char *)hdr); |
1955 | } | 1940 | } |
1956 | 1941 | ||
1942 | if (!(hdr->flags & ISCSI_FLAG_CMD_FINAL) || | ||
1943 | (hdr->flags & ISCSI_FLAG_TEXT_CONTINUE)) { | ||
1944 | pr_err("Multi sequence text commands currently not supported\n"); | ||
1945 | return iscsit_reject_cmd(cmd, ISCSI_REASON_CMD_NOT_SUPPORTED, | ||
1946 | (unsigned char *)hdr); | ||
1947 | } | ||
1948 | |||
1957 | pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x," | 1949 | pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x," |
1958 | " ExpStatSN: 0x%08x, Length: %u\n", hdr->itt, hdr->cmdsn, | 1950 | " ExpStatSN: 0x%08x, Length: %u\n", hdr->itt, hdr->cmdsn, |
1959 | hdr->exp_statsn, payload_length); | 1951 | hdr->exp_statsn, payload_length); |
@@ -2630,14 +2622,7 @@ static int iscsit_send_datain(struct iscsi_cmd *cmd, struct iscsi_conn *conn) | |||
2630 | return -1; | 2622 | return -1; |
2631 | } | 2623 | } |
2632 | 2624 | ||
2633 | spin_lock_bh(&conn->sess->session_stats_lock); | 2625 | atomic_long_add(datain.length, &conn->sess->tx_data_octets); |
2634 | conn->sess->tx_data_octets += datain.length; | ||
2635 | if (conn->sess->se_sess->se_node_acl) { | ||
2636 | spin_lock(&conn->sess->se_sess->se_node_acl->stats_lock); | ||
2637 | conn->sess->se_sess->se_node_acl->read_bytes += datain.length; | ||
2638 | spin_unlock(&conn->sess->se_sess->se_node_acl->stats_lock); | ||
2639 | } | ||
2640 | spin_unlock_bh(&conn->sess->session_stats_lock); | ||
2641 | /* | 2626 | /* |
2642 | * Special case for successfully execution w/ both DATAIN | 2627 | * Special case for successfully execution w/ both DATAIN |
2643 | * and Sense Data. | 2628 | * and Sense Data. |
@@ -3162,9 +3147,7 @@ void iscsit_build_rsp_pdu(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
3162 | if (inc_stat_sn) | 3147 | if (inc_stat_sn) |
3163 | cmd->stat_sn = conn->stat_sn++; | 3148 | cmd->stat_sn = conn->stat_sn++; |
3164 | 3149 | ||
3165 | spin_lock_bh(&conn->sess->session_stats_lock); | 3150 | atomic_long_inc(&conn->sess->rsp_pdus); |
3166 | conn->sess->rsp_pdus++; | ||
3167 | spin_unlock_bh(&conn->sess->session_stats_lock); | ||
3168 | 3151 | ||
3169 | memset(hdr, 0, ISCSI_HDR_LEN); | 3152 | memset(hdr, 0, ISCSI_HDR_LEN); |
3170 | hdr->opcode = ISCSI_OP_SCSI_CMD_RSP; | 3153 | hdr->opcode = ISCSI_OP_SCSI_CMD_RSP; |
@@ -3374,6 +3357,7 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) | |||
3374 | struct iscsi_tiqn *tiqn; | 3357 | struct iscsi_tiqn *tiqn; |
3375 | struct iscsi_tpg_np *tpg_np; | 3358 | struct iscsi_tpg_np *tpg_np; |
3376 | int buffer_len, end_of_buf = 0, len = 0, payload_len = 0; | 3359 | int buffer_len, end_of_buf = 0, len = 0, payload_len = 0; |
3360 | int target_name_printed; | ||
3377 | unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */ | 3361 | unsigned char buf[ISCSI_IQN_LEN+12]; /* iqn + "TargetName=" + \0 */ |
3378 | unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL; | 3362 | unsigned char *text_in = cmd->text_in_ptr, *text_ptr = NULL; |
3379 | 3363 | ||
@@ -3411,19 +3395,23 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) | |||
3411 | continue; | 3395 | continue; |
3412 | } | 3396 | } |
3413 | 3397 | ||
3414 | len = sprintf(buf, "TargetName=%s", tiqn->tiqn); | 3398 | target_name_printed = 0; |
3415 | len += 1; | ||
3416 | |||
3417 | if ((len + payload_len) > buffer_len) { | ||
3418 | end_of_buf = 1; | ||
3419 | goto eob; | ||
3420 | } | ||
3421 | memcpy(payload + payload_len, buf, len); | ||
3422 | payload_len += len; | ||
3423 | 3399 | ||
3424 | spin_lock(&tiqn->tiqn_tpg_lock); | 3400 | spin_lock(&tiqn->tiqn_tpg_lock); |
3425 | list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) { | 3401 | list_for_each_entry(tpg, &tiqn->tiqn_tpg_list, tpg_list) { |
3426 | 3402 | ||
3403 | /* If demo_mode_discovery=0 and generate_node_acls=0 | ||
3404 | * (demo mode dislabed) do not return | ||
3405 | * TargetName+TargetAddress unless a NodeACL exists. | ||
3406 | */ | ||
3407 | |||
3408 | if ((tpg->tpg_attrib.generate_node_acls == 0) && | ||
3409 | (tpg->tpg_attrib.demo_mode_discovery == 0) && | ||
3410 | (!core_tpg_get_initiator_node_acl(&tpg->tpg_se_tpg, | ||
3411 | cmd->conn->sess->sess_ops->InitiatorName))) { | ||
3412 | continue; | ||
3413 | } | ||
3414 | |||
3427 | spin_lock(&tpg->tpg_state_lock); | 3415 | spin_lock(&tpg->tpg_state_lock); |
3428 | if ((tpg->tpg_state == TPG_STATE_FREE) || | 3416 | if ((tpg->tpg_state == TPG_STATE_FREE) || |
3429 | (tpg->tpg_state == TPG_STATE_INACTIVE)) { | 3417 | (tpg->tpg_state == TPG_STATE_INACTIVE)) { |
@@ -3438,6 +3426,22 @@ static int iscsit_build_sendtargets_response(struct iscsi_cmd *cmd) | |||
3438 | struct iscsi_np *np = tpg_np->tpg_np; | 3426 | struct iscsi_np *np = tpg_np->tpg_np; |
3439 | bool inaddr_any = iscsit_check_inaddr_any(np); | 3427 | bool inaddr_any = iscsit_check_inaddr_any(np); |
3440 | 3428 | ||
3429 | if (!target_name_printed) { | ||
3430 | len = sprintf(buf, "TargetName=%s", | ||
3431 | tiqn->tiqn); | ||
3432 | len += 1; | ||
3433 | |||
3434 | if ((len + payload_len) > buffer_len) { | ||
3435 | spin_unlock(&tpg->tpg_np_lock); | ||
3436 | spin_unlock(&tiqn->tiqn_tpg_lock); | ||
3437 | end_of_buf = 1; | ||
3438 | goto eob; | ||
3439 | } | ||
3440 | memcpy(payload + payload_len, buf, len); | ||
3441 | payload_len += len; | ||
3442 | target_name_printed = 1; | ||
3443 | } | ||
3444 | |||
3441 | len = sprintf(buf, "TargetAddress=" | 3445 | len = sprintf(buf, "TargetAddress=" |
3442 | "%s:%hu,%hu", | 3446 | "%s:%hu,%hu", |
3443 | (inaddr_any == false) ? | 3447 | (inaddr_any == false) ? |
@@ -4092,9 +4096,7 @@ restart: | |||
4092 | * hit default in the switch below. | 4096 | * hit default in the switch below. |
4093 | */ | 4097 | */ |
4094 | memset(buffer, 0xff, ISCSI_HDR_LEN); | 4098 | memset(buffer, 0xff, ISCSI_HDR_LEN); |
4095 | spin_lock_bh(&conn->sess->session_stats_lock); | 4099 | atomic_long_inc(&conn->sess->conn_digest_errors); |
4096 | conn->sess->conn_digest_errors++; | ||
4097 | spin_unlock_bh(&conn->sess->session_stats_lock); | ||
4098 | } else { | 4100 | } else { |
4099 | pr_debug("Got HeaderDigest CRC32C" | 4101 | pr_debug("Got HeaderDigest CRC32C" |
4100 | " 0x%08x\n", checksum); | 4102 | " 0x%08x\n", checksum); |
@@ -4381,7 +4383,7 @@ int iscsit_close_connection( | |||
4381 | 4383 | ||
4382 | int iscsit_close_session(struct iscsi_session *sess) | 4384 | int iscsit_close_session(struct iscsi_session *sess) |
4383 | { | 4385 | { |
4384 | struct iscsi_portal_group *tpg = ISCSI_TPG_S(sess); | 4386 | struct iscsi_portal_group *tpg = sess->tpg; |
4385 | struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; | 4387 | struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; |
4386 | 4388 | ||
4387 | if (atomic_read(&sess->nconn)) { | 4389 | if (atomic_read(&sess->nconn)) { |