The bunch of pending changes. Sorry, it's quite big.
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Tue, 22 Apr 2008 10:30:53 +0000 (10:30 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Tue, 22 Apr 2008 10:30:53 +0000 (10:30 +0000)
 - "RECEIVE DIAGNOSTIC RESULTS" command handling fixed
 - Obtaining device queue parameters in scst_obtain_device_parameters() changed to handle NOT READY sense
 - Fixed possible dev_cmd_count underflow
 - Minor iSCSI-SCST connection closing cleanups and fixes
 - Semantic of other *_atomic flags changed a bit. Now they are intended only to allow SCST to optimize execution context. The corresponing functions now can *always* be called on atomic context and, if necessary, should manually determine that using scst_cmd_atomic() function and restart using corresponding *_NEED_THREAD_* return value.
 - scst_cmd_get_tgt_resp_flags() and SCST_TSC_FLAG_STATUS flag made obsolete and replaced by scst_cmd_get_is_send_status(). All in-tree drivers updated accordingly
 - Cleanup: preprocessing_done_atomic removed, now preprocessing_done() callback always called on thread context
 - 64-bit cleanups
 - Documented that iscsi-scst-adm is currently broken and explained why
 - In user space Makefile's added possibility to specify external linker flags
 - Minor performance optimizations
 - Other minor cleanups

git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@350 d57e44dd-8a1f-0410-8b47-8ef2f437770f

29 files changed:
iscsi-scst/README
iscsi-scst/ToDo
iscsi-scst/include/iscsi_u.h
iscsi-scst/kernel/config.c
iscsi-scst/kernel/conn.c
iscsi-scst/kernel/iscsi.c
iscsi-scst/kernel/nthread.c
iscsi-scst/kernel/session.c
iscsi-scst/usr/Makefile
mpt/mpt_scst.c
qla2x00t/qla2x00-target/qla2x00t.c
qla_isp/linux/isp_scst.c
scst/README
scst/include/scst.h
scst/src/dev_handlers/scst_changer.c
scst/src/dev_handlers/scst_processor.c
scst/src/dev_handlers/scst_raid.c
scst/src/dev_handlers/scst_tape.c
scst/src/dev_handlers/scst_user.c
scst/src/dev_handlers/scst_vdisk.c
scst/src/scst_cdbprobe.h
scst/src/scst_lib.c
scst/src/scst_main.c
scst/src/scst_mem.c
scst/src/scst_mem.h
scst/src/scst_targ.c
usr/fileio/Makefile
usr/fileio/common.c
usr/fileio/fileio.c

index 7a1cd69..07742bc 100644 (file)
@@ -118,7 +118,6 @@ that issue.
 CAUTION:  Working of target and initiator on the same host isn't
 ========  supported. See SCST README file for details.
 
-
 Compilation options
 -------------------
 
@@ -136,6 +135,19 @@ in/out in the kernel's module Makefile:
 
  - DEBUG_DIGEST_FAILURES - simulates digest failures in random places.
 
+Known issues
+------------
+
+Currently some iscsi-scst-adm functionality is broken. But, from one
+side, at the moment I don't have time to look at it and and, from other
+side, in contrast to IET, in iSCSI-SCST this utility doesn't worth much,
+since all devices management is done using SCST's /proc interface.
+What's remained for iscsi-scst-adm is managing iSCSI targets and their
+parameters, but in any case changing of any negotiable iSCSI parameter
+needs renegotiation, i.e. the corresponding session restart, i.e.
+iSCSI-SCST restart. But, if you decide to fix iscsi-scst-adm, I will
+appreciate your patches.
+
 Creating version of put_page_callback patch for your kernel
 -----------------------------------------------------------
 
index 7b5fa12..8d0af2b 100644 (file)
@@ -21,6 +21,8 @@
    for adding support for ranges in the negotiation keys, so it needs to
    be fixed as well.
 
+ - Fix iscsi-scst-adm.
+
  - Fix SNACK command handling. Currently it violates iSCSI RFC.
 
  - Consider better integration with TCP internals on receive path to
index 81a1f72..1badfba 100644 (file)
@@ -30,7 +30,7 @@
 #define SCSI_ID_LEN    24
 
 #ifndef aligned_u64
-#define aligned_u64 unsigned long long __attribute__((aligned(8)))
+#define aligned_u64 uint64_t __attribute__((aligned(8)))
 #endif
 
 struct target_info {
index 3a0ec09..8fb0a62 100644 (file)
@@ -50,8 +50,8 @@ static int iscsi_log_info_show(struct seq_file *seq, void *v)
        return res;
 }
 
-static int iscsi_proc_log_entry_write(struct file *file, const char __user *buf,
-                                        size_t length, loff_t *off)
+static ssize_t iscsi_proc_log_entry_write(struct file *file,
+       const char __user *buf, size_t length, loff_t *off)
 {
        int res = 0;
 
@@ -475,10 +475,10 @@ void iscsi_dump_iov(struct msghdr *msg)
 {
        if (trace_flag & TRACE_D_IOV) {
                int i;
-               printk("%p, %d\n", msg->msg_iov, msg->msg_iovlen);
+               printk("%p, %zd\n", msg->msg_iov, msg->msg_iovlen);
                for (i = 0; i < min_t(size_t, msg->msg_iovlen, 
                                ISCSI_CONN_IOV_MAX); i++) {
-                       printk("%d: %p,%d\n", i, msg->msg_iov[i].iov_base,
+                       printk("%d: %p,%zd\n", i, msg->msg_iov[i].iov_base,
                                msg->msg_iov[i].iov_len);
                }
        }
@@ -520,7 +520,7 @@ void iscsi_dump_pdu(struct iscsi_pdu *pdu)
                int i;
 
                buf = (void *)&pdu->bhs;
-               printk("BHS: (%p,%d)\n", buf, sizeof(pdu->bhs));
+               printk("BHS: (%p,%zd)\n", buf, sizeof(pdu->bhs));
                for (i = 0; i < sizeof(pdu->bhs); i++)
                        iscsi_dump_char(*buf++);
                iscsi_dump_char(-1);
index c514c1a..6e3f1e7 100644 (file)
@@ -281,7 +281,7 @@ static int iscsi_socket_bind(struct iscsi_conn *conn)
        mm_segment_t oldfs;
        struct iscsi_session *session = conn->session;
 
-       TRACE_DBG("%llu", (unsigned long long) session->sid);
+       TRACE_DBG("%llu", session->sid);
 
        conn->sock = SOCKET_I(conn->file->f_dentry->d_inode);
 
@@ -324,8 +324,7 @@ out:
 int conn_free(struct iscsi_conn *conn)
 {
        TRACE_MGMT_DBG("Freeing conn %p (sess=%p, %#Lx %u)", conn,
-               conn->session, (unsigned long long)conn->session->sid,
-               conn->cid);
+               conn->session, conn->session->sid, conn->cid);
 
        del_timer_sync(&conn->rsp_timer);
 
@@ -360,7 +359,7 @@ static int iscsi_conn_alloc(struct iscsi_session *session, struct conn_info *inf
        }
 
        TRACE_MGMT_DBG("Creating connection %p for sid %#Lx, cid %u", conn,
-               (unsigned long long)session->sid, info->cid);
+               session->sid, info->cid);
 
        /* Changing it, change ISCSI_CONN_IOV_MAX as well !! */
        conn->read_iov = (struct iovec *)get_zeroed_page(GFP_KERNEL);
index d9892a7..ee771bc 100644 (file)
@@ -1036,7 +1036,7 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
                        break;
                }
                conn->read_iov[i].iov_len = PAGE_SIZE - offset;
-               TRACE_DBG("idx=%d, offset=%u, size=%d, iov_len=%d, addr=%p",
+               TRACE_DBG("idx=%d, offset=%u, size=%d, iov_len=%zd, addr=%p",
                        idx, offset, size, conn->read_iov[i].iov_len, addr);
                size -= conn->read_iov[i].iov_len;
                offset = 0;
@@ -1050,7 +1050,7 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
                }
                idx++;
        }
-       TRACE_DBG("msg_iov=%p, msg_iovlen=%d",
+       TRACE_DBG("msg_iov=%p, msg_iovlen=%zd",
                conn->read_msg.msg_iov, conn->read_msg.msg_iovlen);
 
 out:
@@ -1244,7 +1244,7 @@ static int noop_out_start(struct iscsi_cmnd *cmnd)
                }
                sBUG_ON(size == 0);
                conn->read_msg.msg_iovlen = i;
-               TRACE_DBG("msg_iov=%p, msg_iovlen=%d", conn->read_msg.msg_iov,
+               TRACE_DBG("msg_iov=%p, msg_iovlen=%zd", conn->read_msg.msg_iov,
                        conn->read_msg.msg_iovlen);
        }
 out:
@@ -2493,7 +2493,7 @@ static void iscsi_try_local_processing(struct iscsi_conn *conn,
 
 static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
 {
-       int resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd);
+       int is_send_status = scst_cmd_get_is_send_status(scst_cmd);
        struct iscsi_cmnd *req = (struct iscsi_cmnd*)
                                        scst_cmd_get_tgt_priv(scst_cmd);
        struct iscsi_conn *conn = req->conn;
@@ -2507,6 +2507,9 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
        bool single_only = 0;
 #endif
 
+       if (scst_cmd_atomic(scst_cmd))
+               return SCST_TGT_RES_NEED_THREAD_CTX;
+
        scst_cmd_set_tgt_priv(scst_cmd, NULL);
 
        req->tmfabort |= scst_cmd_aborted(scst_cmd) ? 1 : 0;
@@ -2541,34 +2544,31 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
        req->sg = scst_cmd_get_sg(scst_cmd);
        req->sg_cnt = scst_cmd_get_sg_cnt(scst_cmd);
 
-       TRACE_DBG("req %p, resp_flags=%x, req->bufflen=%d, req->sg=%p, "
-               "req->sg_cnt %d", req, resp_flags, req->bufflen, req->sg,
+       TRACE_DBG("req %p, is_send_status=%x, req->bufflen=%d, req->sg=%p, "
+               "req->sg_cnt %d", req, is_send_status, req->bufflen, req->sg,
                req->sg_cnt);
 
-       if (unlikely((req->bufflen != 0) &&
-                    !(resp_flags & SCST_TSC_FLAG_STATUS))) {
+       if (unlikely((req->bufflen != 0) && !is_send_status)) {
                PRINT_CRIT_ERROR("%s", "Sending DATA without STATUS is unsupported");
                scst_set_cmd_error(scst_cmd,
                        SCST_LOAD_SENSE(scst_sense_hardw_error));
-               resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd);
                sBUG();
        }
 
        if (req->bufflen != 0) {
                /* 
-                * Check above makes sure that SCST_TSC_FLAG_STATUS is set,
+                * Check above makes sure that is_send_status is set,
                 * so status is valid here, but in future that could change.
                 * ToDo
                 */
                if (status != SAM_STAT_CHECK_CONDITION) {
-                       send_data_rsp(req, status,
-                               resp_flags & SCST_TSC_FLAG_STATUS);
+                       send_data_rsp(req, status, is_send_status);
                } else {
                        struct iscsi_cmnd *rsp;
                        struct iscsi_scsi_rsp_hdr *rsp_hdr;
                        int resid;
                        send_data_rsp(req, 0, 0);
-                       if (resp_flags & SCST_TSC_FLAG_STATUS) {
+                       if (is_send_status) {
                                rsp = create_status_rsp(req, status, sense,
                                        sense_len);
                                rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs;
@@ -2586,7 +2586,7 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
                                        ISCSI_INIT_WRITE_REMOVE_HASH);
                        }
                }
-       } else if (resp_flags & SCST_TSC_FLAG_STATUS) {
+       } else if (is_send_status) {
                struct iscsi_cmnd *rsp;
                struct iscsi_scsi_rsp_hdr *rsp_hdr;
                u32 resid;
@@ -2781,7 +2781,6 @@ struct scst_tgt_template iscsi_template = {
        .threads_num = 0,
        .no_clustering = 1,
        .xmit_response_atomic = 0,
-       .preprocessing_done_atomic = 1,
        .detect = iscsi_target_detect,
        .release = iscsi_target_release,
        .xmit_response = iscsi_xmit_response,
index 2806a6a..23102c1 100644 (file)
@@ -183,10 +183,15 @@ static void close_conn(struct iscsi_conn *conn)
 {
        struct iscsi_session *session = conn->session;
        struct iscsi_target *target = conn->target;
-       unsigned long start_waiting = jiffies;
-       unsigned long shut_start_waiting = start_waiting;
+       typeof(jiffies) start_waiting = jiffies;
+       typeof(jiffies) shut_start_waiting = start_waiting;
        bool pending_reported = 0, wait_expired = 0, shut_expired = 0;
 
+#define CONN_PENDING_TIMEOUT   ((typeof(jiffies))10*HZ)
+#define CONN_WAIT_TIMEOUT      ((typeof(jiffies))10*HZ)
+#define CONN_REG_SHUT_TIMEOUT  ((typeof(jiffies))125*HZ)
+#define CONN_DEL_SHUT_TIMEOUT  ((typeof(jiffies))10*HZ)
+
        TRACE_ENTRY();
 
        TRACE_CONN_CLOSE("Closing connection %p (conn_ref_cnt=%d)", conn,
@@ -291,7 +296,7 @@ static void close_conn(struct iscsi_conn *conn)
                        } while(req_freed);
                        spin_unlock(&session->sn_lock);
 
-                       if (time_after(jiffies, start_waiting + 10*HZ)) {
+                       if (time_after(jiffies, start_waiting + CONN_PENDING_TIMEOUT)) {
                                if (!pending_reported) {
                                        TRACE_CONN_CLOSE("%s", "Pending wait time expired");
                                        pending_reported = 1;
@@ -331,7 +336,9 @@ static void close_conn(struct iscsi_conn *conn)
 
                iscsi_make_conn_wr_active(conn);
 
-               if (time_after(jiffies, start_waiting + 10*HZ) && !wait_expired) {
+               /* That's for active close only, actually */
+               if (time_after(jiffies, start_waiting + CONN_WAIT_TIMEOUT) &&
+                   !wait_expired) {
                        TRACE_CONN_CLOSE("Wait time expired (conn %p, "
                                "sk_state %d)", conn, conn->sock->sk->sk_state);
                        conn->sock->ops->shutdown(conn->sock, SEND_SHUTDOWN);
@@ -339,17 +346,20 @@ static void close_conn(struct iscsi_conn *conn)
                        shut_start_waiting = jiffies;
                }
 
-               if (conn->deleting) {
-                       if (wait_expired && !shut_expired &&
-                           time_after(jiffies, shut_start_waiting + 10*HZ)) {
-                               TRACE_CONN_CLOSE("Wait time after shutdown expired "
-                                       "(conn %p, sk_state %d)", conn,
-                                       conn->sock->sk->sk_state);
-                               conn->sock->sk->sk_prot->disconnect(conn->sock->sk, 0);
-                               shut_expired = 1;
-                       }
+               if (wait_expired && !shut_expired &&
+                   time_after(jiffies, shut_start_waiting +
+                               conn->deleting ? CONN_DEL_SHUT_TIMEOUT :
+                                                CONN_REG_SHUT_TIMEOUT)) {
+                       TRACE_CONN_CLOSE("Wait time after shutdown expired "
+                               "(conn %p, sk_state %d)", conn,
+                               conn->sock->sk->sk_state);
+                       conn->sock->sk->sk_prot->disconnect(conn->sock->sk, 0);
+                       shut_expired = 1;
+               }
+
+               if (conn->deleting)
                        msleep(200);
-               else
+               else
                        msleep(1000);
 
                TRACE_CONN_CLOSE_DBG("conn %p, conn_ref_cnt %d left, wr_state %d, "
@@ -362,7 +372,7 @@ static void close_conn(struct iscsi_conn *conn)
 #endif
 
 #if 0
-                       if (time_after(jiffies, start_waiting+10*HZ))
+                       if (time_after(jiffies, start_waiting + 10*HZ))
                                trace_flag |= TRACE_CONN_OC_DBG;
 #endif
 
@@ -924,7 +934,7 @@ static int write_data(struct iscsi_conn *conn)
        struct scatterlist *sg;
        struct iovec *iop;
        int saved_size, size, sendsize;
-       int offset, idx;
+       int offset, idx, sg_offset;
        int flags, res, count;
        bool do_put = false;
 
@@ -947,7 +957,6 @@ static int write_data(struct iscsi_conn *conn)
                spin_unlock_bh(&conn->write_list_lock);
        }
 
-#if 0 /* temp. ToDo */
        if (!timer_pending(&conn->rsp_timer)) {
                sBUG_ON(!ref_cmd->on_written_list);
                spin_lock_bh(&conn->write_list_lock);
@@ -959,7 +968,6 @@ static int write_data(struct iscsi_conn *conn)
                }
                spin_unlock_bh(&conn->write_list_lock);
        }
-#endif
 
        file = conn->file;
        saved_size = size = conn->write_size;
@@ -976,8 +984,7 @@ retry:
                set_fs(KERNEL_DS);
                res = vfs_writev(file, (struct iovec __user *)iop, count, &off);
                set_fs(oldfs);
-               TRACE_WRITE("%#Lx:%u: %d(%ld)",
-                       (unsigned long long)conn->session->sid, conn->cid,
+               TRACE_WRITE("%#Lx:%u: %d(%ld)", conn->session->sid, conn->cid,
                        res, (long)iop->iov_len);
                if (unlikely(res <= 0)) {
                        if (res == -EAGAIN) {
@@ -1020,7 +1027,8 @@ retry:
        __iscsi_get_page_callback(ref_cmd);
        do_put = true;
 
-       offset = conn->write_offset + sg[0].offset;
+       sg_offset = sg[0].offset;
+       offset = conn->write_offset + sg_offset;
        idx = offset >> PAGE_SHIFT;
        offset &= ~PAGE_MASK;
 
@@ -1074,7 +1082,7 @@ retry2:
                        TRACE_WRITE("Final %s %#Lx:%u: %d(%lu,%u,%u, cmd %p, page %p)",
                                (sendpage != sock_no_sendpage) ? "sendpage" : 
                                                                 "sock_no_sendpage",
-                               (unsigned long long)conn->session->sid, conn->cid,
+                               conn->session->sid, conn->cid,
                                res, sg_page(&sg[idx])->index, offset, size,
                                write_cmnd, sg_page(&sg[idx]));
                        if (unlikely(res <= 0)) {
@@ -1124,7 +1132,7 @@ retry1:
        }
 
 out_off:
-       conn->write_offset = (idx << PAGE_SHIFT) + offset - sg[0].offset;
+       conn->write_offset = (idx << PAGE_SHIFT) + offset - sg_offset;
 
 out_iov:
        conn->write_size = size;
@@ -1153,8 +1161,7 @@ out_err:
 #endif
        {
                PRINT_ERROR("error %d at sid:cid %#Lx:%u, cmnd %p", res,
-                       (unsigned long long)conn->session->sid, conn->cid,
-                       conn->write_cmnd);
+                       conn->session->sid, conn->cid, conn->write_cmnd);
        }
        if (ref_cmd->scst_cmd != NULL)
                scst_set_delivery_status(ref_cmd->scst_cmd,
index e3b0500..cab228e 100644 (file)
@@ -94,7 +94,7 @@ static int iscsi_session_alloc(struct iscsi_target *target, struct session_info
        list_add(&session->session_list_entry, &target->session_list);
 
        TRACE_MGMT_DBG("Session %p created: target %p, tid %u, sid %#Lx",
-               session, target, target->tid, (unsigned long long) info->sid);
+               session, target, target->tid, info->sid);
 
        return 0;
 err:
@@ -129,8 +129,7 @@ int session_free(struct iscsi_session *session)
 {
        int i;
 
-       TRACE_MGMT_DBG("Freeing session %p:%#Lx", session,
-               (unsigned long long)session->sid);
+       TRACE_MGMT_DBG("Freeing session %p:%#Lx", session, session->sid);
 
        sBUG_ON(!list_empty(&session->conn_list));
        if (unlikely(atomic_read(&session->active_cmds) != 0)) {
@@ -163,8 +162,7 @@ int session_del(struct iscsi_target *target, u64 sid)
                return -ENOENT;
 
        if (!list_empty(&session->conn_list)) {
-               PRINT_ERROR("%llu still have connections",
-                       (unsigned long long)session->sid);
+               PRINT_ERROR("%llu still have connections", session->sid);
                return -EBUSY;
        }
 
@@ -178,8 +176,8 @@ static void iscsi_session_info_show(struct seq_file *seq, struct iscsi_target *t
 
        list_for_each_entry(session, &target->session_list, session_list_entry) {
                seq_printf(seq, "\tsid:%llu initiator:%s shutting down %d\n",
-                          (unsigned long long)session->sid,
-                          session->initiator_name, session->shutting_down);
+                       session->sid, session->initiator_name,
+                       session->shutting_down);
                conn_info_show(seq, session);
        }
 }
index c7cf12b..49145a9 100644 (file)
@@ -28,10 +28,10 @@ LIBS = -lcrypto
 all: $(PROGRAMS)
 
 iscsi-scstd: .depend_d $(OBJS_D)
-       $(CC) $(OBJS_D) $(LIBS) -o $@
+       $(CC) $(OBJS_D) $(LIBS) $(LOCAL_LD_FLAGS) -o $@
 
 iscsi-scst-adm: .depend_adm  $(OBJS_ADM)
-       $(CC) $(OBJS_ADM) $(LIBS) -o $@
+       $(CC) $(OBJS_ADM) $(LIBS) $(LOCAL_LD_FLAGS) -o $@
 
 ifeq (.depend_d,$(wildcard .depend_d))
 -include .depend_d
index a221084..e63299f 100644 (file)
@@ -1588,11 +1588,17 @@ mpt_xmit_response(struct scst_cmd *scst_cmd)
        int res = SCST_TGT_RES_SUCCESS;
        struct mpt_sess *sess;
        struct mpt_prm prm = { 0 };
-       int resp_flags;
+       int is_send_status;
        //uint16_t full_req_cnt;
        //int data_sense_flag = 0;
 
        TRACE_ENTRY();
+
+#ifdef DEBUG_WORK_IN_THREAD
+       if (scst_cmd_atomic(scst_cmd))
+               return SCST_TGT_RES_NEED_THREAD_CTX;
+#endif
+
        prm.cmd = (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
        sess = (struct mpt_sess *)
                scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
@@ -1607,16 +1613,16 @@ mpt_xmit_response(struct scst_cmd *scst_cmd)
        prm.sense_buffer_len = scst_cmd_get_sense_buffer_len(scst_cmd);
        prm.tgt = sess->tgt;
        prm.seg_cnt = 0;
-       resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd);
+       is_send_status = scst_cmd_get_is_send_status(scst_cmd);
 
-       TRACE_DBG("rq_result=%x, resp_flags=%x, %x, %d", prm.rq_result, 
-                       resp_flags, prm.bufflen, prm.sense_buffer_len);
+       TRACE_DBG("rq_result=%x, is_send_status=%x, %x, %d", prm.rq_result, 
+                       is_send_status, prm.bufflen, prm.sense_buffer_len);
        if ((prm.rq_result != 0) && (prm.sense_buffer != NULL))
                TRACE_BUFFER("Sense", prm.sense_buffer, prm.sense_buffer_len);
 
-       if ((resp_flags & SCST_TSC_FLAG_STATUS) == 0) {
+       if (!is_send_status) {
                /* ToDo, after it's done in SCST */
-               PRINT_ERROR(MYNAM ": SCST_TSC_FLAG_STATUS not set: "
+               PRINT_ERROR(MYNAM ": is_send_status not set: "
                            "feature not implemented %p", scst_cmd);
                res = SCST_TGT_RES_FATAL_ERROR;
                goto out_tgt_free;
@@ -1740,6 +1746,12 @@ static int mpt_rdy_to_xfer(struct scst_cmd *scst_cmd)
        struct mpt_prm prm = { 0 };
 
        TRACE_ENTRY();
+
+#ifdef DEBUG_WORK_IN_THREAD
+       if (scst_cmd_atomic(scst_cmd))
+               return SCST_TGT_RES_NEED_THREAD_CTX;
+#endif
+
        prm.cmd = (struct mpt_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
        sess = (struct mpt_sess *)
                scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
index bad91b3..e959e1f 100644 (file)
@@ -672,7 +672,7 @@ static int q2t_xmit_response(struct scst_cmd *scst_cmd)
 {
        int res = SCST_TGT_RES_SUCCESS;
        struct q2t_sess *sess;
-       int resp_flags;
+       int is_send_status;
        unsigned long flags = 0;
        struct q2t_prm prm = { 0 };
        int data_sense_flag = 0;
@@ -681,6 +681,11 @@ static int q2t_xmit_response(struct scst_cmd *scst_cmd)
        TRACE_ENTRY();
        TRACE(TRACE_SCSI, "tag=%Ld", scst_cmd_get_tag(scst_cmd));
 
+#ifdef DEBUG_WORK_IN_THREAD
+       if (scst_cmd_atomic(scst_cmd))
+               return SCST_TGT_RES_NEED_THREAD_CTX;
+#endif
+
        prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
        sess = (struct q2t_sess *)
                scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
@@ -709,15 +714,17 @@ static int q2t_xmit_response(struct scst_cmd *scst_cmd)
        prm.tgt = sess->tgt;
        prm.seg_cnt = 0;
        prm.req_cnt = 1;
-       resp_flags = scst_cmd_get_tgt_resp_flags(scst_cmd);
+       is_send_status = scst_cmd_get_is_send_status(scst_cmd);
+
+       TRACE_DBG("rq_result=%x, is_send_status=%x", prm.rq_result,
+               is_send_status);
 
-       TRACE_DBG("rq_result=%x, resp_flags=%x", prm.rq_result, resp_flags);
        if (prm.rq_result != 0)
                TRACE_BUFFER("Sense", prm.sense_buffer, prm.sense_buffer_len);
 
-       if ((resp_flags & SCST_TSC_FLAG_STATUS) == 0) {
+       if (!is_send_status) {
                /* ToDo, after it's done in SCST */
-               PRINT_ERROR("qla2x00tgt(%ld): SCST_TSC_FLAG_STATUS not set: "
+               PRINT_ERROR("qla2x00tgt(%ld): is_send_status not set: "
                     "feature not implemented", prm.tgt->ha->instance);
                res = SCST_TGT_RES_FATAL_ERROR;
                goto out;
@@ -827,6 +834,11 @@ static int q2t_rdy_to_xfer(struct scst_cmd *scst_cmd)
        TRACE_ENTRY();
        TRACE(TRACE_SCSI, "tag=%Ld", scst_cmd_get_tag(scst_cmd));
 
+#ifdef DEBUG_WORK_IN_THREAD
+       if (scst_cmd_atomic(scst_cmd))
+               return SCST_TGT_RES_NEED_THREAD_CTX;
+#endif
+
        prm.cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
        sess = (struct q2t_sess *)
                scst_sess_get_tgt_priv(scst_cmd_get_session(scst_cmd));
@@ -2134,8 +2146,8 @@ static int q2t_log_info_show(struct seq_file *seq, void *v)
        return res;
 }
 
-static int q2t_proc_log_entry_write(struct file *file, const char __user *buf,
-                                        size_t length, loff_t *off)
+static ssize_t q2t_proc_log_entry_write(struct file *file,
+       const char __user *buf, size_t length, loff_t *off)
 {
        int res = 0;
 
@@ -2148,7 +2160,6 @@ static int q2t_proc_log_entry_write(struct file *file, const char __user *buf,
        return res;
 }
 
-
 static struct scst_proc_data q2t_log_proc_data = {
        SCST_DEF_RW_SEQ_OP(q2t_proc_log_entry_write)
        .show = q2t_log_info_show,
index 5f4c637..7af3d56 100644 (file)
@@ -1089,7 +1089,7 @@ isp_xmit_response(struct scst_cmd *scst_cmd)
         xact->td_hflags &= ~TDFH_DATA_MASK;
     }
 
-    if (scst_cmd_get_tgt_resp_flags(scst_cmd) & SCST_TSC_FLAG_STATUS) {
+    if (scst_cmd_get_is_send_status(scst_cmd)) {
         xact->td_hflags |= TDFH_STSVALID;
         tmd->cd_scsi_status = scst_cmd_get_status(scst_cmd);
 
index dd9c2f4..75ca05f 100644 (file)
@@ -106,16 +106,6 @@ IMPORTANT: Working of target and initiator on the same host isn't
           request to the target -> target needs memory -> problem is
           possible.
 
-IMPORTANT: Experience shows that if people work with out of SCST tree target
-=========  drivers, like target driver for Infiniband or in case if they
-           downloaded and use the released versions of SCST and target
-          drivers, they are too often (actually, almost always) after
-          upgrading SCST core forget to rebuild their target drivers,
-          which then immediately after load crash in the hard to trace
-          manner. So, after you reinstalled SCST core don't forget to
-          rebuild and reinstall all your target drivers, custom dev
-          handlers and necessary user space applications.
-
 IMPORTANT: In the current version simultaneous access to local SCSI devices
 =========  via standard high-level SCSI drivers (sd, st, sg, etc.) and
            SCST's target drivers is unsupported. Especially it is
@@ -396,6 +386,9 @@ following files and directories under /proc/scsi_tgt:
   - "clear" to /proc/scsi_tgt/groups/GROUP/names clears the list of names
     for group "GROUP"
 
+There must be LUN 0 in each security group, i.e. LUs numeration must not
+start from, e.g., 1.
+
 Examples:
 
  - "echo "add 1:0:1:0 0" >/proc/scsi_tgt/groups/Default/devices" will
index 7df5e51..555a077 100644 (file)
@@ -293,16 +293,12 @@ typedef _Bool bool;
  *************************************************************/
 #define SCST_DEFAULT_TIMEOUT         (30*HZ)
 
-/*************************************************************
- ** Flags of cmd->tgt_resp_flags
- *************************************************************/
-
 /* 
  * Set if cmd is finished and there is status/sense to be sent. 
  * The status should be not sent (i.e. the flag not set) if the 
  * possibility to perform a command in "chunks" (i.e. with multiple 
- * xmit_response()/rdy_to_xfer()) is used (not implemented and,
- * probably, will never be).
+ * xmit_response()/rdy_to_xfer()) is used (not implemented yet).
+ * Obsolete, use scst_cmd_get_is_send_status() instead.
  */
 #define SCST_TSC_FLAG_STATUS         0x2
 
@@ -472,7 +468,6 @@ struct scst_tgt_template
         */
        unsigned xmit_response_atomic:1;
        unsigned rdy_to_xfer_atomic:1;
-       unsigned preprocessing_done_atomic:1;
 
        /* True, if the template doesn't need the entry in /proc */
        unsigned no_proc_entry:1;
@@ -752,7 +747,7 @@ struct scst_dev_type
 
        /* 
         * Called to notify dev handler about the result of cmd execution
-        * and perform some post processing. Cmd's fields tgt_resp_flags and
+        * and perform some post processing. Cmd's fields is_send_status and
         * resp_data_len should be set by this function, but SCST offers good
         * defaults.
         * Returns the command's next state or SCST_CMD_STATE_DEFAULT, 
@@ -1022,6 +1017,9 @@ struct scst_cmd
        /* Set if cmd is being processed in atomic context */
        unsigned int atomic:1;
 
+       /* Set if this command contains status */
+       unsigned int is_send_status:1;
+
        /*
         * Set if the cmd is being processed in the processable context. See
         * comment for SCST_CONTEXT_PROCESSABLE for what it means.
@@ -1208,12 +1206,6 @@ struct scst_cmd
        /* scst_get_sg_buf_[first,next]() support */
        int get_sg_buf_entry_num;
 
-       /*
-        * The following two fields should be corrected by the dev_done(),
-        * if necessary
-        */
-       int tgt_resp_flags;     /* response flags (SCST_TSC_FLAG_* constants) */
-
        /* 
         * Response data length in data buffer. This field must not be set
         * directly, use scst_set_resp_data_len() for that
@@ -1340,6 +1332,9 @@ struct scst_device
        /* How many cmds alive on this dev */
        atomic_t dev_cmd_count; 
 
+       /* How many write cmds alive on this dev. Temporary, ToDo */
+       atomic_t write_cmd_count; 
+
        unsigned short type;    /* SCSI type of the device */
 
        /*************************************************************
@@ -2029,10 +2024,19 @@ static inline int scst_cmd_get_resp_data_len(struct scst_cmd *cmd)
        return cmd->resp_data_len;
 }
 
-/* Returns cmd's response flags (SCST_TSC_FLAG_* constants) */
-static inline int scst_cmd_get_tgt_resp_flags(struct scst_cmd *cmd)
+/*
+ * Returns cmd's response flags (SCST_TSC_FLAG_* constants). Obsolete, use
+ * scst_cmd_get_is_send_status() instead.
+ */
+static inline __deprecated int scst_cmd_get_tgt_resp_flags(struct scst_cmd *cmd)
+{
+       return cmd->is_send_status ? SCST_TSC_FLAG_STATUS : 0;
+}
+
+/* Returns if status should be sent for cmd */
+static inline int scst_cmd_get_is_send_status(struct scst_cmd *cmd)
 {
-       return cmd->tgt_resp_flags;
+       return cmd->is_send_status;
 }
 
 /*
index 6c33973..c141948 100644 (file)
@@ -177,7 +177,7 @@ int changer_done(struct scst_cmd *cmd)
        TRACE_ENTRY();
 
        /*
-        * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len
+        * SCST sets good defaults for cmd->is_send_status and cmd->resp_data_len
         * based on cmd->status and cmd->data_direction, therefore change
         * them only if necessary
         */
index c1c7231..644155e 100644 (file)
@@ -176,7 +176,7 @@ int processor_done(struct scst_cmd *cmd)
        TRACE_ENTRY();
 
        /*
-        * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len
+        * SCST sets good defaults for cmd->is_send_status and cmd->resp_data_len
         * based on cmd->status and cmd->data_direction, therefore change
         * them only if necessary
         */
index da41be6..d553b6d 100644 (file)
@@ -176,7 +176,7 @@ int raid_done(struct scst_cmd *cmd)
        TRACE_ENTRY();
 
        /*
-        * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len
+        * SCST sets good defaults for cmd->is_send_status and cmd->resp_data_len
         * based on cmd->status and cmd->data_direction, therefore change
         * them only if necessary
         */
index 658da01..8062496 100644 (file)
@@ -384,8 +384,8 @@ int tape_done(struct scst_cmd *cmd)
                }
        }
 
-       TRACE_DBG("cmd->tgt_resp_flags=%x, cmd->resp_data_len=%d, "
-             "res=%d", cmd->tgt_resp_flags, cmd->resp_data_len, res);
+       TRACE_DBG("cmd->is_send_status=%x, cmd->resp_data_len=%d, "
+             "res=%d", cmd->is_send_status, cmd->resp_data_len, res);
 
        TRACE_EXIT_RES(res);
        return res;
index d16ca4d..f0091c0 100644 (file)
@@ -278,7 +278,7 @@ static inline struct scst_user_cmd *__ucmd_find_hash(struct scst_user_dev *dev,
        return NULL;
 }
 
-static void cmnd_insert_hash(struct scst_user_cmd *ucmd)
+static void cmd_insert_hash(struct scst_user_cmd *ucmd)
 {
        struct list_head *head;
        struct scst_user_dev *dev = ucmd->dev;
@@ -298,7 +298,7 @@ static void cmnd_insert_hash(struct scst_user_cmd *ucmd)
        return;
 }
 
-static inline void cmnd_remove_hash(struct scst_user_cmd *ucmd)
+static inline void cmd_remove_hash(struct scst_user_cmd *ucmd)
 {
        unsigned long flags;
        spin_lock_irqsave(&ucmd->dev->cmd_lists.cmd_list_lock, flags);
@@ -315,7 +315,7 @@ static void dev_user_free_ucmd(struct scst_user_cmd *ucmd)
 
        TRACE_MEM("Freeing ucmd %p", ucmd);
 
-       cmnd_remove_hash(ucmd);
+       cmd_remove_hash(ucmd);
        EXTRACHECKS_BUG_ON(ucmd->cmd != NULL);
 
        kmem_cache_free(user_cmd_cachep, ucmd);
@@ -630,7 +630,7 @@ static struct scst_user_cmd *dev_user_alloc_ucmd(struct scst_user_dev *dev,
        ucmd->dev = dev;
        atomic_set(&ucmd->ucmd_ref, 1);
 
-       cmnd_insert_hash(ucmd);
+       cmd_insert_hash(ucmd);
 
        TRACE_MEM("ucmd %p allocated", ucmd);
 
@@ -784,9 +784,22 @@ out:
 static int dev_user_exec(struct scst_cmd *cmd)
 {
        struct scst_user_cmd *ucmd = (struct scst_user_cmd*)cmd->dh_priv;
+       int res = SCST_EXEC_COMPLETED;
 
        TRACE_ENTRY();
 
+#if 0 /* We set exec_atomic in 0 to let SCST core know that we need a thread
+       * context to complete the necessary actions, but all we are going to
+       * do in this function is, in fact, atomic, so let's skip this check.
+       */
+       if (scst_cmd_atomic(cmd)) {
+               TRACE_DBG("%s", "User exec() can not be called in atomic "
+                       "context, rescheduling to the thread");
+               res = SCST_EXEC_NEED_THREAD;
+               goto out;
+       }
+#endif
+
        TRACE_DBG("Preparing EXEC for user space (ucmd=%p, h=%d, "
                "bufflen %d, data_len %d, ubuff %lx)", ucmd, ucmd->h,
                cmd->bufflen, cmd->data_len, ucmd->ubuff);
@@ -818,8 +831,8 @@ static int dev_user_exec(struct scst_cmd *cmd)
 
        dev_user_add_to_ready(ucmd);
 
-       TRACE_EXIT();
-       return SCST_EXEC_COMPLETED;
+       TRACE_EXIT_RES(res);
+       return res;
 }
 
 static void dev_user_free_sgv(struct scst_user_cmd *ucmd)
@@ -2920,6 +2933,8 @@ static int dev_user_release(struct inode *inode, struct file *file)
        }
        file->private_data = NULL;
 
+       TRACE(TRACE_MGMT, "Releasing dev %s", dev->name);
+
        spin_lock(&dev_list_lock);
        list_del(&dev->dev_list_entry);
        spin_unlock(&dev_list_lock);
@@ -2928,8 +2943,6 @@ static int dev_user_release(struct inode *inode, struct file *file)
 
        down_write(&dev->dev_rwsem);
 
-       TRACE_DBG("Releasing dev %p", dev);
-
        spin_lock(&cleanup_lock);
        list_add_tail(&dev->cleanup_list_entry, &cleanup_list);
        spin_unlock(&cleanup_lock);
index 63822d6..df3595c 100644 (file)
@@ -666,7 +666,7 @@ static inline int vdisk_need_pre_sync(enum scst_cmd_queue_type cur,
 
 static int vdisk_do_job(struct scst_cmd *cmd)
 {
-       int rc;
+       int rc, res;
        uint64_t lba_start = 0;
        loff_t data_len = 0;
        uint8_t *cdb = cmd->cdb;
@@ -681,6 +681,13 @@ static int vdisk_do_job(struct scst_cmd *cmd)
 
        TRACE_ENTRY();
 
+       if (scst_cmd_atomic(cmd)) {
+               TRACE_DBG("%s", "vdisk exec() can not be done in atomic "
+                       "context, requesting thread context");
+               res = SCST_EXEC_NEED_THREAD;
+               goto out;
+       }
+
        switch(cmd->queue_type) {
        case SCST_CMD_QUEUE_ORDERED:
                TRACE(TRACE_ORDER, "ORDERED cmd %p", cmd);
@@ -795,7 +802,7 @@ static int vdisk_do_job(struct scst_cmd *cmd)
        case READ_16:
                if (virt_dev->blockio) {
                        blockio_exec_rw(cmd, thr, lba_start, 0);
-                       goto out;
+                       goto out_thr;
                } else
                        vdisk_exec_read(cmd, thr, loff);
                break;
@@ -822,7 +829,7 @@ static int vdisk_do_job(struct scst_cmd *cmd)
                        }
                        if (virt_dev->blockio) {
                                blockio_exec_rw(cmd, thr, lba_start, 1);
-                               goto out;
+                               goto out_thr;
                        } else
                                vdisk_exec_write(cmd, thr, loff);
                        /* O_SYNC flag is used for WT devices */
@@ -882,7 +889,7 @@ static int vdisk_do_job(struct scst_cmd *cmd)
                        vdisk_fsync(thr, loff, data_len, NULL);
                        /* ToDo: vdisk_fsync() error processing */
                        scst_cmd_put(cmd);
-                       goto out;
+                       goto out_thr;
                } else {
                        vdisk_fsync(thr, loff, data_len, cmd);
                        break;
@@ -949,12 +956,15 @@ out_compl:
 out_done:
        cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
 
-out:
+out_thr:
        if (likely(thr != NULL))
                scst_thr_data_put(&thr->hdr);
 
-       TRACE_EXIT();
-       return SCST_EXEC_COMPLETED;
+       res = SCST_EXEC_COMPLETED;
+
+out:
+       TRACE_EXIT_RES(res);
+       return res;
 }
 
 static int vdisk_get_block_shift(struct scst_cmd *cmd)
index 0c2a703..10f92e8 100644 (file)
@@ -197,7 +197,7 @@ static const struct scst_sdbops scst_scsi_op_table[] = {
        {0x1B, "O   OO O    O   ", "STOP START UNIT",
         SCST_DATA_NONE, SCST_LONG_TIMEOUT, 0, get_trans_len_none},
        {0x1C, "OOOOOOOOOOOOOOOO", "RECEIVE DIAGNOSTIC RESULTS",
-        SCST_DATA_READ, FLAG_NONE, 4, get_trans_len_1},
+        SCST_DATA_READ, FLAG_NONE, 3, get_trans_len_2},
        {0x1D, "MMMMMMMMMMMMMMMM", "SEND DIAGNOSTIC",
         SCST_DATA_WRITE, FLAG_NONE, 4, get_trans_len_1},
        {0x1E, "OOOOOOOOOOOOOOOO", "PREVENT ALLOW MEDIUM REMOVAL",
index bd91768..037e90a 100644 (file)
@@ -94,7 +94,7 @@ void scst_set_cmd_error_status(struct scst_cmd *cmd, int status)
        cmd->host_status = DID_OK;
 
        cmd->data_direction = SCST_DATA_NONE;
-       cmd->tgt_resp_flags = SCST_TSC_FLAG_STATUS;
+       cmd->is_send_status = 1;
        cmd->resp_data_len = 0;
 
        cmd->completed = 1;
@@ -233,6 +233,7 @@ int scst_alloc_device(int gfp_mask, struct scst_device **out_dev)
        dev->handler = &scst_null_devtype;
        dev->p_cmd_lists = &scst_main_cmd_lists;
        atomic_set(&dev->dev_cmd_count, 0);
+       atomic_set(&dev->write_cmd_count, 0);
        spin_lock_init(&dev->dev_lock);
        atomic_set(&dev->on_dev_count, 0);
        INIT_LIST_HEAD(&dev->blocked_cmd_list);
@@ -474,16 +475,18 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
                atomic_set(&tgt_dev->sn_slots[i], 0);
 
        if (dev->handler->parse_atomic && 
-           sess->tgt->tgtt->preprocessing_done_atomic) {
-               if (sess->tgt->tgtt->rdy_to_xfer_atomic)
+           (sess->tgt->tgtt->preprocessing_done == NULL)) {
+               if (sess->tgt->tgtt->rdy_to_xfer_atomic ||
+                   (sess->tgt->tgtt->rdy_to_xfer == NULL))
                        __set_bit(SCST_TGT_DEV_AFTER_INIT_WR_ATOMIC,
                                &tgt_dev->tgt_dev_flags);
-               if (dev->handler->exec_atomic)
+               if (dev->handler->exec_atomic || (dev->handler->exec == NULL))
                        __set_bit(SCST_TGT_DEV_AFTER_INIT_OTH_ATOMIC,
                                &tgt_dev->tgt_dev_flags);
        }
-       if (dev->handler->exec_atomic) {
-               if (sess->tgt->tgtt->rdy_to_xfer_atomic)
+       if (dev->handler->exec_atomic || (dev->handler->exec == NULL)) {
+               if (sess->tgt->tgtt->rdy_to_xfer_atomic ||
+                   (sess->tgt->tgtt->rdy_to_xfer == NULL))
                        __set_bit(SCST_TGT_DEV_AFTER_RESTART_WR_ATOMIC,
                                &tgt_dev->tgt_dev_flags);
                __set_bit(SCST_TGT_DEV_AFTER_RESTART_OTH_ATOMIC,
@@ -491,7 +494,8 @@ static struct scst_tgt_dev *scst_alloc_add_tgt_dev(struct scst_session *sess,
                __set_bit(SCST_TGT_DEV_AFTER_RX_DATA_ATOMIC,
                        &tgt_dev->tgt_dev_flags);
        }
-       if (dev->handler->dev_done_atomic && 
+       if ((dev->handler->dev_done_atomic ||
+            (dev->handler->dev_done == NULL)) &&
            sess->tgt->tgtt->xmit_response_atomic) {
                __set_bit(SCST_TGT_DEV_AFTER_EXEC_ATOMIC,
                        &tgt_dev->tgt_dev_flags);
@@ -1301,7 +1305,7 @@ struct scst_cmd *scst_alloc_cmd(int gfp_mask)
        cmd->timeout = SCST_DEFAULT_TIMEOUT;
        cmd->retries = 0;
        cmd->data_len = -1;
-       cmd->tgt_resp_flags = SCST_TSC_FLAG_STATUS;
+       cmd->is_send_status = 1;
        cmd->resp_data_len = -1;
 
 out:
@@ -1677,7 +1681,7 @@ static int get_trans_len_read_pos(struct scst_cmd *cmd, uint8_t off)
        cmd->bufflen = 0;
        cmd->bufflen |= ((u32)p[0]) << 8;
        cmd->bufflen |= ((u32)p[1]);
-       
+
        switch (cmd->cdb[1] & 0x1f) {
        case 0:
        case 1:
@@ -2177,7 +2181,7 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd,
        TRACE_ENTRY();
 
        /*
-        * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len
+        * SCST sets good defaults for cmd->is_send_status and cmd->resp_data_len
         * based on cmd->status and cmd->data_direction, therefore change
         * them only if necessary
         */
@@ -2215,8 +2219,8 @@ int scst_block_generic_dev_done(struct scst_cmd *cmd,
                }
        }
 
-       TRACE_DBG("cmd->tgt_resp_flags=%x, cmd->resp_data_len=%d, "
-             "res=%d", cmd->tgt_resp_flags, cmd->resp_data_len, res);
+       TRACE_DBG("cmd->is_send_status=%x, cmd->resp_data_len=%d, "
+             "res=%d", cmd->is_send_status, cmd->resp_data_len, res);
 
 out:
        TRACE_EXIT_RES(res);
@@ -2234,7 +2238,7 @@ int scst_tape_generic_dev_done(struct scst_cmd *cmd,
        TRACE_ENTRY();
 
        /*
-        * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len
+        * SCST sets good defaults for cmd->is_send_status and cmd->resp_data_len
         * based on cmd->status and cmd->data_direction, therefore change
         * them only if necessary
         */
@@ -2375,18 +2379,27 @@ int scst_obtain_device_parameters(struct scst_device *dev)
 #else
                        if (
 #endif
-                           SCST_SENSE_VALID(sense_buffer) &&
-                           (sense_buffer[2] == ILLEGAL_REQUEST)) {
-                               TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Device %d:%d:%d:%d "
-                                       "doesn't support control mode page, using "
-                                       "defaults: TST %x, QUEUE ALG %x, SWP %x, "
-                                       "TAS %x, has_own_order_mgmt %d",
-                                       dev->scsi_dev->host->host_no,
-                                       dev->scsi_dev->channel, dev->scsi_dev->id,
-                                       dev->scsi_dev->lun, dev->tst, dev->queue_alg,
-                                       dev->swp, dev->tas, dev->has_own_order_mgmt);
-                               res = 0;
-                               goto out;
+                           SCST_SENSE_VALID(sense_buffer)) {
+                               if (sense_buffer[2] == ILLEGAL_REQUEST) {
+                                       TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Device "
+                                               "%d:%d:%d:%d doesn't support control "
+                                               "mode page, using defaults: TST "
+                                               "%x, QUEUE ALG %x, SWP %x, TAS %x, "
+                                               "has_own_order_mgmt %d",
+                                               dev->scsi_dev->host->host_no,
+                                               dev->scsi_dev->channel, dev->scsi_dev->id,
+                                               dev->scsi_dev->lun, dev->tst, dev->queue_alg,
+                                               dev->swp, dev->tas, dev->has_own_order_mgmt);
+                                       res = 0;
+                                       goto out;
+                               } else if (sense_buffer[2] == NOT_READY) {
+                                       TRACE(TRACE_SCSI, "Device %d:%d:%d:%d not ready",
+                                               dev->scsi_dev->host->host_no,
+                                               dev->scsi_dev->channel, dev->scsi_dev->id,
+                                               dev->scsi_dev->lun);
+                                       res = 0;
+                                       goto out;
+                               }
                        } else {
                                TRACE(TRACE_SCSI|TRACE_MGMT_MINOR, "Internal MODE SENSE to "
                                        "device %d:%d:%d:%d failed: %x",
index 862bc08..2b2729b 100644 (file)
@@ -204,9 +204,6 @@ int __scst_register_target_template(struct scst_tgt_template *vtt,
                        goto out_err;
        }
 
-       if (vtt->preprocessing_done == NULL)
-               vtt->preprocessing_done_atomic = 1;
-
        if (mutex_lock_interruptible(&m) != 0)
                goto out_err;
 
index 38d5050..87112ed 100644 (file)
 #include "scst_priv.h"
 #include "scst_mem.h"
 
-#define PURGE_INTERVAL         (15 * HZ)
-#define PURGE_TIME_AFTER       (15 * HZ)
+#define PURGE_INTERVAL         (60 * HZ)
+#define PURGE_TIME_AFTER       PURGE_INTERVAL
 #define SHRINK_TIME_AFTER      (1 * HZ)
 
-
 static struct scst_sgv_pools_manager sgv_pools_mgr;
 
 void scst_sgv_pool_use_norm(struct scst_tgt_dev *tgt_dev)
@@ -342,8 +341,7 @@ static struct sgv_pool_obj *sgv_pool_cached_get(struct sgv_pool *pool,
                sgv_pools_mgr.mgr.thr.inactive_pages_total -= 1 << order;
                spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
                EXTRACHECKS_BUG_ON(obj->order != order);
-               
-               return obj;
+               goto out;
        }
 
        pool->acc.cached_entries++;
@@ -364,20 +362,43 @@ static struct sgv_pool_obj *sgv_pool_cached_get(struct sgv_pool *pool,
                spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
        }
 
+out:
        return obj;     
 }
 
 static void sgv_pool_cached_put(struct sgv_pool_obj *sgv)
 {
        struct sgv_pool *owner = sgv->owner_pool;
+       struct list_head *entry;
+       struct list_head *list = &owner->recycling_lists[sgv->order];
        int sched = 0;
 
        spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
 
-       list_add(&sgv->recycle_entry.recycling_list_entry,
-               &owner->recycling_lists[sgv->order]);
+       TRACE_MEM("sgv %p, order %d, sg_count %d", sgv, sgv->order,
+               sgv->sg_count);
+
+       if (owner->clustered) {
+               /* Make objects with less entries more preferred */
+               __list_for_each(entry, list) {
+                       struct sgv_pool_obj *tmp = list_entry(entry,
+                               struct sgv_pool_obj,
+                               recycle_entry.recycling_list_entry);
+                       TRACE_DBG("tmp %p, order %d, sg_count %d", tmp,
+                               tmp->order, tmp->sg_count);
+                       if (sgv->sg_count <= tmp->sg_count)
+                               break;
+               }
+               entry = entry->prev;
+       } else
+               entry = list;
+
+       TRACE_DBG("Adding in %p (list %p)", entry, list);
+       list_add(&sgv->recycle_entry.recycling_list_entry, entry);
+
        list_add_tail(&sgv->recycle_entry.sorted_recycling_list_entry,
                &sgv_pools_mgr.mgr.sorted_recycling_list);
+
        sgv->recycle_entry.time_stamp = jiffies;
        
        sgv_pools_mgr.mgr.thr.inactive_pages_total += 1 << sgv->order;
@@ -457,7 +478,7 @@ static int sgv_pool_hiwmk_check(int pages_to_alloc, int no_fail)
 
        spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
 
-       pages += sgv_pools_mgr.mgr.thr.active_pages_total;
+       pages += atomic_read(&sgv_pools_mgr.mgr.thr.active_pages_total);
        pages += sgv_pools_mgr.mgr.thr.inactive_pages_total;
 
        if (unlikely((u32)pages > sgv_pools_mgr.mgr.thr.hi_wmk)) {
@@ -497,7 +518,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size,
        int pages_to_alloc;
        struct kmem_cache *cache;
        int no_cached = flags & SCST_POOL_ALLOC_NO_CACHED;
-       int no_fail = ((gfp_mask & __GFP_NOFAIL) == __GFP_NOFAIL);
+       bool no_fail = ((gfp_mask & __GFP_NOFAIL) == __GFP_NOFAIL);
 
        TRACE_ENTRY();
 
@@ -621,9 +642,7 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size,
        }
 
 success:
-       spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
-       sgv_pools_mgr.mgr.thr.active_pages_total += 1 << order;
-       spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
+       atomic_add(1 << order, &sgv_pools_mgr.mgr.thr.active_pages_total);
 
        if (cache) {
                int sg;
@@ -725,9 +744,7 @@ void sgv_pool_free(struct sgv_pool_obj *sgv)
                kfree(sgv);
        }
 
-       spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
-       sgv_pools_mgr.mgr.thr.active_pages_total -= pages;
-       spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
+       atomic_sub(pages, &sgv_pools_mgr.mgr.thr.active_pages_total);
        return;
 }
 
@@ -764,9 +781,7 @@ struct scatterlist *scst_alloc(int size, unsigned long gfp_mask, int *count)
        if (*count <= 0)
                goto out_free;
 
-       spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
-       sgv_pools_mgr.mgr.thr.active_pages_total += pages;
-       spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
+       atomic_add(pages, &sgv_pools_mgr.mgr.thr.active_pages_total);
 
 out:
        TRACE_MEM("Alloced sg %p (count %d)", res, *count);
@@ -784,9 +799,7 @@ void scst_free(struct scatterlist *sg, int count)
 {
        TRACE_MEM("Freeing sg=%p", sg);
 
-       spin_lock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
-       sgv_pools_mgr.mgr.thr.active_pages_total -= count;
-       spin_unlock_bh(&sgv_pools_mgr.mgr.pool_mgr_lock);
+       atomic_sub(count, &sgv_pools_mgr.mgr.thr.active_pages_total);
 
        scst_free_sys_sg_entries(sg, count, NULL);
        kfree(sg);
@@ -907,15 +920,15 @@ static void sgv_pool_evaluate_local_order(struct scst_sgv_pools_manager *pmgr)
 
        TRACE_MEM("sgv_max_local_order %d, sgv_max_trans_order %d",
                pmgr->sgv_max_local_order, pmgr->sgv_max_trans_order);
-       TRACE_MEM("max object size with embedded sgv & ttbl %d",
+       TRACE_MEM("max object size with embedded sgv & ttbl %zd",
                (1 << pmgr->sgv_max_local_order) * 
                (sizeof(struct trans_tbl_ent) + sizeof(struct scatterlist))
                + sizeof(struct sgv_pool_obj));
-       TRACE_MEM("max object size with embedded sgv (!clustered) %d",
+       TRACE_MEM("max object size with embedded sgv (!clustered) %zd",
                (1 << pmgr->sgv_max_local_order) * 
                (sizeof(struct scatterlist))
                + sizeof(struct sgv_pool_obj));
-       TRACE_MEM("max object size with embedded ttbl %d",
+       TRACE_MEM("max object size with embedded ttbl %zd",
                (1 << pmgr->sgv_max_trans_order) * sizeof(struct trans_tbl_ent) +
                sizeof(struct sgv_pool_obj));
 }
@@ -1087,6 +1100,8 @@ int scst_sgv_pools_init(unsigned long mem_hwmark, unsigned long mem_lwmark)
 
        memset(pools, 0, sizeof(*pools));
 
+       atomic_set(&sgv_pools_mgr.mgr.thr.active_pages_total, 0);
+
        sgv_pools_mgr.mgr.thr.hi_wmk = mem_hwmark >> PAGE_SHIFT;
        sgv_pools_mgr.mgr.thr.lo_wmk = mem_lwmark >> PAGE_SHIFT;
 
@@ -1234,7 +1249,7 @@ int sgv_pool_procinfo_show(struct seq_file *seq, void *v)
        seq_printf(seq, "%-42s %d/%d\n%-42s %d/%d\n%-42s %d/%d\n\n",
                "Inactive/active pages",
                sgv_pools_mgr.mgr.thr.inactive_pages_total,
-               sgv_pools_mgr.mgr.thr.active_pages_total,
+               atomic_read(&sgv_pools_mgr.mgr.thr.active_pages_total),
                "Hi/lo watermarks [pages]", sgv_pools_mgr.mgr.thr.hi_wmk,
                sgv_pools_mgr.mgr.thr.lo_wmk, "Hi watermark releases/failures",
                sgv_pools_mgr.mgr.thr.releases_on_hiwmk,
index 60d5360..752544c 100644 (file)
@@ -106,7 +106,7 @@ struct scst_sgv_pools_manager
 
                struct sgv_mem_throttling {
                        u32 inactive_pages_total; 
-                       u32 active_pages_total;
+                       atomic_t active_pages_total;
                
                        u32 hi_wmk; /* compared against inactive_pages_total + active_pages_total */
                        u32 lo_wmk; /* compared against inactive_pages_total only */
index fbdc547..286664f 100644 (file)
@@ -435,19 +435,10 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
        int res = SCST_CMD_STATE_RES_CONT_SAME;
        int state;
        struct scst_device *dev = cmd->dev;
-       int atomic = scst_cmd_atomic(cmd);
        int orig_bufflen = cmd->bufflen;
 
        TRACE_ENTRY();
 
-       if (atomic && !dev->handler->parse_atomic) {
-               TRACE_DBG("Dev handler %s parse() can not be "
-                     "called in atomic context, rescheduling to the thread",
-                     dev->handler->name);
-               res = SCST_CMD_STATE_RES_NEED_THREAD;
-               goto out;
-       }
-
        if (likely(!scst_is_cmd_local(cmd))) {
                TRACE_DBG("Calling dev handler %s parse(%p)",
                      dev->handler->name, cmd);
@@ -676,15 +667,6 @@ check:
 
 prep_done:
        if (cmd->preprocessing_only) {
-               if (scst_cmd_atomic(cmd) && 
-                   !cmd->tgtt->preprocessing_done_atomic) {
-                       TRACE_DBG("%s", "preprocessing_done() can not be "
-                             "called in atomic context, rescheduling to "
-                             "the thread");
-                       res = SCST_CMD_STATE_RES_NEED_THREAD;
-                       goto out;
-               }
-
                if (unlikely(test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags))) {
                        TRACE_MGMT_DBG("ABORTED set, returning ABORTED for "
                                "cmd %p", cmd);
@@ -741,8 +723,7 @@ void scst_restart_cmd(struct scst_cmd *cmd, int status, int pref_context)
 
 #ifdef EXTRACHECKS
        if (in_irq() && ((pref_context == SCST_CONTEXT_DIRECT) ||
-                        (pref_context == SCST_CONTEXT_DIRECT_ATOMIC)))
-       {
+                        (pref_context == SCST_CONTEXT_DIRECT_ATOMIC))) {
                PRINT_ERROR("Wrong context %d in IRQ from target %s, use "
                        "SCST_CONTEXT_TASKLET instead\n", pref_context,
                        cmd->tgtt->name);
@@ -847,7 +828,6 @@ out_unlock_tgt:
 static int scst_rdy_to_xfer(struct scst_cmd *cmd)
 {
        int res, rc;
-       int atomic = scst_cmd_atomic(cmd);
 
        TRACE_ENTRY();
 
@@ -862,13 +842,6 @@ static int scst_rdy_to_xfer(struct scst_cmd *cmd)
                goto out;
        }
 
-       if (atomic && !cmd->tgtt->rdy_to_xfer_atomic) {
-               TRACE_DBG("%s", "rdy_to_xfer() can not be "
-                     "called in atomic context, rescheduling to the thread");
-               res = SCST_CMD_STATE_RES_NEED_THREAD;
-               goto out;
-       }
-
        while (1) {
                int finished_cmds = atomic_read(&cmd->sess->tgt->finished_cmds);
 
@@ -1707,15 +1680,6 @@ static int scst_do_send_to_midlev(struct scst_cmd *cmd)
 
        TRACE_ENTRY();
 
-       /* Check here to let an out of SN cmd be queued w/o context switch */
-       if (scst_cmd_atomic(cmd) && !handler->exec_atomic) {
-               TRACE_DBG("Dev handler %s exec() can not be "
-                     "called in atomic context, rescheduling to the thread",
-                     handler->name);
-               rc = SCST_EXEC_NEED_THREAD;
-               goto out;
-       }
-
        cmd->sent_to_midlev = 1;
        cmd->state = SCST_CMD_STATE_EXECUTING;
        cmd->scst_cmd_done = scst_cmd_done_local;
@@ -1772,6 +1736,16 @@ static int scst_do_send_to_midlev(struct scst_cmd *cmd)
        if (unlikely(rc != 0))
                goto out_done;
 
+#ifndef ALLOW_PASSTHROUGH_IO_SUBMIT_IN_SIRQ
+       if (scst_cmd_atomic(cmd)) {
+               TRACE_DBG("Pass-through exec() can not be called in atomic "
+                       "context, rescheduling to the thread (handler %s)",
+                       handler->name);
+               rc = SCST_EXEC_NEED_THREAD;
+               goto out_clear;
+       }
+#endif
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)        
        if (unlikely(scst_alloc_request(cmd) != 0)) {
                if (scst_cmd_atomic(cmd)) {
@@ -2207,7 +2181,8 @@ static int scst_done_cmd_check(struct scst_cmd *cmd, int *pres)
 
        if (likely(scsi_status_is_good(cmd->status))) {
                unsigned char type = cmd->dev->handler->type;
-               if ((cmd->cdb[0] == MODE_SENSE || cmd->cdb[0] == MODE_SENSE_10) &&
+               if (unlikely((cmd->cdb[0] == MODE_SENSE ||
+                             cmd->cdb[0] == MODE_SENSE_10)) &&
                    cmd->tgt_dev->acg_dev->rd_only_flag &&
                    (type == TYPE_DISK || type == TYPE_WORM || type == TYPE_MOD ||
                     type == TYPE_TAPE)) {
@@ -2228,7 +2203,7 @@ static int scst_done_cmd_check(struct scst_cmd *cmd, int *pres)
                 * Check and clear NormACA option for the device, if necessary,
                 * since we don't support ACA
                 */
-               if ((cmd->cdb[0] == INQUIRY) &&
+               if (unlikely((cmd->cdb[0] == INQUIRY)) &&
                    !(cmd->cdb[1] & SCST_INQ_EVPD/* Std INQUIRY data (no EVPD) */) &&
                    (cmd->resp_data_len > SCST_INQ_BYTE3)) {
                        uint8_t *buffer;
@@ -2371,16 +2346,20 @@ static int scst_mode_select_checks(struct scst_cmd *cmd)
        } else if ((cmd->status == SAM_STAT_CHECK_CONDITION) && 
                    SCST_SENSE_VALID(cmd->sense) &&
                    scst_is_ua_sense(cmd->sense) &&
-                   (cmd->sense[12] == 0x2a) && (cmd->sense[13] == 0x01)) {
+                   (((cmd->sense[12] == 0x2a) && (cmd->sense[13] == 0x01)) ||
+                    (cmd->sense[12] == 0x29) /* reset */ ||
+                    (cmd->sense[12] == 0x28) /* medium changed */ ||
+                    (cmd->sense[12] == 0x2F) /* cleared by another ini (just in case) */)) {
                if (atomic) {
-                       TRACE_DBG("%s", "MODE PARAMETERS CHANGED UA: thread "
-                               "context required");
+                       TRACE_DBG("Possible parameters changed UA %x: "
+                               "thread context required", cmd->sense[12]);
                        res = SCST_CMD_STATE_RES_NEED_THREAD;
                        goto out;
                }
 
-               TRACE(TRACE_SCSI, "MODE PARAMETERS CHANGED UA (lun %Ld): "
-                       "getting new parameters", (uint64_t)cmd->lun);
+               TRACE(TRACE_SCSI, "Possible parameters changed UA %x "
+                       "(lun %Ld): getting new parameters", cmd->sense[12],
+                       (uint64_t)cmd->lun);
 
                scst_obtain_device_parameters(cmd->dev);
        } else
@@ -2405,18 +2384,9 @@ static int scst_dev_done(struct scst_cmd *cmd)
 {
        int res = SCST_CMD_STATE_RES_CONT_SAME;
        int state;
-       int atomic = scst_cmd_atomic(cmd);
 
        TRACE_ENTRY();
 
-       if (atomic && !cmd->dev->handler->dev_done_atomic) {
-               TRACE_DBG("Dev handler %s dev_done() can not be "
-                     "called in atomic context, rescheduling to the thread",
-                     cmd->dev->handler->name);
-               res = SCST_CMD_STATE_RES_NEED_THREAD;
-               goto out;
-       }
-
        state = SCST_CMD_STATE_PRE_XMIT_RESP;
        if (likely(!scst_is_cmd_local(cmd)) && 
            likely(cmd->dev->handler->dev_done != NULL))
@@ -2481,7 +2451,6 @@ static int scst_dev_done(struct scst_cmd *cmd)
        if (cmd->inc_expected_sn_on_done && cmd->sent_to_midlev)
                scst_inc_check_expected_sn(cmd);
 
-out:
        TRACE_EXIT_HRES(res);
        return res;
 }
@@ -2508,6 +2477,9 @@ static int scst_pre_xmit_response(struct scst_cmd *cmd)
        if (likely(cmd->tgt_dev != NULL)) {
                atomic_dec(&cmd->tgt_dev->tgt_dev_cmd_count);
                atomic_dec(&cmd->dev->dev_cmd_count);
+               /* If expected values not set, expected direction is UNKNOWN */
+               if (cmd->expected_data_direction == SCST_DATA_WRITE)
+                       atomic_dec(&cmd->dev->write_cmd_count);
 
                if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_HEAD_OF_QUEUE))
                        scst_on_hq_cmd_response(cmd);
@@ -2582,17 +2554,9 @@ out:
 static int scst_xmit_response(struct scst_cmd *cmd)
 {
        int res, rc;
-       int atomic = scst_cmd_atomic(cmd);
 
        TRACE_ENTRY();
 
-       if (atomic && !cmd->tgtt->xmit_response_atomic) {
-               TRACE_DBG("%s", "xmit_response() can not be "
-                     "called in atomic context, rescheduling to the thread");
-               res = SCST_CMD_STATE_RES_NEED_THREAD;
-               goto out;
-       }
-
        while (1) {
                int finished_cmds = atomic_read(&cmd->sess->tgt->finished_cmds);
 
@@ -2755,7 +2719,8 @@ static void scst_cmd_set_sn(struct scst_cmd *cmd)
        case SCST_CMD_QUEUE_UNTAGGED:
 #if 1 /* temporary, ToDo */
                if (scst_cmd_is_expected_set(cmd)) {
-                       if (cmd->expected_data_direction == SCST_DATA_READ)
+                       if ((cmd->expected_data_direction == SCST_DATA_READ) &&
+                           (atomic_read(&cmd->dev->write_cmd_count) == 0))
                                goto ordered;
                } else
                        goto ordered;
@@ -2776,7 +2741,7 @@ static void scst_cmd_set_sn(struct scst_cmd *cmd)
                        tgt_dev->prev_cmd_ordered = 0;
                } else {
                        TRACE(TRACE_MINOR, "***WARNING*** Not enough SN slots "
-                               "%d", ARRAY_SIZE(tgt_dev->sn_slots));
+                               "%zd", ARRAY_SIZE(tgt_dev->sn_slots));
                        goto ordered;
                }
                break;
@@ -2917,23 +2882,38 @@ static int __scst_init_cmd(struct scst_cmd *cmd)
        res = scst_translate_lun(cmd);
        if (likely(res == 0)) {
                int cnt;
+               bool failure = false;
+
                cmd->state = SCST_CMD_STATE_PRE_PARSE;
+
                cnt = atomic_inc_return(&cmd->tgt_dev->tgt_dev_cmd_count);
                if (unlikely(cnt > SCST_MAX_TGT_DEV_COMMANDS)) {
                        TRACE(TRACE_MGMT_MINOR, "Too many pending commands (%d) in "
                                "session, returning BUSY to initiator \"%s\"",
                                cnt, (cmd->sess->initiator_name[0] == '\0') ?
                                  "Anonymous" : cmd->sess->initiator_name);
-                       goto out_busy;
+                       failure = true;
                }
+
                cnt = atomic_inc_return(&cmd->dev->dev_cmd_count);
                if (unlikely(cnt > SCST_MAX_DEV_COMMANDS)) {
-                       TRACE(TRACE_MGMT_MINOR, "Too many pending device commands "
-                               "(%d), returning BUSY to initiator \"%s\"",
-                               cnt, (cmd->sess->initiator_name[0] == '\0') ?
-                                 "Anonymous" : cmd->sess->initiator_name);
-                       goto out_busy;
+                       if (!failure) {
+                               TRACE(TRACE_MGMT_MINOR, "Too many pending device "
+                                       "commands (%d), returning BUSY to "
+                                       "initiator \"%s\"", cnt,
+                                       (cmd->sess->initiator_name[0] == '\0') ?
+                                         "Anonymous" : cmd->sess->initiator_name);
+                               failure = true;
+                       }
                }
+
+               /* If expected values not set, expected direction is UNKNOWN */
+               if (cmd->expected_data_direction == SCST_DATA_WRITE)
+                       atomic_inc(&cmd->dev->write_cmd_count);
+
+               if (unlikely(failure))
+                       goto out_busy;
+
                if (!cmd->set_sn_on_restart_cmd)
                        scst_cmd_set_sn(cmd);
        } else if (res < 0) {
index c77e844..5ac27e5 100644 (file)
@@ -41,10 +41,10 @@ CFLAGS += -DDEBUG -g
 all: $(PROGS)
 
 fileio_tgt: .depend_f $(OBJS_F)
-       $(CC) $(OBJS_F) $(LIBS) -o $@
+       $(CC) $(OBJS_F) $(LIBS) $(LOCAL_LD_FLAGS) -o $@
 
 #cdrom_tgt: .depend_c  $(OBJS_C)
-#      $(CC) $(OBJS_C) $(LIBS) -o $@
+#      $(CC) $(OBJS_C) $(LIBS) $(LOCAL_LD_FLAGS) -o $@
 
 ifeq (.depend_f,$(wildcard .depend_f))
 -include .depend_f
index 53b231d..b74ebc2 100644 (file)
@@ -23,6 +23,7 @@
 #include <unistd.h>
 #include <stdint.h>
 #include <getopt.h>
+#include <inttypes.h>
 
 #include <sys/ioctl.h>
 #include <sys/poll.h>
@@ -224,7 +225,8 @@ static int do_exec(struct vdisk_cmd *vcmd)
                else
 #endif
                        cmd->pbuf = (unsigned long)dev->alloc_fn(cmd->alloc_len);
-               TRACE_MEM("Buf %Lx alloced, len %d", cmd->pbuf, cmd->alloc_len);
+               TRACE_MEM("Buf %"PRIx64" alloced, len %d", cmd->pbuf,
+                       cmd->alloc_len);
                reply->pbuf = cmd->pbuf;
                if (cmd->pbuf == 0) {
                        TRACE(TRACE_OUT_OF_MEM, "Unable to allocate buffer "
@@ -286,12 +288,12 @@ static int do_exec(struct vdisk_cmd *vcmd)
        }
 
        loff = (loff_t)lba_start << dev->block_shift;
-       TRACE_DBG("cmd %d, buf %Lx, lba_start %Ld, loff %Ld, data_len %Ld",
-               vcmd->cmd->cmd_h, cmd->pbuf, lba_start, (uint64_t)loff,
-               (uint64_t)data_len);
+       TRACE_DBG("cmd %d, buf %"PRIx64", lba_start %"PRId64", loff %"PRId64
+               ", data_len %"PRId64, vcmd->cmd->cmd_h, cmd->pbuf, lba_start,
+               (uint64_t)loff, (uint64_t)data_len);
        if ((loff < 0) || (data_len < 0) || ((loff + data_len) > dev->file_size)) {
                PRINT_INFO("Access beyond the end of the device "
-                       "(%lld of %lld, len %Ld)", (uint64_t)loff, 
+                       "(%"PRId64" of %"PRId64", len %"PRId64")", (uint64_t)loff,
                        (uint64_t)dev->file_size, (uint64_t)data_len);
                set_cmd_error(vcmd, SCST_LOAD_SENSE(
                                scst_sense_block_out_range_error));
@@ -304,8 +306,8 @@ static int do_exec(struct vdisk_cmd *vcmd)
        case WRITE_16:
                fua = (cdb[1] & 0x8);
                if (cdb[1] & 0x8) {
-                       TRACE(TRACE_ORDER, "FUA(%d): loff=%Ld, "
-                               "data_len=%Ld", fua, (uint64_t)loff,
+                       TRACE(TRACE_ORDER, "FUA(%d): loff=%"PRId64", "
+                               "data_len=%"PRId64, fua, (uint64_t)loff,
                                (uint64_t)data_len);
                }
                break;
@@ -329,7 +331,7 @@ static int do_exec(struct vdisk_cmd *vcmd)
 
                        tgt_dev = find_tgt_dev(dev, cmd->sess_h);
                        if (tgt_dev == NULL) {
-                               PRINT_ERROR("Session %Lx not found",
+                               PRINT_ERROR("Session %"PRIx64" not found",
                                        cmd->sess_h);
                                set_cmd_error(vcmd,
                                    SCST_LOAD_SENSE(scst_sense_hardw_error));
@@ -340,8 +342,8 @@ static int do_exec(struct vdisk_cmd *vcmd)
                        tgt_dev->last_write_cmd_queue_type = cmd->queue_type;
                        if (need_pre_sync(cmd->queue_type, last_queue_type)) {
                                TRACE(TRACE_ORDER, "ORDERED "
-                                       "WRITE(%d): loff=%Ld, data_len=%Ld",
-                                       cmd->queue_type, (uint64_t)loff,
+                                       "WRITE(%d): loff=%"PRId64", data_len=%"
+                                       PRId64, cmd->queue_type, (uint64_t)loff,
                                        (uint64_t)data_len);
                                do_fsync = 1;
                                if (exec_fsync(vcmd) != 0)
@@ -368,7 +370,7 @@ static int do_exec(struct vdisk_cmd *vcmd)
 
                        tgt_dev = find_tgt_dev(dev, cmd->sess_h);
                        if (tgt_dev == NULL) {
-                               PRINT_ERROR("Session %Lx not found",
+                               PRINT_ERROR("Session %"PRIx64" not found",
                                        cmd->sess_h);
                                set_cmd_error(vcmd,
                                    SCST_LOAD_SENSE(scst_sense_hardw_error));
@@ -379,9 +381,9 @@ static int do_exec(struct vdisk_cmd *vcmd)
                        tgt_dev->last_write_cmd_queue_type = cmd->queue_type;
                        if (need_pre_sync(cmd->queue_type, last_queue_type)) {
                                TRACE(TRACE_ORDER, "ORDERED "
-                                       "WRITE_VERIFY(%d): loff=%Ld, data_len=%Ld",
-                                       cmd->queue_type, (uint64_t)loff,
-                                       (uint64_t)data_len);
+                                       "WRITE_VERIFY(%d): loff=%"PRId64", "
+                                       "data_len=%"PRId64, cmd->queue_type,
+                                       (uint64_t)loff, (uint64_t)data_len);
                                do_fsync = 1;
                                if (exec_fsync(vcmd) != 0)
                                        goto out;
@@ -403,8 +405,8 @@ static int do_exec(struct vdisk_cmd *vcmd)
        {
                int immed = cdb[1] & 0x2;
                TRACE(TRACE_ORDER, "SYNCHRONIZE_CACHE: "
-                       "loff=%Ld, data_len=%Ld, immed=%d", (uint64_t)loff,
-                       (uint64_t)data_len, immed);
+                       "loff=%"PRId64", data_len=%"PRId64", immed=%d",
+                       (uint64_t)loff, (uint64_t)data_len, immed);
                if (immed) {
                        /* ToDo: backgroung exec */
                        exec_fsync(vcmd);
@@ -478,7 +480,7 @@ static int do_alloc_mem(struct vdisk_cmd *vcmd)
 
        TRACE_ENTRY();
 
-       TRACE_MEM("Alloc mem (cmd %d, sess_h %Lx, cdb_len %d, "
+       TRACE_MEM("Alloc mem (cmd %d, sess_h %"PRIx64", cdb_len %d, "
                "alloc_len %d, queue_type %d, data_direction %d)", cmd->cmd_h,
                cmd->alloc_cmd.sess_h, cmd->alloc_cmd.cdb_len,
                cmd->alloc_cmd.alloc_len, cmd->alloc_cmd.queue_type,
@@ -497,7 +499,7 @@ static int do_alloc_mem(struct vdisk_cmd *vcmd)
 #endif
                reply->alloc_reply.pbuf = (unsigned long)vcmd->dev->alloc_fn(
                                                cmd->alloc_cmd.alloc_len);
-       TRACE_MEM("Buf %Lx alloced, len %d", reply->alloc_reply.pbuf,
+       TRACE_MEM("Buf %"PRIx64" alloced, len %d", reply->alloc_reply.pbuf,
                cmd->alloc_cmd.alloc_len);
        if (reply->alloc_reply.pbuf == 0) {
                TRACE(TRACE_OUT_OF_MEM, "Unable to allocate buffer (len %d)",
@@ -516,7 +518,7 @@ static int do_cached_mem_free(struct vdisk_cmd *vcmd)
 
        TRACE_ENTRY();
 
-       TRACE_MEM("Cached mem free (cmd %d, buf %Lx)", cmd->cmd_h,
+       TRACE_MEM("Cached mem free (cmd %d, buf %"PRIx64")", cmd->cmd_h,
                cmd->on_cached_mem_free.pbuf);
 
        free((void*)(unsigned long)cmd->on_cached_mem_free.pbuf);
@@ -542,11 +544,12 @@ static int do_on_free_cmd(struct vdisk_cmd *vcmd)
                cmd->on_free_cmd.resp_data_len, cmd->on_free_cmd.aborted,
                cmd->on_free_cmd.status, cmd->on_free_cmd.delivery_status);
 
-       TRACE_MEM("On free cmd (cmd %d, buf %Lx, buffer_cached %d)", cmd->cmd_h,
-               cmd->on_free_cmd.pbuf, cmd->on_free_cmd.buffer_cached);
+       TRACE_MEM("On free cmd (cmd %d, buf %"PRIx64", buffer_cached %d)",
+               cmd->cmd_h, cmd->on_free_cmd.pbuf,
+               cmd->on_free_cmd.buffer_cached);
 
        if (!cmd->on_free_cmd.buffer_cached && (cmd->on_free_cmd.pbuf != 0)) {
-               TRACE_MEM("Freeing buf %Lx", cmd->on_free_cmd.pbuf);
+               TRACE_MEM("Freeing buf %"PRIx64, cmd->on_free_cmd.pbuf);
                free((void*)(unsigned long)cmd->on_free_cmd.pbuf);
        }
 
@@ -567,7 +570,7 @@ static int do_tm(struct vdisk_cmd *vcmd)
        TRACE_ENTRY();
 
        TRACE((cmd->tm_cmd.fn == SCST_ABORT_TASK) ? TRACE_MGMT_MINOR : TRACE_MGMT,
-               "TM fn %d (sess_h %Lx, cmd_h_to_abort %d)", cmd->tm_cmd.fn,
+               "TM fn %d (sess_h %"PRIx64", cmd_h_to_abort %d)", cmd->tm_cmd.fn,
                cmd->tm_cmd.sess_h, cmd->tm_cmd.cmd_h_to_abort);
 
        memset(reply, 0, sizeof(*reply));
@@ -597,7 +600,7 @@ static int do_sess(struct vdisk_cmd *vcmd)
 
        if (cmd->subcode == SCST_USER_ATTACH_SESS) {
                if (tgt_dev != NULL) {
-                       PRINT_ERROR("Session %Lx already exists)",
+                       PRINT_ERROR("Session %"PRIx64" already exists)",
                                cmd->sess.sess_h);
                        res = EEXIST;
                        goto reply;
@@ -605,8 +608,8 @@ static int do_sess(struct vdisk_cmd *vcmd)
 
                tgt_dev = find_empty_tgt_dev(vcmd->dev);
                if (tgt_dev == NULL) {
-                       PRINT_ERROR("Too many initiators, session %Lx refused)",
-                               cmd->sess.sess_h);
+                       PRINT_ERROR("Too many initiators, session %"PRIx64
+                               " refused)", cmd->sess.sess_h);
                        res = ENOMEM;
                        goto reply;
                }
@@ -614,19 +617,21 @@ static int do_sess(struct vdisk_cmd *vcmd)
                tgt_dev->sess_h = cmd->sess.sess_h;
                tgt_dev->last_write_cmd_queue_type = SCST_CMD_QUEUE_SIMPLE;
 
-               PRINT_INFO("Session from initiator %s attached (LUN %Lx, "
-                       "threads_num %d, rd_only %d, sess_h %Lx)",
+               PRINT_INFO("Session from initiator %s attached (LUN %"PRIx64", "
+                       "threads_num %d, rd_only %d, sess_h %"PRIx64")",
                        cmd->sess.initiator_name, cmd->sess.lun,
                        cmd->sess.threads_num, cmd->sess.rd_only,
                        cmd->sess.sess_h);
        } else {
                if (tgt_dev == NULL) {
-                       PRINT_ERROR("Session %Lx not found)", cmd->sess.sess_h);
+                       PRINT_ERROR("Session %"PRIx64" not found)",
+                               cmd->sess.sess_h);
                        res = ESRCH;
                        goto reply;
                }
                tgt_dev->sess_h = 0;
-               PRINT_INFO("Session detached (sess_h %Lx)", cmd->sess.sess_h);
+               PRINT_INFO("Session detached (sess_h %"PRIx64")",
+                       cmd->sess.sess_h);
        }
 
 reply:
@@ -824,7 +829,7 @@ out:
        PRINT_INFO("Thread %d exiting (res=%d)", gettid(), res);
 
        TRACE_EXIT_RES(res);
-       return (void*)res;
+       return (void*)(long)res;
 }
 
 void *prio_loop(void *arg)
@@ -896,7 +901,7 @@ out_close:
        PRINT_INFO("Prio thread %d exited (res=%d)", gettid(), res);
 
        TRACE_EXIT_RES(res);
-       return (void*)res;
+       return (void*)(long)res;
 }
 
 static void exec_inquiry(struct vdisk_cmd *vcmd)
@@ -1579,15 +1584,16 @@ static void exec_read(struct vdisk_cmd *vcmd, loff_t loff)
 
        TRACE_ENTRY();
        
-       TRACE_DBG("reading off %lld, len %d", loff, length);
+       TRACE_DBG("reading off %"PRId64", len %d", loff, length);
        if (dev->nullio)
                err = length;
        else {
                /* SEEK */      
                err = lseek64(fd, loff, 0/*SEEK_SET*/);
                if (err != loff) {
-                       PRINT_ERROR("lseek trouble %Ld != %Ld (errno %d)",
-                               (uint64_t)err, (uint64_t)loff, errno);
+                       PRINT_ERROR("lseek trouble %"PRId64" != %"PRId64
+                               " (errno %d)", (uint64_t)err, (uint64_t)loff,
+                               errno);
                        set_cmd_error(vcmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
                        goto out;
                }
@@ -1596,7 +1602,7 @@ static void exec_read(struct vdisk_cmd *vcmd, loff_t loff)
        }
 
        if ((err < 0) || (err < length)) {
-               PRINT_ERROR("read() returned %Ld from %d (errno %d)",
+               PRINT_ERROR("read() returned %"PRId64" from %d (errno %d)",
                        (uint64_t)err, length, errno);
                if (err == -EAGAIN)
                        set_busy(reply);
@@ -1627,7 +1633,7 @@ static void exec_write(struct vdisk_cmd *vcmd, loff_t loff)
        TRACE_ENTRY();
 
 restart:
-       TRACE_DBG("writing off %lld, len %d", loff, length);
+       TRACE_DBG("writing off %"PRId64", len %d", loff, length);
 
        if (dev->nullio)
                err = length;
@@ -1635,8 +1641,9 @@ restart:
                /* SEEK */
                err = lseek64(fd, loff, 0/*SEEK_SET*/);
                if (err != loff) {
-                       PRINT_ERROR("lseek trouble %Ld != %Ld (errno %d)",
-                               (uint64_t)err, (uint64_t)loff, errno);
+                       PRINT_ERROR("lseek trouble %"PRId64" != %"PRId64
+                               " (errno %d)", (uint64_t)err, (uint64_t)loff,
+                               errno);
                        set_cmd_error(vcmd,
                            SCST_LOAD_SENSE(scst_sense_hardw_error));
                        goto out;
@@ -1647,8 +1654,8 @@ restart:
        }
 
        if (err < 0) {
-               PRINT_ERROR("write() returned %Ld from %zd (errno %d, cmd_h "
-                       "%x)", (uint64_t)err, length, errno, vcmd->cmd->cmd_h);
+               PRINT_ERROR("write() returned %"PRId64" from %d (errno %d, "
+                       "cmd_h %x)", err, length, errno, vcmd->cmd->cmd_h);
                if (err == -EAGAIN)
                        set_busy(reply);
                else {
@@ -1704,8 +1711,9 @@ static void exec_verify(struct vdisk_cmd *vcmd, loff_t loff)
        if (!dev->nullio) {
                err = lseek64(fd, loff, 0/*SEEK_SET*/);
                if (err != loff) {
-                       PRINT_ERROR("lseek trouble %Ld != %Ld (errno %d)",
-                               (uint64_t)err, (uint64_t)loff, errno);
+                       PRINT_ERROR("lseek trouble %"PRId64" != %"PRId64
+                               " (errno %d)", (uint64_t)err,
+                               (uint64_t)loff, errno);
                        set_cmd_error(vcmd, SCST_LOAD_SENSE(scst_sense_hardw_error));
                        goto out;
                }
@@ -1727,8 +1735,8 @@ static void exec_verify(struct vdisk_cmd *vcmd, loff_t loff)
                else
                        err = len_mem;
                if ((err < 0) || (err < len_mem)) {
-                       PRINT_ERROR("read() returned %Ld from %d (errno %d)",
-                               (uint64_t)err, len_mem, errno);
+                       PRINT_ERROR("read() returned %"PRId64" from %d "
+                               "(errno %d)", (uint64_t)err, len_mem, errno);
                        if (err == -EAGAIN)
                                set_busy(reply);
                        else {
@@ -1738,7 +1746,7 @@ static void exec_verify(struct vdisk_cmd *vcmd, loff_t loff)
                        goto out;
                }
                if (compare && memcmp(address, mem_verify, len_mem) != 0) {
-                       TRACE_DBG("Verify: error memcmp length %zd", length);
+                       TRACE_DBG("Verify: error memcmp length %d", length);
                        set_cmd_error(vcmd,
                            SCST_LOAD_SENSE(scst_sense_miscompare_error));
                        goto out;
index 6ed7b5c..e2bff76 100644 (file)
@@ -24,6 +24,7 @@
 #include <stdint.h>
 #include <getopt.h>
 #include <malloc.h>
+#include <inttypes.h>
 
 #include <sys/types.h>
 #include <sys/user.h>
@@ -287,9 +288,10 @@ int main(int argc, char **argv)
 
        close(fd);
 
-       PRINT_INFO("Virtual device \"%s\", path \"%s\", size %LdMb, "
-               "block size %d, nblocks %Ld, options:", dev.name, dev.file_name,
-               dev.file_size/1024/1024, dev.block_size, dev.nblocks);
+       PRINT_INFO("Virtual device \"%s\", path \"%s\", size %"PRId64"Mb, "
+               "block size %d, nblocks %"PRId64", options:", dev.name,
+               dev.file_name, (uint64_t)dev.file_size/1024/1024,
+               dev.block_size, (uint64_t)dev.nblocks);
        if (dev.rd_only_flag)
                PRINT_INFO("    %s", "READ ONLY");
        if (dev.wt_flag)
@@ -467,8 +469,9 @@ int main(int argc, char **argv)
                                PRINT_ERROR("pthread_join() failed: %s",
                                        strerror(res));
                        } else if (rc1 != NULL) {
-                               res = (int)rc1;
-                               PRINT_INFO("Thread %d exited, res %x", i, res);
+                               res = (long)rc1;
+                               PRINT_INFO("Thread %d exited, res %lx", i,
+                                       (long)rc1);
                        } else
                                PRINT_INFO("Thread %d exited", i);
                }
@@ -479,8 +482,9 @@ int main(int argc, char **argv)
                                PRINT_ERROR("Prio pthread_join() failed: %s",
                                        strerror(res));
                        } else if (rc1 != NULL) {
-                               res = (int)rc1;
-                               PRINT_INFO("Prio thread %d exited, res %x", i, res);
+                               res = (long)rc1;
+                               PRINT_INFO("Prio thread %d exited, res %lx", i,
+                                       (long)rc1);
                        } else
                                PRINT_INFO("Prio thread %d exited", i);
                }