From: Kristof V. D. <kva...@as...> - 2009-12-08 10:14:26
|
Hey Vladislav, Thanks for sending the patch. I applied the patch. At this moment I'm installing windows 7 on the iscsi target. So no crash anymore at the point where I could select the disk. Kristof On 07 Dec 2009, at 21:07, Vladislav Bolkhovitin wrote: > Hi Kristof, Benjamin, > > Please try with the attached patch. It's quite raw, so be cautious. > > Thanks, > Vlad > > P.S. One more piece of IET code is going to be rewritten.. > Index: iscsi-scst/kernel/iscsi.c > =================================================================== > --- iscsi-scst/kernel/iscsi.c (revision 1375) > +++ iscsi-scst/kernel/iscsi.c (working copy) > @@ -93,7 +93,7 @@ static inline int cmnd_read_size(struct > ahdr = (struct iscsi_ahs_hdr *)cmnd->pdu.ahs; > if (ahdr != NULL) { > uint8_t *p = (uint8_t *)ahdr; > - int size = 0; > + unsigned int size = 0; > do { > int s; > > @@ -582,7 +582,7 @@ static void iscsi_cmnds_init_write(struc > */ > if ((flags & ISCSI_INIT_WRITE_REMOVE_HASH) && > rsp->parent_req->hashed && > - (rsp->parent_req->r2t_length == 0) && > + (rsp->parent_req->r2t_len_to_receive == 0) && > (rsp->parent_req->outstanding_r2t == 0)) > cmnd_remove_hash(rsp->parent_req); > > @@ -624,12 +624,9 @@ static void iscsi_cmnd_init_write(struct > > if (unlikely(rsp->on_write_list)) { > PRINT_CRIT_ERROR("cmd already on write list (%x %x %x %x %u " > - "%u %u %u %u %u %u %d %d", > - cmnd_itt(rsp), cmnd_ttt(rsp), cmnd_opcode(rsp), > - cmnd_scsicode(rsp), rsp->r2t_sn, > - rsp->r2t_length, rsp->is_unsolicited_data, > - rsp->target_task_tag, rsp->outstanding_r2t, > - rsp->hdigest, rsp->ddigest, > + "%u %u %d %d", cmnd_itt(rsp), cmnd_ttt(rsp), > + cmnd_opcode(rsp), cmnd_scsicode(rsp), > + rsp->target_task_tag, rsp->hdigest, rsp->ddigest, > list_empty(&rsp->rsp_cmd_list), rsp->hashed); > sBUG(); > } > @@ -672,7 +669,7 @@ static void send_data_rsp(struct iscsi_c > TRACE_DBG("offset %d, size %d", offset, size); > rsp->pdu.datasize = size; > if (send_status) { > - int scsisize; > + unsigned int scsisize; > > TRACE_DBG("status %x", status); > > @@ -1169,8 +1166,10 @@ static void send_r2t(struct iscsi_cmnd * > > if (unlikely(req->tm_aborted)) { > TRACE_MGMT_DBG("req %p (scst_cmd %p) aborted on R2T " > - "(r2t_length %d, outstanding_r2t %d)", req, > - req->scst_cmd, req->r2t_length, req->outstanding_r2t); > + "(r2t_len_to_send %d, r2t_len_to_receive %d, " > + "outstanding_r2t %d)", req, req->scst_cmd, > + req->r2t_len_to_send, req->r2t_len_to_receive, > + req->outstanding_r2t); > if (req->outstanding_r2t == 0) > iscsi_fail_waiting_cmnd(req); > goto out; > @@ -1182,8 +1181,12 @@ static void send_r2t(struct iscsi_cmnd * > */ > iscsi_extracheck_is_rd_thread(req->conn); > > + EXTRACHECKS_BUG_ON(req->outstanding_r2t >= > + session->sess_param.max_outstanding_r2t); > + > burst = session->sess_param.max_burst_length; > - offset = be32_to_cpu(cmnd_hdr(req)->data_length) - req->r2t_length; > + offset = be32_to_cpu(cmnd_hdr(req)->data_length) - > + req->r2t_len_to_send; > > do { > rsp = iscsi_cmnd_create_rsp_cmnd(req); > @@ -1195,13 +1198,13 @@ static void send_r2t(struct iscsi_cmnd * > rsp_hdr->itt = cmnd_hdr(req)->itt; > rsp_hdr->r2t_sn = cpu_to_be32(req->r2t_sn++); > rsp_hdr->buffer_offset = cpu_to_be32(offset); > - if (req->r2t_length > burst) { > + if (req->r2t_len_to_send > burst) { > rsp_hdr->data_length = cpu_to_be32(burst); > - req->r2t_length -= burst; > + req->r2t_len_to_send -= burst; > offset += burst; > } else { > - rsp_hdr->data_length = cpu_to_be32(req->r2t_length); > - req->r2t_length = 0; > + rsp_hdr->data_length = cpu_to_be32(req->r2t_len_to_send); > + req->r2t_len_to_send = 0; > } > > TRACE_WRITE("%x %u %u %u %u", cmnd_itt(req), > @@ -1210,11 +1213,10 @@ static void send_r2t(struct iscsi_cmnd * > be32_to_cpu(rsp_hdr->r2t_sn), req->outstanding_r2t); > > list_add_tail(&rsp->write_list_entry, &send); > + req->outstanding_r2t++; > > - if (++req->outstanding_r2t >= session->sess_param.max_outstanding_r2t) > - break; > - > - } while (req->r2t_length != 0); > + } while ((req->r2t_len_to_send != 0) && > + (req->outstanding_r2t >= session->sess_param.max_outstanding_r2t)); > > iscsi_cmnds_init_write(&send, ISCSI_INIT_WRITE_WAKE); > > @@ -1397,13 +1399,77 @@ int cmnd_rx_continue(struct iscsi_cmnd * > sBUG(); > } > > + req->target_task_tag = get_next_ttt(conn); > + > dir = scst_cmd_get_data_direction(scst_cmd); > + > + if (dir != SCST_DATA_BIDI) { > + req->sg = scst_cmd_get_sg(scst_cmd); > + req->sg_cnt = scst_cmd_get_sg_cnt(scst_cmd); > + req->bufflen = scst_cmd_get_bufflen(scst_cmd); > + } else { > + req->sg = scst_cmd_get_in_sg(scst_cmd); > + req->sg_cnt = scst_cmd_get_in_sg_cnt(scst_cmd); > + req->bufflen = scst_cmd_get_in_bufflen(scst_cmd); > + } > + > if (dir & SCST_DATA_WRITE) { > - req->is_unsolicited_data = !(req_hdr->flags & ISCSI_CMD_FINAL); > - req->r2t_length = be32_to_cpu(req_hdr->data_length) - > - req->pdu.datasize; > - if (req->r2t_length > 0) > + req->unsolicited_data_expected = !(req_hdr->flags & ISCSI_CMD_FINAL); > + > + if (unlikely(session->sess_param.initial_r2t && > + req->unsolicited_data_expected)) { > + PRINT_ERROR("Initiator %s violated negotiated " > + "parameters: initial R2T is required (ITT %x, " > + "op %x)", session->initiator_name, > + cmnd_itt(req), req_hdr->scb[0]); > + res = -EINVAL; > + goto out; > + } > + > + if (unlikely(!session->sess_param.immediate_data && > + req->pdu.datasize)) { > + PRINT_ERROR("Initiator %s violated negotiated " > + "parameters: forbidden immediate data sent " > + "(ITT %x, op %x)", session->initiator_name, > + cmnd_itt(req), req_hdr->scb[0]); > + res = -EINVAL; > + goto out; > + } > + > + if (unlikely(session->sess_param.first_burst_length < req->pdu.datasize)) { > + PRINT_ERROR("Initiator %s violated negotiated " > + "parameters: immediate data len (%d) > " > + "first_burst_length (%d) (ITT %x, op %x)", > + session->initiator_name, > + req->pdu.datasize, > + session->sess_param.first_burst_length, > + cmnd_itt(req), req_hdr->scb[0]); > + res = -EINVAL; > + goto out; > + } > + > + req->r2t_len_to_receive = be32_to_cpu(req_hdr->data_length) - > + req->pdu.datasize; > + > + if (unlikely(req->r2t_len_to_receive > req->bufflen)) { > + PRINT_ERROR("req->r2t_len_to_receive %d > req->bufflen %d", > + req->r2t_len_to_receive, req->bufflen); > + req->r2t_len_to_receive = req->bufflen - req->pdu.datasize; > + } > + > + if (req->unsolicited_data_expected) { > + req->r2t_len_to_send = req->r2t_len_to_receive - > + min_t(unsigned int, > + session->sess_param.first_burst_length - req->pdu.datasize, > + req->r2t_len_to_receive); > + } else > + req->r2t_len_to_send = req->r2t_len_to_receive; > + > + if (req->r2t_len_to_receive > 0) > req->data_waiting = 1; > + > + if (req->pdu.datasize) > + res = cmnd_prepare_recv_pdu(conn, req, 0, req->pdu.datasize); > } else { > if (unlikely(!(req_hdr->flags & ISCSI_CMD_FINAL) || > req->pdu.datasize)) { > @@ -1421,49 +1487,11 @@ int cmnd_rx_continue(struct iscsi_cmnd * > goto out; > } > } > - > - req->target_task_tag = get_next_ttt(conn); > - if (dir != SCST_DATA_BIDI) { > - req->sg = scst_cmd_get_sg(scst_cmd); > - req->sg_cnt = scst_cmd_get_sg_cnt(scst_cmd); > - req->bufflen = scst_cmd_get_bufflen(scst_cmd); > - } else { > - req->sg = scst_cmd_get_in_sg(scst_cmd); > - req->sg_cnt = scst_cmd_get_in_sg_cnt(scst_cmd); > - req->bufflen = scst_cmd_get_in_bufflen(scst_cmd); > - } > - if (unlikely(req->r2t_length > req->bufflen)) { > - PRINT_ERROR("req->r2t_length %d > req->bufflen %d", > - req->r2t_length, req->bufflen); > - req->r2t_length = req->bufflen; > - } > - > - TRACE_DBG("req=%p, dir=%d, is_unsolicited_data=%d, " > - "r2t_length=%d, bufflen=%d", req, dir, > - req->is_unsolicited_data, req->r2t_length, req->bufflen); > - > - if (unlikely(!session->sess_param.immediate_data && > - req->pdu.datasize)) { > - PRINT_ERROR("Initiator %s violated negotiated paremeters: " > - "forbidden immediate data sent (ITT %x, op %x)", > - session->initiator_name, cmnd_itt(req), > - req_hdr->scb[0]); > - res = -EINVAL; > - goto out; > - } > - > - if (unlikely(session->sess_param.initial_r2t && > - !(req_hdr->flags & ISCSI_CMD_FINAL))) { > - PRINT_ERROR("Initiator %s violated negotiated paremeters: " > - "initial R2T is required (ITT %x, op %x)", > - session->initiator_name, cmnd_itt(req), > - req_hdr->scb[0]); > - res = -EINVAL; > - goto out; > - } > - > - if (req->pdu.datasize) > - res = cmnd_prepare_recv_pdu(conn, req, 0, req->pdu.datasize); > + > + TRACE_DBG("req=%p, dir=%d, unsolicited_data_expected=%d, " > + "r2t_len_to_receive=%d, r2t_len_to_send=%d, bufflen=%d", req, > + dir, req->unsolicited_data_expected, req->r2t_len_to_receive, > + req->r2t_len_to_send, req->bufflen); > > out: > /* Aborted commands will be freed in cmnd_rx_end() */ > @@ -1572,7 +1600,7 @@ static int scsi_cmnd_start(struct iscsi_ > ahdr = (struct iscsi_ahs_hdr *)req->pdu.ahs; > if (ahdr != NULL) { > uint8_t *p = (uint8_t *)ahdr; > - int size = 0; > + unsigned int size = 0; > do { > int s; > > @@ -1639,25 +1667,33 @@ static int data_out_start(struct iscsi_c > goto out_reject; > } > > - if (orig_req->is_unsolicited_data) { > - if (unlikely(orig_req->r2t_length < cmnd->pdu.datasize)) { > - PRINT_ERROR("Data size (%d) > R2T length (%d)", > - cmnd->pdu.datasize, orig_req->r2t_length); > + if (unlikely(orig_req->r2t_len_to_receive < cmnd->pdu.datasize)) { > + PRINT_ERROR("Data size (%d) > R2T length to receive (%d)", > + cmnd->pdu.datasize, orig_req->r2t_len_to_receive); > + mark_conn_closed(conn); > + res = -EINVAL; > + goto out; > + } > + > + if (req_hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) { > + if (unlikely(orig_req->pdu.bhs.flags & ISCSI_FLG_FINAL)) { > + PRINT_ERROR("Unexpected unsolicited data from %x %x", > + cmnd_itt(cmnd), cmnd_ttt(cmnd)); > + mark_conn_closed(conn); > + res = -EINVAL; > + goto out; > + } > + if (unlikely(!orig_req->unsolicited_data_expected)) { > + PRINT_ERROR("Unexpected unsolicited data " > + "(r2t_len_to_receive %d, r2t_len_to_send %d, " > + "outstanding_r2t %d)", > + orig_req->r2t_len_to_receive, > + orig_req->r2t_len_to_send, > + orig_req->unsolicited_data_expected); > mark_conn_closed(conn); > res = -EINVAL; > goto out; > } > - orig_req->r2t_length -= cmnd->pdu.datasize; > - } > - > - /* Check unsolicited burst data */ > - if (unlikely((req_hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) && > - (orig_req->pdu.bhs.flags & ISCSI_FLG_FINAL))) { > - PRINT_ERROR("Unexpected data from %x %x", > - cmnd_itt(cmnd), cmnd_ttt(cmnd)); > - mark_conn_closed(conn); > - res = -EINVAL; > - goto out; > } > > TRACE_WRITE("%u %p %p %u %u", req_hdr->ttt, cmnd, orig_req, > @@ -1697,39 +1733,32 @@ static void data_out_end(struct iscsi_cm > cmnd_get(cmnd); > } > > + EXTRACHECKS_BUG_ON(req->r2t_len_to_receive < cmnd->pdu.datasize); > + req->r2t_len_to_receive -= cmnd->pdu.datasize; > + > if (req_hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) { > TRACE_DBG("ISCSI_RESERVED_TAG, FINAL %x", > req_hdr->flags & ISCSI_FLG_FINAL); > > - if (req_hdr->flags & ISCSI_FLG_FINAL) { > - req->is_unsolicited_data = 0; > - if (req->pending) > - goto out_put; > - } else > + if (req_hdr->flags & ISCSI_FLG_FINAL) > + req->unsolicited_data_expected = 0; > + else > goto out_put; > } else { > - TRACE_DBG("FINAL %x, outstanding_r2t %d, r2t_length %d", > - req_hdr->flags & ISCSI_FLG_FINAL, > - req->outstanding_r2t, req->r2t_length); > - > - if (req_hdr->flags & ISCSI_FLG_FINAL) { > - if (unlikely(req->is_unsolicited_data)) { > - PRINT_ERROR("Unexpected unsolicited data " > - "(r2t_length %u, outstanding_r2t %d)", > - req->r2t_length, > - req->is_unsolicited_data); > - mark_conn_closed(req->conn); > - goto out_put; > - } > + TRACE_DBG("FINAL %x, outstanding_r2t %d, r2t_len_to_receive %d, " > + "r2t_len_to_send %d", req_hdr->flags & ISCSI_FLG_FINAL, > + req->outstanding_r2t, req->r2t_len_to_receive, > + req->r2t_len_to_send); > + > + if (req_hdr->flags & ISCSI_FLG_FINAL) > req->outstanding_r2t--; > - } else > + else > goto out_put; > } > > - if (req->r2t_length != 0) { > - if (!req->is_unsolicited_data) > - send_r2t(req); > - } else > + if (req->r2t_len_to_send != 0) > + send_r2t(req); > + else if (req->r2t_len_to_receive == 0) > iscsi_restart_waiting_cmnd(req); > > out_put: > @@ -1757,13 +1786,15 @@ static void __cmnd_abort(struct iscsi_cm > */ > > TRACE_MGMT_DBG("Aborting cmd %p, scst_cmd %p (scst state %x, " > - "ref_cnt %d, itt %x, sn %u, op %x, r2t_len %x, CDB op %x, " > - "size to write %u, is_unsolicited_data %d, " > - "outstanding_r2t %d, data_waiting %d, sess->exp_cmd_sn %u, " > - "conn %p, rd_task %p)", cmnd, cmnd->scst_cmd, cmnd->scst_state, > + "ref_cnt %d, itt %x, sn %u, op %x, r2t_len_to_receive %d, " > + "r2t_len_to_send %d, CDB op %x, size to write %u, " > + "unsolicited_data_expected %d, outstanding_r2t %d, " > + "data_waiting %d, sess->exp_cmd_sn %u, conn %p, rd_task %p)", > + cmnd, cmnd->scst_cmd, cmnd->scst_state, > atomic_read(&cmnd->ref_cnt), cmnd_itt(cmnd), cmnd->pdu.bhs.sn, > - cmnd_opcode(cmnd), cmnd->r2t_length, cmnd_scsicode(cmnd), > - cmnd_write_size(cmnd), cmnd->is_unsolicited_data, > + cmnd_opcode(cmnd), cmnd->r2t_len_to_receive, > + cmnd->r2t_len_to_send, cmnd_scsicode(cmnd), > + cmnd_write_size(cmnd), cmnd->unsolicited_data_expected, > cmnd->outstanding_r2t, cmnd->data_waiting, > cmnd->conn->session->exp_cmd_sn, cmnd->conn, > cmnd->conn->rd_task); > @@ -2190,12 +2221,9 @@ static void iscsi_cmnd_exec(struct iscsi > > switch (cmnd_opcode(cmnd)) { > case ISCSI_OP_SCSI_CMD: > - if (cmnd->r2t_length != 0) { > - if (!cmnd->is_unsolicited_data) { > - send_r2t(cmnd); > - break; > - } > - } else > + if (cmnd->r2t_len_to_send != 0) > + send_r2t(cmnd); > + else > iscsi_restart_cmnd(cmnd); > break; > case ISCSI_OP_NOOP_OUT: > @@ -2424,7 +2452,6 @@ static void iscsi_session_push_cmnd(stru > break; > > list_del(&cmnd->pending_list_entry); > - cmnd->pending = 0; > > TRACE_DBG("Processing pending cmd %p (cmd_sn %u)", > cmnd, cmd_sn); > @@ -2499,7 +2526,6 @@ static void iscsi_session_push_cmnd(stru > break; > } > list_add_tail(&cmnd->pending_list_entry, entry); > - cmnd->pending = 1; > } > > spin_unlock(&session->sn_lock); > Index: iscsi-scst/kernel/iscsi.h > =================================================================== > --- iscsi-scst/kernel/iscsi.h (revision 1375) > +++ iscsi-scst/kernel/iscsi.h (working copy) > @@ -306,10 +306,10 @@ struct iscsi_cmnd { > unsigned int hashed:1; > unsigned int should_close_conn:1; > unsigned int should_close_all_conn:1; > - unsigned int pending:1; > unsigned int own_sg:1; > unsigned int on_write_list:1; > unsigned int write_processing_started:1; > + unsigned int unsolicited_data_expected:1; > unsigned int data_waiting:1; > unsigned int force_cleanup_done:1; > unsigned int dec_active_cmnds:1; > @@ -396,11 +396,10 @@ struct iscsi_cmnd { > int sg_cnt; > unsigned int bufflen; > u32 r2t_sn; > - u32 r2t_length; > - u32 is_unsolicited_data; > + unsigned int r2t_len_to_receive; > + unsigned int r2t_len_to_send; > + unsigned int outstanding_r2t; > u32 target_task_tag; > - u32 outstanding_r2t; > - > u32 hdigest; > u32 ddigest; > > Index: iscsi-scst/kernel/nthread.c > =================================================================== > --- iscsi-scst/kernel/nthread.c (revision 1375) > +++ iscsi-scst/kernel/nthread.c (working copy) > @@ -185,7 +185,6 @@ static void free_pending_commands(struct > cmnd); > > list_del(&cmnd->pending_list_entry); > - cmnd->pending = 0; > > session->exp_cmd_sn++; > > @@ -224,7 +223,6 @@ static void free_orphaned_pending_comman > cmnd); > > list_del(&cmnd->pending_list_entry); > - cmnd->pending = 0; > > if (session->exp_cmd_sn == cmnd->pdu.bhs.sn) > session->exp_cmd_sn++; > @@ -263,12 +261,12 @@ static void trace_conn_close(struct iscs > TRACE_CONN_CLOSE_DBG( > "cmd %p, scst_state %x, scst_cmd state %d, " > "data_waiting %d, ref_cnt %d, sn %u, " > - "parent_req %p, pending %d", > + "parent_req %p", > cmnd, cmnd->scst_state, > (cmnd->parent_req && cmnd->scst_cmd) ? > cmnd->scst_cmd->state : -1, > cmnd->data_waiting, atomic_read(&cmnd->ref_cnt), > - cmnd->pdu.bhs.sn, cmnd->parent_req, cmnd->pending); > + cmnd->pdu.bhs.sn, cmnd->parent_req); > #if defined(CONFIG_TCP_ZERO_COPY_TRANSFER_COMPLETION_NOTIFICATION) > TRACE_CONN_CLOSE_DBG("net_ref_cnt %d, sg %p", > atomic_read(&cmnd->net_ref_cnt), |