diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-08-12 15:08:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-08-12 15:08:59 -0400 |
commit | a99bcdce8395e3eab534d69eb886a1563030bc00 (patch) | |
tree | 0a8291dbecfd6c074175d6314e120f98c8ba387f | |
parent | 043cd07c555f74ab51c9589d1f5baff4b29929ae (diff) | |
parent | 6f48655facfd7f7ccfe6d252ac0fe319ab02e4dd (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target fixes from Nicholas Bellinger:
"The highlights include:
- Fix iscsi-target payload memory leak during
ISCSI_FLAG_TEXT_CONTINUE (Varun Prakash)
- Fix tcm_qla2xxx incorrect use of tcm_qla2xxx_free_cmd during ABORT
(Pascal de Bruijn + Himanshu Madhani + nab)
- Fix iscsi-target long-standing issue with parallel delete of a
single network portal across multiple target instances (Gary Guo +
nab)
- Fix target dynamic se_node GPF during uncached shutdown regression
(Justin Maggard + nab)"
* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
target: Fix node_acl demo-mode + uncached dynamic shutdown regression
iscsi-target: Fix iscsi_np reset hung task during parallel delete
qla2xxx: Fix incorrect tcm_qla2xxx_free_cmd use during TMR ABORT (v2)
cxgbit: fix sg_nents calculation
iscsi-target: fix invalid flags in text response
iscsi-target: fix memory leak in iscsit_setup_text_cmd()
cxgbit: add missing __kfree_skb()
tcmu: free old string on reconfig
tcmu: Fix possible to/from address overflow when doing the memcpy
-rw-r--r-- | drivers/scsi/qla2xxx/tcm_qla2xxx.c | 30 | ||||
-rw-r--r-- | drivers/target/iscsi/cxgbit/cxgbit_cm.c | 16 | ||||
-rw-r--r-- | drivers/target/iscsi/cxgbit/cxgbit_target.c | 12 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 6 | ||||
-rw-r--r-- | drivers/target/iscsi/iscsi_target_login.c | 7 | ||||
-rw-r--r-- | drivers/target/target_core_tpg.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_transport.c | 4 | ||||
-rw-r--r-- | drivers/target/target_core_user.c | 13 | ||||
-rw-r--r-- | include/target/iscsi/iscsi_target_core.h | 1 |
9 files changed, 40 insertions, 53 deletions
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index b20da0d27ad7..3f82ea1b72dc 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -500,7 +500,6 @@ static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, | |||
500 | static void tcm_qla2xxx_handle_data_work(struct work_struct *work) | 500 | static void tcm_qla2xxx_handle_data_work(struct work_struct *work) |
501 | { | 501 | { |
502 | struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); | 502 | struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); |
503 | unsigned long flags; | ||
504 | 503 | ||
505 | /* | 504 | /* |
506 | * Ensure that the complete FCP WRITE payload has been received. | 505 | * Ensure that the complete FCP WRITE payload has been received. |
@@ -508,17 +507,6 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work) | |||
508 | */ | 507 | */ |
509 | cmd->cmd_in_wq = 0; | 508 | cmd->cmd_in_wq = 0; |
510 | 509 | ||
511 | spin_lock_irqsave(&cmd->cmd_lock, flags); | ||
512 | cmd->data_work = 1; | ||
513 | if (cmd->aborted) { | ||
514 | cmd->data_work_free = 1; | ||
515 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | ||
516 | |||
517 | tcm_qla2xxx_free_cmd(cmd); | ||
518 | return; | ||
519 | } | ||
520 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | ||
521 | |||
522 | cmd->qpair->tgt_counters.qla_core_ret_ctio++; | 510 | cmd->qpair->tgt_counters.qla_core_ret_ctio++; |
523 | if (!cmd->write_data_transferred) { | 511 | if (!cmd->write_data_transferred) { |
524 | /* | 512 | /* |
@@ -765,31 +753,13 @@ static void tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) | |||
765 | qlt_xmit_tm_rsp(mcmd); | 753 | qlt_xmit_tm_rsp(mcmd); |
766 | } | 754 | } |
767 | 755 | ||
768 | #define DATA_WORK_NOT_FREE(_cmd) (_cmd->data_work && !_cmd->data_work_free) | ||
769 | static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd) | 756 | static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd) |
770 | { | 757 | { |
771 | struct qla_tgt_cmd *cmd = container_of(se_cmd, | 758 | struct qla_tgt_cmd *cmd = container_of(se_cmd, |
772 | struct qla_tgt_cmd, se_cmd); | 759 | struct qla_tgt_cmd, se_cmd); |
773 | unsigned long flags; | ||
774 | 760 | ||
775 | if (qlt_abort_cmd(cmd)) | 761 | if (qlt_abort_cmd(cmd)) |
776 | return; | 762 | return; |
777 | |||
778 | spin_lock_irqsave(&cmd->cmd_lock, flags); | ||
779 | if ((cmd->state == QLA_TGT_STATE_NEW)|| | ||
780 | ((cmd->state == QLA_TGT_STATE_DATA_IN) && | ||
781 | DATA_WORK_NOT_FREE(cmd))) { | ||
782 | cmd->data_work_free = 1; | ||
783 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | ||
784 | /* | ||
785 | * cmd has not reached fw, Use this trigger to free it. | ||
786 | */ | ||
787 | tcm_qla2xxx_free_cmd(cmd); | ||
788 | return; | ||
789 | } | ||
790 | spin_unlock_irqrestore(&cmd->cmd_lock, flags); | ||
791 | return; | ||
792 | |||
793 | } | 763 | } |
794 | 764 | ||
795 | static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, | 765 | static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *, |
diff --git a/drivers/target/iscsi/cxgbit/cxgbit_cm.c b/drivers/target/iscsi/cxgbit/cxgbit_cm.c index e583dd8a418b..d4fa41be80f9 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_cm.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_cm.c | |||
@@ -1510,11 +1510,13 @@ cxgbit_pass_open_rpl(struct cxgbit_device *cdev, struct sk_buff *skb) | |||
1510 | 1510 | ||
1511 | if (!cnp) { | 1511 | if (!cnp) { |
1512 | pr_info("%s stid %d lookup failure\n", __func__, stid); | 1512 | pr_info("%s stid %d lookup failure\n", __func__, stid); |
1513 | return; | 1513 | goto rel_skb; |
1514 | } | 1514 | } |
1515 | 1515 | ||
1516 | cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status); | 1516 | cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status); |
1517 | cxgbit_put_cnp(cnp); | 1517 | cxgbit_put_cnp(cnp); |
1518 | rel_skb: | ||
1519 | __kfree_skb(skb); | ||
1518 | } | 1520 | } |
1519 | 1521 | ||
1520 | static void | 1522 | static void |
@@ -1530,11 +1532,13 @@ cxgbit_close_listsrv_rpl(struct cxgbit_device *cdev, struct sk_buff *skb) | |||
1530 | 1532 | ||
1531 | if (!cnp) { | 1533 | if (!cnp) { |
1532 | pr_info("%s stid %d lookup failure\n", __func__, stid); | 1534 | pr_info("%s stid %d lookup failure\n", __func__, stid); |
1533 | return; | 1535 | goto rel_skb; |
1534 | } | 1536 | } |
1535 | 1537 | ||
1536 | cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status); | 1538 | cxgbit_wake_up(&cnp->com.wr_wait, __func__, rpl->status); |
1537 | cxgbit_put_cnp(cnp); | 1539 | cxgbit_put_cnp(cnp); |
1540 | rel_skb: | ||
1541 | __kfree_skb(skb); | ||
1538 | } | 1542 | } |
1539 | 1543 | ||
1540 | static void | 1544 | static void |
@@ -1819,12 +1823,16 @@ static void cxgbit_set_tcb_rpl(struct cxgbit_device *cdev, struct sk_buff *skb) | |||
1819 | struct tid_info *t = lldi->tids; | 1823 | struct tid_info *t = lldi->tids; |
1820 | 1824 | ||
1821 | csk = lookup_tid(t, tid); | 1825 | csk = lookup_tid(t, tid); |
1822 | if (unlikely(!csk)) | 1826 | if (unlikely(!csk)) { |
1823 | pr_err("can't find connection for tid %u.\n", tid); | 1827 | pr_err("can't find connection for tid %u.\n", tid); |
1824 | else | 1828 | goto rel_skb; |
1829 | } else { | ||
1825 | cxgbit_wake_up(&csk->com.wr_wait, __func__, rpl->status); | 1830 | cxgbit_wake_up(&csk->com.wr_wait, __func__, rpl->status); |
1831 | } | ||
1826 | 1832 | ||
1827 | cxgbit_put_csk(csk); | 1833 | cxgbit_put_csk(csk); |
1834 | rel_skb: | ||
1835 | __kfree_skb(skb); | ||
1828 | } | 1836 | } |
1829 | 1837 | ||
1830 | static void cxgbit_rx_data(struct cxgbit_device *cdev, struct sk_buff *skb) | 1838 | static void cxgbit_rx_data(struct cxgbit_device *cdev, struct sk_buff *skb) |
diff --git a/drivers/target/iscsi/cxgbit/cxgbit_target.c b/drivers/target/iscsi/cxgbit/cxgbit_target.c index dda13f1af38e..514986b57c2d 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_target.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_target.c | |||
@@ -827,7 +827,7 @@ cxgbit_put_login_tx(struct iscsi_conn *conn, struct iscsi_login *login, | |||
827 | 827 | ||
828 | static void | 828 | static void |
829 | cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg, | 829 | cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg, |
830 | unsigned int nents) | 830 | unsigned int nents, u32 skip) |
831 | { | 831 | { |
832 | struct skb_seq_state st; | 832 | struct skb_seq_state st; |
833 | const u8 *buf; | 833 | const u8 *buf; |
@@ -846,7 +846,7 @@ cxgbit_skb_copy_to_sg(struct sk_buff *skb, struct scatterlist *sg, | |||
846 | } | 846 | } |
847 | 847 | ||
848 | consumed += sg_pcopy_from_buffer(sg, nents, (void *)buf, | 848 | consumed += sg_pcopy_from_buffer(sg, nents, (void *)buf, |
849 | buf_len, consumed); | 849 | buf_len, skip + consumed); |
850 | } | 850 | } |
851 | } | 851 | } |
852 | 852 | ||
@@ -912,7 +912,7 @@ cxgbit_handle_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr, | |||
912 | struct scatterlist *sg = &cmd->se_cmd.t_data_sg[0]; | 912 | struct scatterlist *sg = &cmd->se_cmd.t_data_sg[0]; |
913 | u32 sg_nents = max(1UL, DIV_ROUND_UP(pdu_cb->dlen, PAGE_SIZE)); | 913 | u32 sg_nents = max(1UL, DIV_ROUND_UP(pdu_cb->dlen, PAGE_SIZE)); |
914 | 914 | ||
915 | cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents); | 915 | cxgbit_skb_copy_to_sg(csk->skb, sg, sg_nents, 0); |
916 | } | 916 | } |
917 | 917 | ||
918 | cmd->write_data_done += pdu_cb->dlen; | 918 | cmd->write_data_done += pdu_cb->dlen; |
@@ -1069,11 +1069,13 @@ static int cxgbit_handle_iscsi_dataout(struct cxgbit_sock *csk) | |||
1069 | cmd->se_cmd.data_length); | 1069 | cmd->se_cmd.data_length); |
1070 | 1070 | ||
1071 | if (!(pdu_cb->flags & PDUCBF_RX_DATA_DDPD)) { | 1071 | if (!(pdu_cb->flags & PDUCBF_RX_DATA_DDPD)) { |
1072 | u32 skip = data_offset % PAGE_SIZE; | ||
1073 | |||
1072 | sg_off = data_offset / PAGE_SIZE; | 1074 | sg_off = data_offset / PAGE_SIZE; |
1073 | sg_start = &cmd->se_cmd.t_data_sg[sg_off]; | 1075 | sg_start = &cmd->se_cmd.t_data_sg[sg_off]; |
1074 | sg_nents = max(1UL, DIV_ROUND_UP(data_len, PAGE_SIZE)); | 1076 | sg_nents = max(1UL, DIV_ROUND_UP(skip + data_len, PAGE_SIZE)); |
1075 | 1077 | ||
1076 | cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents); | 1078 | cxgbit_skb_copy_to_sg(csk->skb, sg_start, sg_nents, skip); |
1077 | } | 1079 | } |
1078 | 1080 | ||
1079 | check_payload: | 1081 | check_payload: |
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 74e4975dd1b1..5001261f5d69 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -418,6 +418,7 @@ int iscsit_reset_np_thread( | |||
418 | return 0; | 418 | return 0; |
419 | } | 419 | } |
420 | np->np_thread_state = ISCSI_NP_THREAD_RESET; | 420 | np->np_thread_state = ISCSI_NP_THREAD_RESET; |
421 | atomic_inc(&np->np_reset_count); | ||
421 | 422 | ||
422 | if (np->np_thread) { | 423 | if (np->np_thread) { |
423 | spin_unlock_bh(&np->np_thread_lock); | 424 | spin_unlock_bh(&np->np_thread_lock); |
@@ -2167,6 +2168,7 @@ iscsit_setup_text_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, | |||
2167 | cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); | 2168 | cmd->cmd_sn = be32_to_cpu(hdr->cmdsn); |
2168 | cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); | 2169 | cmd->exp_stat_sn = be32_to_cpu(hdr->exp_statsn); |
2169 | cmd->data_direction = DMA_NONE; | 2170 | cmd->data_direction = DMA_NONE; |
2171 | kfree(cmd->text_in_ptr); | ||
2170 | cmd->text_in_ptr = NULL; | 2172 | cmd->text_in_ptr = NULL; |
2171 | 2173 | ||
2172 | return 0; | 2174 | return 0; |
@@ -3487,9 +3489,9 @@ iscsit_build_text_rsp(struct iscsi_cmd *cmd, struct iscsi_conn *conn, | |||
3487 | return text_length; | 3489 | return text_length; |
3488 | 3490 | ||
3489 | if (completed) { | 3491 | if (completed) { |
3490 | hdr->flags |= ISCSI_FLAG_CMD_FINAL; | 3492 | hdr->flags = ISCSI_FLAG_CMD_FINAL; |
3491 | } else { | 3493 | } else { |
3492 | hdr->flags |= ISCSI_FLAG_TEXT_CONTINUE; | 3494 | hdr->flags = ISCSI_FLAG_TEXT_CONTINUE; |
3493 | cmd->read_data_done += text_length; | 3495 | cmd->read_data_done += text_length; |
3494 | if (cmd->targ_xfer_tag == 0xFFFFFFFF) | 3496 | if (cmd->targ_xfer_tag == 0xFFFFFFFF) |
3495 | cmd->targ_xfer_tag = session_get_next_ttt(conn->sess); | 3497 | cmd->targ_xfer_tag = session_get_next_ttt(conn->sess); |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index e9bdc8b86e7d..dc13afbd4c88 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -1243,9 +1243,11 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) | |||
1243 | flush_signals(current); | 1243 | flush_signals(current); |
1244 | 1244 | ||
1245 | spin_lock_bh(&np->np_thread_lock); | 1245 | spin_lock_bh(&np->np_thread_lock); |
1246 | if (np->np_thread_state == ISCSI_NP_THREAD_RESET) { | 1246 | if (atomic_dec_if_positive(&np->np_reset_count) >= 0) { |
1247 | np->np_thread_state = ISCSI_NP_THREAD_ACTIVE; | 1247 | np->np_thread_state = ISCSI_NP_THREAD_ACTIVE; |
1248 | spin_unlock_bh(&np->np_thread_lock); | ||
1248 | complete(&np->np_restart_comp); | 1249 | complete(&np->np_restart_comp); |
1250 | return 1; | ||
1249 | } else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) { | 1251 | } else if (np->np_thread_state == ISCSI_NP_THREAD_SHUTDOWN) { |
1250 | spin_unlock_bh(&np->np_thread_lock); | 1252 | spin_unlock_bh(&np->np_thread_lock); |
1251 | goto exit; | 1253 | goto exit; |
@@ -1278,7 +1280,8 @@ static int __iscsi_target_login_thread(struct iscsi_np *np) | |||
1278 | goto exit; | 1280 | goto exit; |
1279 | } else if (rc < 0) { | 1281 | } else if (rc < 0) { |
1280 | spin_lock_bh(&np->np_thread_lock); | 1282 | spin_lock_bh(&np->np_thread_lock); |
1281 | if (np->np_thread_state == ISCSI_NP_THREAD_RESET) { | 1283 | if (atomic_dec_if_positive(&np->np_reset_count) >= 0) { |
1284 | np->np_thread_state = ISCSI_NP_THREAD_ACTIVE; | ||
1282 | spin_unlock_bh(&np->np_thread_lock); | 1285 | spin_unlock_bh(&np->np_thread_lock); |
1283 | complete(&np->np_restart_comp); | 1286 | complete(&np->np_restart_comp); |
1284 | iscsit_put_transport(conn->conn_transport); | 1287 | iscsit_put_transport(conn->conn_transport); |
diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 36913734c6bc..02e8a5d86658 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c | |||
@@ -364,7 +364,7 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl) | |||
364 | mutex_lock(&tpg->acl_node_mutex); | 364 | mutex_lock(&tpg->acl_node_mutex); |
365 | if (acl->dynamic_node_acl) | 365 | if (acl->dynamic_node_acl) |
366 | acl->dynamic_node_acl = 0; | 366 | acl->dynamic_node_acl = 0; |
367 | list_del(&acl->acl_list); | 367 | list_del_init(&acl->acl_list); |
368 | mutex_unlock(&tpg->acl_node_mutex); | 368 | mutex_unlock(&tpg->acl_node_mutex); |
369 | 369 | ||
370 | target_shutdown_sessions(acl); | 370 | target_shutdown_sessions(acl); |
@@ -548,7 +548,7 @@ int core_tpg_deregister(struct se_portal_group *se_tpg) | |||
548 | * in transport_deregister_session(). | 548 | * in transport_deregister_session(). |
549 | */ | 549 | */ |
550 | list_for_each_entry_safe(nacl, nacl_tmp, &node_list, acl_list) { | 550 | list_for_each_entry_safe(nacl, nacl_tmp, &node_list, acl_list) { |
551 | list_del(&nacl->acl_list); | 551 | list_del_init(&nacl->acl_list); |
552 | 552 | ||
553 | core_tpg_wait_for_nacl_pr_ref(nacl); | 553 | core_tpg_wait_for_nacl_pr_ref(nacl); |
554 | core_free_device_list_for_node(nacl, se_tpg); | 554 | core_free_device_list_for_node(nacl, se_tpg); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 97fed9a298bd..836d552b0385 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -466,7 +466,7 @@ static void target_complete_nacl(struct kref *kref) | |||
466 | } | 466 | } |
467 | 467 | ||
468 | mutex_lock(&se_tpg->acl_node_mutex); | 468 | mutex_lock(&se_tpg->acl_node_mutex); |
469 | list_del(&nacl->acl_list); | 469 | list_del_init(&nacl->acl_list); |
470 | mutex_unlock(&se_tpg->acl_node_mutex); | 470 | mutex_unlock(&se_tpg->acl_node_mutex); |
471 | 471 | ||
472 | core_tpg_wait_for_nacl_pr_ref(nacl); | 472 | core_tpg_wait_for_nacl_pr_ref(nacl); |
@@ -538,7 +538,7 @@ void transport_free_session(struct se_session *se_sess) | |||
538 | spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags); | 538 | spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags); |
539 | 539 | ||
540 | if (se_nacl->dynamic_stop) | 540 | if (se_nacl->dynamic_stop) |
541 | list_del(&se_nacl->acl_list); | 541 | list_del_init(&se_nacl->acl_list); |
542 | } | 542 | } |
543 | mutex_unlock(&se_tpg->acl_node_mutex); | 543 | mutex_unlock(&se_tpg->acl_node_mutex); |
544 | 544 | ||
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 80ee130f8253..942d094269fb 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c | |||
@@ -563,8 +563,6 @@ static int scatter_data_area(struct tcmu_dev *udev, | |||
563 | block_remaining); | 563 | block_remaining); |
564 | to_offset = get_block_offset_user(udev, dbi, | 564 | to_offset = get_block_offset_user(udev, dbi, |
565 | block_remaining); | 565 | block_remaining); |
566 | offset = DATA_BLOCK_SIZE - block_remaining; | ||
567 | to += offset; | ||
568 | 566 | ||
569 | if (*iov_cnt != 0 && | 567 | if (*iov_cnt != 0 && |
570 | to_offset == iov_tail(*iov)) { | 568 | to_offset == iov_tail(*iov)) { |
@@ -575,8 +573,10 @@ static int scatter_data_area(struct tcmu_dev *udev, | |||
575 | (*iov)->iov_len = copy_bytes; | 573 | (*iov)->iov_len = copy_bytes; |
576 | } | 574 | } |
577 | if (copy_data) { | 575 | if (copy_data) { |
578 | memcpy(to, from + sg->length - sg_remaining, | 576 | offset = DATA_BLOCK_SIZE - block_remaining; |
579 | copy_bytes); | 577 | memcpy(to + offset, |
578 | from + sg->length - sg_remaining, | ||
579 | copy_bytes); | ||
580 | tcmu_flush_dcache_range(to, copy_bytes); | 580 | tcmu_flush_dcache_range(to, copy_bytes); |
581 | } | 581 | } |
582 | sg_remaining -= copy_bytes; | 582 | sg_remaining -= copy_bytes; |
@@ -637,9 +637,8 @@ static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd, | |||
637 | copy_bytes = min_t(size_t, sg_remaining, | 637 | copy_bytes = min_t(size_t, sg_remaining, |
638 | block_remaining); | 638 | block_remaining); |
639 | offset = DATA_BLOCK_SIZE - block_remaining; | 639 | offset = DATA_BLOCK_SIZE - block_remaining; |
640 | from += offset; | ||
641 | tcmu_flush_dcache_range(from, copy_bytes); | 640 | tcmu_flush_dcache_range(from, copy_bytes); |
642 | memcpy(to + sg->length - sg_remaining, from, | 641 | memcpy(to + sg->length - sg_remaining, from + offset, |
643 | copy_bytes); | 642 | copy_bytes); |
644 | 643 | ||
645 | sg_remaining -= copy_bytes; | 644 | sg_remaining -= copy_bytes; |
@@ -1433,6 +1432,8 @@ static int tcmu_update_uio_info(struct tcmu_dev *udev) | |||
1433 | if (udev->dev_config[0]) | 1432 | if (udev->dev_config[0]) |
1434 | snprintf(str + used, size - used, "/%s", udev->dev_config); | 1433 | snprintf(str + used, size - used, "/%s", udev->dev_config); |
1435 | 1434 | ||
1435 | /* If the old string exists, free it */ | ||
1436 | kfree(info->name); | ||
1436 | info->name = str; | 1437 | info->name = str; |
1437 | 1438 | ||
1438 | return 0; | 1439 | return 0; |
diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index 0ca1fb08805b..fb87d32f5e51 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h | |||
@@ -786,6 +786,7 @@ struct iscsi_np { | |||
786 | int np_sock_type; | 786 | int np_sock_type; |
787 | enum np_thread_state_table np_thread_state; | 787 | enum np_thread_state_table np_thread_state; |
788 | bool enabled; | 788 | bool enabled; |
789 | atomic_t np_reset_count; | ||
789 | enum iscsi_timer_flags_table np_login_timer_flags; | 790 | enum iscsi_timer_flags_table np_login_timer_flags; |
790 | u32 np_exports; | 791 | u32 np_exports; |
791 | enum np_flags_table np_flags; | 792 | enum np_flags_table np_flags; |