From: <vl...@us...> - 2008-05-07 18:44:31
|
Revision: 364 http://scst.svn.sourceforge.net/scst/?rev=364&view=rev Author: vlnb Date: 2008-05-07 11:44:15 -0700 (Wed, 07 May 2008) Log Message: ----------- - Rejecting command reimplemented in a more simple, straightforward and readable way. - Minor external interface change: now target drivers should set for aborted commands SCST_CMD_DELIVERY_ABORTED status via scst_set_delivery_status(). In-tree drivers updated. - Fixed broken compilation if put_page_callback patch not applied to the kernel. Reported by Erez Zilber <er...@Vo...> - Fixed several minor problems reported by David Berton <dav...@ya...> - Fixed __exit misuse, when such functions called from __init functions. - Docs updated. - Other minor changes and cleanups. Modified Paths: -------------- trunk/iscsi-scst/kernel/digest.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/iscsi_hdr.h trunk/iscsi-scst/kernel/nthread.c trunk/qla2x00t/qla2x00-target/qla2x00t.c trunk/qla_isp/README.scst trunk/qla_isp/linux/isp_scst.c trunk/scst/README trunk/scst/include/scst.h trunk/scst/include/scst_const.h trunk/scst/src/dev_handlers/scst_vdisk.c trunk/scst/src/scst_lib.c trunk/scst/src/scst_proc.c trunk/scst/src/scst_targ.c trunk/srpt/src/ib_srpt.c Modified: trunk/iscsi-scst/kernel/digest.c =================================================================== --- trunk/iscsi-scst/kernel/digest.c 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/iscsi-scst/kernel/digest.c 2008-05-07 18:44:15 UTC (rev 364) @@ -162,6 +162,9 @@ u32 offset, crc; int res = 0; + if (unlikely(cmnd->rejected)) + goto out; + switch (cmnd_opcode(cmnd)) { case ISCSI_OP_SCSI_DATA_OUT: req = cmnd->cmd_req; @@ -169,11 +172,6 @@ offset = be32_to_cpu(req_hdr->buffer_offset); break; - case ISCSI_OP_SCSI_REJECT: - case ISCSI_OP_PDU_REJECT: - case ISCSI_OP_DATA_REJECT: - goto out; - default: req = cmnd; offset = 0; Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-05-07 18:44:15 UTC (rev 364) @@ -61,7 +61,7 @@ static void cmnd_remove_hash(struct iscsi_cmnd *cmnd); static void iscsi_send_task_mgmt_resp(struct iscsi_cmnd *req, int status); -static void cmnd_prepare_skip_pdu(struct iscsi_cmnd *cmnd); +static void cmnd_prepare_get_rejected_cmd_data(struct iscsi_cmnd *cmnd); static void iscsi_check_send_delayed_tm_resp(struct iscsi_session *sess); static void iscsi_session_push_cmnd(struct iscsi_cmnd *cmnd); @@ -149,7 +149,6 @@ #ifdef NET_PAGE_CALLBACKS_DEFINED atomic_set(&cmnd->net_ref_cnt, 0); #endif - cmnd->target = conn->target; spin_lock_init(&cmnd->rsp_cmd_lock); INIT_LIST_HEAD(&cmnd->rsp_cmd_list); INIT_LIST_HEAD(&cmnd->rx_ddigest_cmd_list); @@ -168,7 +167,7 @@ { TRACE_DBG("%p", cmnd); - if (unlikely(cmnd->tmfabort)) { + if (unlikely(cmnd->tm_aborted)) { TRACE_MGMT_DBG("Free aborted cmd %p (scst cmd %p, state %d, " "parent_req %p)", cmnd, cmnd->scst_cmd, cmnd->scst_state, cmnd->parent_req); @@ -203,7 +202,7 @@ { TRACE_DBG("%p", cmnd); - if (unlikely(cmnd->tmfabort)) { + if (unlikely(cmnd->tm_aborted)) { TRACE_MGMT_DBG("Done aborted cmd %p (scst cmd %p, state %d, " "parent_req %p)", cmnd, cmnd->scst_cmd, cmnd->scst_state, cmnd->parent_req); @@ -238,6 +237,10 @@ if (cmnd->scst_cmd) { switch(cmnd->scst_state) { + case ISCSI_CMD_STATE_PROCESSED: + TRACE_DBG("cmd %p PROCESSED", cmnd); + scst_tgt_cmd_done(cmnd->scst_cmd); + break; case ISCSI_CMD_STATE_AFTER_PREPROC: { struct scst_cmd *scst_cmd = cmnd->scst_cmd; @@ -249,10 +252,6 @@ SCST_CONTEXT_THREAD); break; } - case ISCSI_CMD_STATE_PROCESSED: - TRACE_DBG("cmd %p PROCESSED", cmnd); - scst_tgt_cmd_done(cmnd->scst_cmd); - break; default: PRINT_CRIT_ERROR("Unexpected cmnd scst state %d", cmnd->scst_state); @@ -398,7 +397,7 @@ req->release_called = 1; #endif - if (unlikely(req->tmfabort)) { + if (unlikely(req->tm_aborted)) { TRACE_MGMT_DBG("Release aborted req cmd %p (scst cmd %p, " "state %d)", req, req->scst_cmd, req->scst_state); } @@ -717,6 +716,10 @@ TRACE_MGMT_DBG("Reject: req %p, reason %x", req, reason); + sBUG_ON(req->rejected); + req->rejected = 1; + req->reject_reason = ISCSI_REJECT_CMD; + rsp = iscsi_cmnd_create_rsp_cmnd(req); rsp_hdr = (struct iscsi_reject_hdr *)&rsp->pdu.bhs; @@ -735,9 +738,11 @@ clear_page(addr); memcpy(addr, &req->pdu.bhs, sizeof(struct iscsi_hdr)); rsp->bufflen = rsp->pdu.datasize = sizeof(struct iscsi_hdr); - cmnd_prepare_skip_pdu(req); - req->pdu.bhs.opcode = ISCSI_OP_PDU_REJECT; + iscsi_cmnd_init_write(rsp, ISCSI_INIT_WRITE_REMOVE_HASH | + ISCSI_INIT_WRITE_WAKE); + + cmnd_prepare_get_rejected_cmd_data(req); } static inline int iscsi_get_allowed_cmds(struct iscsi_session *sess) @@ -913,7 +918,7 @@ spin_unlock(&session->cmnd_hash_lock); } -static void cmnd_prepare_skip_pdu(struct iscsi_cmnd *cmnd) +static void cmnd_prepare_get_rejected_cmd_data(struct iscsi_cmnd *cmnd) { struct iscsi_conn *conn = cmnd->conn; struct scatterlist *sg = cmnd->sg; @@ -954,9 +959,11 @@ conn->read_iov[i].iov_len = size; conn->read_msg.msg_iov = conn->read_iov; conn->read_msg.msg_iovlen = ++i; + + return; } -static void cmnd_prepare_skip_pdu_set_resid(struct iscsi_cmnd *req) +static void cmnd_reject_scsi_cmd(struct iscsi_cmnd *req) { struct iscsi_cmnd *rsp; struct iscsi_scsi_rsp_hdr *rsp_hdr; @@ -964,9 +971,15 @@ TRACE_DBG("%p", req); + sBUG_ON(req->rejected); + req->rejected = 1; + req->reject_reason = ISCSI_REJECT_SCSI_CMD; + rsp = get_rsp_cmnd(req); - if (rsp == NULL) - goto skip; + if (rsp == NULL) { + /* That can be true for aborted commands */ + goto out_reject; + } rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; @@ -988,11 +1001,12 @@ } } -skip: - req->pdu.bhs.opcode = - (req->pdu.bhs.opcode & ~ISCSI_OPCODE_MASK) | ISCSI_OP_SCSI_REJECT; + iscsi_cmnd_init_write(rsp, ISCSI_INIT_WRITE_REMOVE_HASH | + ISCSI_INIT_WRITE_WAKE); - cmnd_prepare_skip_pdu(req); +out_reject: + cmnd_prepare_get_rejected_cmd_data(req); + return; } static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn, @@ -1065,7 +1079,7 @@ u32 offset, burst; LIST_HEAD(send); - if (unlikely(req->tmfabort)) { + 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); @@ -1289,7 +1303,7 @@ req_hdr->scb, sizeof(req_hdr->scb), SCST_NON_ATOMIC); if (scst_cmd == NULL) { create_status_rsp(req, SAM_STAT_BUSY, NULL, 0); - cmnd_prepare_skip_pdu_set_resid(req); + cmnd_reject_scsi_cmd(req); goto out; } @@ -1344,13 +1358,13 @@ if (unlikely(req->scst_state != ISCSI_CMD_STATE_AFTER_PREPROC)) { TRACE_DBG("req %p is in %x state", req, req->scst_state); if (req->scst_state == ISCSI_CMD_STATE_PROCESSED) { - cmnd_prepare_skip_pdu_set_resid(req); + cmnd_reject_scsi_cmd(req); goto out; } - if (unlikely(req->tmfabort)) { + if (unlikely(req->tm_aborted)) { TRACE_MGMT_DBG("req %p (scst_cmd %p) aborted", req, req->scst_cmd); - cmnd_prepare_skip_pdu(req); + cmnd_prepare_get_rejected_cmd_data(req); goto out; } sBUG(); @@ -1363,7 +1377,7 @@ PRINT_ERROR("Unexpected unsolicited data (ITT %x " "CDB %x", cmnd_itt(req), req_hdr->scb[0]); create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc); - cmnd_prepare_skip_pdu_set_resid(req); + cmnd_reject_scsi_cmd(req); goto out; } } @@ -1411,7 +1425,7 @@ PRINT_ERROR("pdu.datasize(%d) >0, but dir(%x) isn't WRITE", req->pdu.datasize, dir); create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc); - cmnd_prepare_skip_pdu_set_resid(req); + cmnd_reject_scsi_cmd(req); } else res = cmnd_prepare_recv_pdu(conn, req, 0, req->pdu.datasize); } @@ -1424,7 +1438,7 @@ static int data_out_start(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) { struct iscsi_data_out_hdr *req_hdr = (struct iscsi_data_out_hdr *)&cmnd->pdu.bhs; - struct iscsi_cmnd *req = NULL; + struct iscsi_cmnd *orig_req = NULL; u32 offset = be32_to_cpu(req_hdr->buffer_offset); int res = 0; @@ -1438,29 +1452,29 @@ update_stat_sn(cmnd); - cmnd->cmd_req = req = cmnd_find_hash(conn->session, req_hdr->itt, + cmnd->cmd_req = orig_req = cmnd_find_hash(conn->session, req_hdr->itt, req_hdr->ttt); - if (unlikely(req == NULL)) { + if (unlikely(orig_req == NULL)) { /* It might happen if req was aborted and then freed */ TRACE(TRACE_MGMT_MINOR, "Unable to find scsi task %x %x", cmnd_itt(cmnd), cmnd_ttt(cmnd)); - goto skip_pdu; + goto out_reject; } - if (req->is_unsolicited_data) { - if (unlikely(req->r2t_length < cmnd->pdu.datasize)) { + 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, req->r2t_length); + cmnd->pdu.datasize, orig_req->r2t_length); mark_conn_closed(conn); res = -EINVAL; goto out; } - req->r2t_length -= cmnd->pdu.datasize; + orig_req->r2t_length -= cmnd->pdu.datasize; } /* Check unsolicited burst data */ if (unlikely((req_hdr->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) && - (req->pdu.bhs.flags & ISCSI_FLG_FINAL))) { + (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); @@ -1468,18 +1482,20 @@ goto out; } - TRACE_WRITE("%u %p %p %u %u", req_hdr->ttt, cmnd, req, + TRACE_WRITE("%u %p %p %u %u", req_hdr->ttt, cmnd, orig_req, offset, cmnd->pdu.datasize); - res = cmnd_prepare_recv_pdu(conn, req, offset, cmnd->pdu.datasize); + res = cmnd_prepare_recv_pdu(conn, orig_req, offset, cmnd->pdu.datasize); out: TRACE_EXIT_RES(res); return res; -skip_pdu: - cmnd->pdu.bhs.opcode = ISCSI_OP_DATA_REJECT; - cmnd_prepare_skip_pdu(cmnd); +out_reject: + sBUG_ON(cmnd->rejected); + cmnd->rejected = 1; + cmnd->reject_reason = ISCSI_REJECT_DATA; + cmnd_prepare_get_rejected_cmd_data(cmnd); goto out; } @@ -1543,6 +1559,23 @@ static void __cmnd_abort(struct iscsi_cmnd *cmnd) { + /* + * Here, if cmnd is data_waiting, we should iscsi_fail_waiting_cmnd() + * it. But, since this function can be called from any thread, not only + * from the read one, we at the moment can't do that, because of + * absence of appropriate locking protection. But this isn't a stuff + * for 0.9.6. So, currently a misbehaving initiator, not sending + * data in R2T state for a sharing between targets device, for which + * for some reason an aborting TM command, e.g. TARGET RESET, from + * another initiator is issued, can block response for this TM command + * virtually forever and by this make the issuing initiator eventually + * put the device offline. + * + * ToDo in the next version, possibly a simple connection mutex, taken + * by the read thread before starting any processing and by this + * function, should be sufficient. + */ + 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, " @@ -1559,7 +1592,7 @@ TRACE_MGMT_DBG("net_ref_cnt %d", atomic_read(&cmnd->net_ref_cnt)); #endif - cmnd->tmfabort = 1; + cmnd->tm_aborted = 1; return; } @@ -1949,16 +1982,21 @@ static void iscsi_cmnd_exec(struct iscsi_cmnd *cmnd) { + TRACE_ENTRY(); + TRACE_DBG("%p,%x,%u", cmnd, cmnd_opcode(cmnd), cmnd->pdu.bhs.sn); - if (unlikely(cmnd->tmfabort)) { + iscsi_extracheck_is_rd_thread(cmnd->conn); + + if (unlikely(cmnd->tm_aborted)) { TRACE_MGMT_DBG("cmnd %p (scst_cmd %p) aborted", cmnd, cmnd->scst_cmd); req_cmnd_release_force(cmnd, ISCSI_FORCE_RELEASE_WRITE); goto out; } - iscsi_extracheck_is_rd_thread(cmnd->conn); + if (unlikely(cmnd->rejected)) + goto out_rejected; switch (cmnd_opcode(cmnd)) { case ISCSI_OP_SCSI_CMD: @@ -1979,24 +2017,27 @@ case ISCSI_OP_LOGOUT_CMD: logout_exec(cmnd); break; - case ISCSI_OP_SCSI_REJECT: - { - struct iscsi_cmnd *rsp = get_rsp_cmnd(cmnd); - TRACE_MGMT_DBG("REJECT cmnd %p (scst_cmd %p), rsp %p", cmnd, - cmnd->scst_cmd, rsp); - if (rsp != NULL) - iscsi_cmnd_init_write(rsp, ISCSI_INIT_WRITE_REMOVE_HASH | - ISCSI_INIT_WRITE_WAKE); + default: + PRINT_ERROR("unexpected cmnd op %x", cmnd_opcode(cmnd)); req_cmnd_release(cmnd); break; } +out: + TRACE_EXIT(); + return; + +out_rejected: + TRACE_MGMT_DBG("Rejected cmd %p (reason %d)", cmnd, + cmnd->reject_reason); + switch (cmnd->reject_reason) { default: - PRINT_ERROR("unexpected cmnd op %x", cmnd_opcode(cmnd)); + PRINT_ERROR("Unexpected reject reason %d", cmnd->reject_reason); + /* go through */ + case ISCSI_REJECT_SCSI_CMD: req_cmnd_release(cmnd); break; } -out: - return; + goto out; } static void __cmnd_send_pdu(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd, @@ -2238,7 +2279,7 @@ goto out; } - if (unlikely(cmnd->tmfabort)) { + if (unlikely(cmnd->tm_aborted)) { struct iscsi_cmnd *tm_clone; TRACE_MGMT_DBG("Pending aborted cmnd %p, creating TM " @@ -2247,7 +2288,7 @@ tm_clone = cmnd_alloc(cmnd->conn, NULL); if (tm_clone != NULL) { - tm_clone->tmfabort = 1; + tm_clone->tm_aborted = 1; tm_clone->pdu = cmnd->pdu; TRACE_MGMT_DBG("TM clone %p created", tm_clone); @@ -2353,9 +2394,12 @@ TRACE_DBG("%p:%x", cmnd, cmnd_opcode(cmnd)); + if (unlikely(cmnd->rejected)) + goto out_rejected; + +cont: switch (cmnd_opcode(cmnd)) { case ISCSI_OP_SCSI_CMD: - case ISCSI_OP_SCSI_REJECT: case ISCSI_OP_NOOP_OUT: case ISCSI_OP_SCSI_TASK_MGT_MSG: case ISCSI_OP_LOGOUT_CMD: @@ -2364,26 +2408,29 @@ case ISCSI_OP_SCSI_DATA_OUT: data_out_end(cmnd); break; - case ISCSI_OP_PDU_REJECT: - { - struct iscsi_cmnd *rsp = get_rsp_cmnd(cmnd); - if (rsp != NULL) - iscsi_cmnd_init_write(rsp, ISCSI_INIT_WRITE_REMOVE_HASH | - ISCSI_INIT_WRITE_WAKE); - req_cmnd_release(cmnd); - break; - } - case ISCSI_OP_DATA_REJECT: - req_cmnd_release(cmnd); - break; default: PRINT_ERROR("unexpected cmnd op %x", cmnd_opcode(cmnd)); req_cmnd_release(cmnd); break; } +out: TRACE_EXIT(); return; + +out_rejected: + switch (cmnd->reject_reason) { + default: + PRINT_ERROR("Unexpected reject reason %d", cmnd->reject_reason); + /* go through */ + case ISCSI_REJECT_CMD: + case ISCSI_REJECT_DATA: + req_cmnd_release(cmnd); + break; + case ISCSI_REJECT_SCSI_CMD: + goto cont; + } + goto out; } #ifndef NET_PAGE_CALLBACKS_DEFINED @@ -2512,21 +2559,28 @@ scst_cmd_set_tgt_priv(scst_cmd, NULL); - req->tmfabort |= scst_cmd_aborted(scst_cmd) ? 1 : 0; - if (unlikely(req->tmfabort)) { + req->tm_aborted |= scst_cmd_aborted(scst_cmd) ? 1 : 0; + if (unlikely(req->tm_aborted)) { TRACE_MGMT_DBG("req %p (scst_cmd %p) aborted", req, req->scst_cmd); + + scst_set_delivery_status(req->scst_cmd, + SCST_CMD_DELIVERY_ABORTED); + if (old_state == ISCSI_CMD_STATE_RESTARTED) { req->scst_state = ISCSI_CMD_STATE_PROCESSED; req_cmnd_release_force(req, ISCSI_FORCE_RELEASE_WRITE); } else iscsi_set_state_wake_up(req, ISCSI_CMD_STATE_PROCESSED); + goto out; } if (unlikely(old_state != ISCSI_CMD_STATE_RESTARTED)) { TRACE_DBG("req %p on %d state", req, old_state); + create_status_rsp(req, status, sense, sense_len); + switch(old_state) { case ISCSI_CMD_STATE_RX_CMD: case ISCSI_CMD_STATE_AFTER_PREPROC: @@ -2534,6 +2588,7 @@ default: sBUG(); } + iscsi_set_state_wake_up(req, ISCSI_CMD_STATE_PROCESSED); goto out; } Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-05-07 18:44:15 UTC (rev 364) @@ -230,6 +230,11 @@ #define ISCSI_CMD_STATE_RESTARTED 3 /* scst_restart_cmd() called and SCST processing it */ #define ISCSI_CMD_STATE_PROCESSED 4 /* SCST done processing */ +/* Command's reject reasons */ +#define ISCSI_REJECT_SCSI_CMD 1 +#define ISCSI_REJECT_CMD 2 +#define ISCSI_REJECT_DATA 3 + /* * Most of the fields don't need any protection, since accessed from only a * single thread, except where noted. @@ -251,12 +256,14 @@ unsigned int force_cleanup_done:1; unsigned int dec_active_cmnds:1; unsigned int ddigest_checked:1; + unsigned int rejected:1; + unsigned int reject_reason:2; #ifdef EXTRACHECKS unsigned int on_rx_digest_list:1; unsigned int release_called:1; #endif - unsigned long tmfabort; /* it's async. with the above flags */ + volatile unsigned int tm_aborted; /* it's async. with the above flags */ struct list_head hash_list_entry; @@ -289,8 +296,6 @@ struct iscsi_cmnd *parent_req; struct iscsi_cmnd *cmd_req; - struct iscsi_target *target; - wait_queue_head_t scst_waitQ; int scst_state; struct scst_cmd *scst_cmd; @@ -316,10 +321,6 @@ struct list_head cmd_list_entry; }; -#define ISCSI_OP_SCSI_REJECT ISCSI_OP_VENDOR1_CMD -#define ISCSI_OP_PDU_REJECT ISCSI_OP_VENDOR2_CMD -#define ISCSI_OP_DATA_REJECT ISCSI_OP_VENDOR3_CMD - /* Flags for req_cmnd_release_force() */ #define ISCSI_FORCE_RELEASE_WRITE 1 Modified: trunk/iscsi-scst/kernel/iscsi_hdr.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi_hdr.h 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/iscsi-scst/kernel/iscsi_hdr.h 2008-05-07 18:44:15 UTC (rev 364) @@ -62,11 +62,6 @@ #define ISCSI_OP_LOGOUT_CMD 0x06 #define ISCSI_OP_SNACK_CMD 0x10 -#define ISCSI_OP_VENDOR1_CMD 0x1c -#define ISCSI_OP_VENDOR2_CMD 0x1d -#define ISCSI_OP_VENDOR3_CMD 0x1e -#define ISCSI_OP_VENDOR4_CMD 0x1f - /* Server to Client Message Opcode values */ #define ISCSI_OP_NOOP_IN 0x20 #define ISCSI_OP_SCSI_RSP 0x21 Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/iscsi-scst/kernel/nthread.c 2008-05-07 18:44:15 UTC (rev 364) @@ -919,6 +919,8 @@ } #else static inline void check_net_priv(struct iscsi_cmnd *cmd, struct page *page) {} +static inline void __iscsi_get_page_callback(struct iscsi_cmnd *cmd) {} +static inline void __iscsi_put_page_callback(struct iscsi_cmnd *cmd) {} #endif /* This is partially taken from the Ardis code. */ Modified: trunk/qla2x00t/qla2x00-target/qla2x00t.c =================================================================== --- trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/qla2x00t/qla2x00-target/qla2x00t.c 2008-05-07 18:44:15 UTC (rev 364) @@ -697,6 +697,8 @@ "for aborted scst_cmd=%p (tag=%Ld)", ha->instance, scst_cmd, scst_cmd_get_tag(scst_cmd)); + scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_ABORTED); + prm.cmd->state = Q2T_STATE_ABORTED; q2t_send_term_exchange(ha, prm.cmd, &prm.cmd->atio, 0); Modified: trunk/qla_isp/README.scst =================================================================== --- trunk/qla_isp/README.scst 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/qla_isp/README.scst 2008-05-07 18:44:15 UTC (rev 364) @@ -37,7 +37,6 @@ Each time you want to run qla_isp, unload all other qla modules $ rmmod qla2x00tgt -$ rmmod qla2x00tgt $ rmmod qla2400 $ rmmod qla2300 $ rmmod qla2200 Modified: trunk/qla_isp/linux/isp_scst.c =================================================================== --- trunk/qla_isp/linux/isp_scst.c 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/qla_isp/linux/isp_scst.c 2008-05-07 18:44:15 UTC (rev 364) @@ -1126,6 +1126,7 @@ tmd_xact_t *xact = &tmd->cd_xact; if (unlikely(scst_cmd_aborted(scst_cmd))) { + scst_set_delivery_status(scst_cmd, SCST_CMD_DELIVERY_ABORTED); scst_tgt_cmd_done(scst_cmd); return (0); } Modified: trunk/scst/README =================================================================== --- trunk/scst/README 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/scst/README 2008-05-07 18:44:15 UTC (rev 364) @@ -349,8 +349,8 @@ or not. In "Default_target_name" target name means name of the target. In /proc/scsi_tgt each group represented as "groups/GROUP_NAME/" -subdirectory. In it there are files "devices" and "users". File -"devices" lists all devices and their LUNs in the group, file "users" +subdirectory. In it there are files "devices" and "names". File +"devices" lists all devices and their LUNs in the group, file "names" lists all names that should be bound to this group. To configure access and devices visibility management SCST provides the @@ -790,6 +790,13 @@ (usually, 32), so start from dividing the current value on 2, i.e. set 16, if /sys/block/sdX/device/queue_depth contains 32. +Note, that logged messages about QUEUE_FULL status are quite different +by nature. This is a normal work, just SCSI flow control in action. +Simply don't enable "mgmt_minor" logging level, or, alternatively, if +you are confident in the worst case performance of your back-end +storage, you can increase SCST_MAX_TGT_DEV_COMMANDS in scst_priv.h to +64. Usually initiators don't try to push more commands on the target. + Credits ------- Modified: trunk/scst/include/scst.h =================================================================== --- trunk/scst/include/scst.h 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/scst/include/scst.h 2008-05-07 18:44:15 UTC (rev 364) @@ -42,6 +42,8 @@ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) typedef _Bool bool; +#define true 1 +#define false 0 #endif /* Version numbers, the same as for the kernel */ @@ -373,7 +375,7 @@ #define SCST_TGT_DEV_AFTER_EXEC_ATOMIC 10 #ifdef DEBUG_TM -#define SCST_TGT_DEV_UNDER_TM_DBG 20 +#define SCST_TGT_DEV_UNDER_TM_DBG 20 #endif /************************************************************* @@ -2080,12 +2082,6 @@ return cmd->data_direction; } -/* Returns cmd's relative data offset */ -static inline unsigned int scst_cmd_get_offset(struct scst_cmd *cmd) -{ - return 0; -} - /* Returns cmd's status byte from host device */ static inline uint8_t scst_cmd_get_status(struct scst_cmd *cmd) { @@ -2208,7 +2204,6 @@ cmd->tgt_sn = tgt_sn; } - /* * Returns 1 if the cmd was aborted, so its status is invalid and no * reply shall be sent to the remote initiator. A target driver should Modified: trunk/scst/include/scst_const.h =================================================================== --- trunk/scst/include/scst_const.h 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/scst/include/scst_const.h 2008-05-07 18:44:15 UTC (rev 364) @@ -35,8 +35,9 @@ ** Allowed delivery statuses for cmd's delivery_status *************************************************************/ -#define SCST_CMD_DELIVERY_SUCCESS 0 -#define SCST_CMD_DELIVERY_FAILED -1 +#define SCST_CMD_DELIVERY_SUCCESS 0 +#define SCST_CMD_DELIVERY_FAILED -1 +#define SCST_CMD_DELIVERY_ABORTED -2 /************************************************************* ** Values for task management functions Modified: trunk/scst/src/dev_handlers/scst_vdisk.c =================================================================== --- trunk/scst/src/dev_handlers/scst_vdisk.c 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/scst/src/dev_handlers/scst_vdisk.c 2008-05-07 18:44:15 UTC (rev 364) @@ -1103,7 +1103,6 @@ goto out_put; } - memset(buf, 0, sizeof(buf)); buf[0] = cmd->dev->handler->type; /* type dev */ if ((buf[0] == TYPE_ROM) || virt_dev->removable) buf[1] = 0x80; /* removable */ @@ -3352,7 +3351,7 @@ goto out; } -static void __exit exit_scst_vdisk(struct scst_dev_type *devtype, +static void exit_scst_vdisk(struct scst_dev_type *devtype, struct list_head *vdisk_dev_list) { TRACE_ENTRY(); Modified: trunk/scst/src/scst_lib.c =================================================================== --- trunk/scst/src/scst_lib.c 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/scst/src/scst_lib.c 2008-05-07 18:44:15 UTC (rev 364) @@ -3096,30 +3096,23 @@ /* It's completed and it's OK to return its result */ goto out; } - TRACE_MGMT_DBG("Flag ABORTED OTHER set for cmd %p (tag %llu)", - cmd, cmd->tag); + if (cmd->dev->tas) { + TRACE_MGMT_DBG("Flag ABORTED OTHER set for cmd %p " + "(tag %llu), returning TASK ABORTED ", cmd, + cmd->tag); scst_set_cmd_error_status(cmd, SAM_STAT_TASK_ABORTED); } else { + TRACE_MGMT_DBG("Flag ABORTED OTHER set for cmd %p " + "(tag %llu), aborting without delivery or " + "notification", cmd, cmd->tag); /* - * Abort without delivery or notification. * There is no need to check/requeue possible UA, * because, if it exists, it will be delivered - * by the "completed" branch. + * by the "completed" branch above. */ - clear_bit(SCST_CMD_ABORTED_OTHER, - &cmd->cmd_flags); + clear_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags); } - } else { - if ((cmd->tgt_dev != NULL) && - scst_is_ua_sense(cmd->sense)) { - /* This UA delivery is going to fail, so requeue it */ - TRACE_MGMT_DBG("Requeuing UA for aborted cmd %p", cmd); - scst_check_set_UA(cmd->tgt_dev, cmd->sense, - SCST_SENSE_BUFFERSIZE, 1); - mempool_free(cmd->sense, scst_sense_mempool); - cmd->sense = NULL; - } } out: @@ -3402,6 +3395,7 @@ c, c->tag, tm_dbg_delayed_cmds_count); if (!test_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags)) { + /* Test how completed commands handled */ if (((scst_random() % 10) == 5)) { scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_hardw_error)); Modified: trunk/scst/src/scst_proc.c =================================================================== --- trunk/scst/src/scst_proc.c 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/scst/src/scst_proc.c 2008-05-07 18:44:15 UTC (rev 364) @@ -521,7 +521,7 @@ return res; } -static void __exit scst_proc_cleanup_module_log(void) +static void scst_proc_cleanup_module_log(void) { TRACE_ENTRY(); @@ -702,7 +702,7 @@ goto out; } -static void __exit scst_proc_cleanup_groups(void) +static void scst_proc_cleanup_groups(void) { struct scst_acg *acg_tmp, *acg; Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/scst/src/scst_targ.c 2008-05-07 18:44:15 UTC (rev 364) @@ -3502,20 +3502,32 @@ int other_ini, int call_dev_task_mgmt_fn) { unsigned long flags; + static spinlock_t other_ini_lock = SPIN_LOCK_UNLOCKED; TRACE_ENTRY(); TRACE(((mcmd != NULL) && (mcmd->fn == SCST_ABORT_TASK)) ? TRACE_MGMT_MINOR : TRACE_MGMT, "Aborting cmd %p (tag %llu, op %x)", cmd, cmd->tag, cmd->cdb[0]); + /* To protect from concurrent aborts */ + spin_lock_irqsave(&other_ini_lock, flags); + if (other_ini) { - set_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags); - smp_mb__after_set_bit(); + /* Might be necessary if command aborted several times */ + if (!test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) { + set_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags); + smp_mb__after_set_bit(); + } } else { /* Might be necessary if command aborted several times */ clear_bit(SCST_CMD_ABORTED_OTHER, &cmd->cmd_flags); } + set_bit(SCST_CMD_ABORTED, &cmd->cmd_flags); + + spin_unlock_irqrestore(&other_ini_lock, flags); + + /* * To sync with cmd->finished/done set in * scst_finish_cmd()/scst_pre_xmit_response() Modified: trunk/srpt/src/ib_srpt.c =================================================================== --- trunk/srpt/src/ib_srpt.c 2008-05-04 10:31:05 UTC (rev 363) +++ trunk/srpt/src/ib_srpt.c 2008-05-07 18:44:15 UTC (rev 364) @@ -1821,8 +1821,10 @@ else if (ch->state == RDMA_CHANNEL_CONNECTING) ret = SCST_TGT_RES_QUEUE_FULL; - if (unlikely(scst_cmd_aborted(scmnd))) + if (unlikely(scst_cmd_aborted(scmnd))) { + scst_set_delivery_status(scmnd, SCST_CMD_DELIVERY_ABORTED); ret = SCST_TGT_RES_SUCCESS; + } goto out; } @@ -1836,6 +1838,7 @@ printk(KERN_ERR PFX "%s[%d] tag= %lld already get aborted\n", __FUNCTION__, __LINE__, (unsigned long long)tag); + scst_set_delivery_status(ioctx->scmnd, SCST_CMD_DELIVERY_ABORTED); scst_tgt_cmd_done(ioctx->scmnd); goto out; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |