The bunch of pending changes. Sorry, it's quite big.

- "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: http://svn.code.sf.net/p/scst/svn/trunk@350 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2008-04-22 10:30:53 +00:00
parent 56382c20ac
commit 925fbcdda3
29 changed files with 379 additions and 302 deletions
+13 -1
View 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
-----------------------------------------------------------
+2
View 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
+1 -1
View 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 {
+5 -5
View 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);
+3 -4
View 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);
+14 -15
View 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,
+32 -25
View 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,
+5 -7
View 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);
}
}
+2 -2
View 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
+18 -6
View 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));
+19 -8
View 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,
+1 -1
View 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);
+3 -10
View 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
+21 -17
View 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->tgt_resp_flags;
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->is_send_status;
}
/*
+1 -1
View 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
*/
+1 -1
View 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
*/
+1 -1
View 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
*/
+2 -2
View 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;
+21 -8
View 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);
+17 -7
View 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)
+1 -1
View 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",
+38 -25
View 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",
-3
View 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;
+40 -25
View File
@@ -35,11 +35,10 @@
#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,
+1 -1
View 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 */
+50 -70
View 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) {
+2 -2
View 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
+54 -46
View 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;
+11 -7
View 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);
}