mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-18 19:21:26 +00:00
- Fixes scst_user brokennesses in various modes, especially in iSCSI-SCST
- Minor debug logging fixes - Minor cleanups git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@336 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -106,9 +106,9 @@ static u32 digest_header(struct iscsi_pdu *pdu)
|
||||
return evaluate_crc32_from_sg(sg, nbytes, 0);
|
||||
}
|
||||
|
||||
static u32 digest_data(struct iscsi_cmnd *req, u32 osize, u32 offset)
|
||||
static u32 digest_data(struct iscsi_cmnd *cmd, u32 osize, u32 offset)
|
||||
{
|
||||
struct scatterlist *sg = req->sg;
|
||||
struct scatterlist *sg = cmd->sg;
|
||||
int idx, count;
|
||||
struct scatterlist saved_sg;
|
||||
u32 size = (osize + 3) & ~3;
|
||||
@@ -119,7 +119,10 @@ static u32 digest_data(struct iscsi_cmnd *req, u32 osize, u32 offset)
|
||||
offset &= ~PAGE_MASK;
|
||||
|
||||
count = get_pgcnt(size, offset);
|
||||
sBUG_ON(idx + count > get_pgcnt(req->bufflen, 0));
|
||||
|
||||
TRACE_DBG("req %p, idx %d, count %d, sg_cnt %d, size %d, "
|
||||
"offset %d", cmd, idx, count, cmd->sg_cnt, size, offset);
|
||||
sBUG_ON(idx + count > cmd->sg_cnt);
|
||||
sBUG_ON(count > ISCSI_CONN_IOV_MAX);
|
||||
|
||||
saved_sg = sg[idx];
|
||||
|
||||
@@ -567,12 +567,13 @@ static void iscsi_set_datasize(struct iscsi_cmnd *cmnd, u32 offset, u32 size)
|
||||
{
|
||||
cmnd->pdu.datasize = size;
|
||||
|
||||
if (cmnd->pdu.datasize & 3) {
|
||||
int idx = (offset + cmnd->pdu.datasize) >> PAGE_SHIFT;
|
||||
u8 *p = (u8 *)page_address(sg_page(&cmnd->sg[idx])) +
|
||||
((offset + cmnd->pdu.datasize) & ~PAGE_MASK);
|
||||
int i = 4 - (cmnd->pdu.datasize & 3);
|
||||
while (i--)
|
||||
if (size & 3) {
|
||||
u32 last_off = offset + size;
|
||||
int idx = last_off >> PAGE_SHIFT;
|
||||
u8 *p = (u8*)page_address(sg_page(&cmnd->sg[idx])) +
|
||||
(last_off & ~PAGE_MASK);
|
||||
int i = 4 - (size & 3);
|
||||
while(i--)
|
||||
*p++ = 0;
|
||||
}
|
||||
}
|
||||
@@ -586,16 +587,18 @@ static void send_data_rsp(struct iscsi_cmnd *req, u8 status, int send_status)
|
||||
LIST_HEAD(send);
|
||||
|
||||
TRACE_DBG("req %p", req);
|
||||
|
||||
pdusize = req->conn->session->sess_param.max_xmit_data_length;
|
||||
expsize = cmnd_read_size(req);
|
||||
size = min(expsize, (u32)req->bufflen);
|
||||
offset = 0;
|
||||
sn = 0;
|
||||
|
||||
while (1) {
|
||||
while(1) {
|
||||
rsp = iscsi_cmnd_create_rsp_cmnd(req);
|
||||
TRACE_DBG("rsp %p", rsp);
|
||||
rsp->sg = req->sg;
|
||||
rsp->sg_cnt = req->sg_cnt;
|
||||
rsp->bufflen = req->bufflen;
|
||||
rsp_hdr = (struct iscsi_data_in_hdr *)&rsp->pdu.bhs;
|
||||
|
||||
@@ -606,6 +609,7 @@ static void send_data_rsp(struct iscsi_cmnd *req, u8 status, int send_status)
|
||||
rsp_hdr->data_sn = cpu_to_be32(sn);
|
||||
|
||||
if (size <= pdusize) {
|
||||
TRACE_DBG("offset %d, size %d", offset, size);
|
||||
iscsi_set_datasize(rsp, offset, size);
|
||||
if (send_status) {
|
||||
TRACE_DBG("status %x", status);
|
||||
@@ -627,6 +631,9 @@ static void send_data_rsp(struct iscsi_cmnd *req, u8 status, int send_status)
|
||||
break;
|
||||
}
|
||||
|
||||
TRACE_DBG("pdusize %d, offset %d, size %d", pdusize, offset,
|
||||
size);
|
||||
|
||||
iscsi_set_datasize(rsp, offset, pdusize);
|
||||
|
||||
size -= pdusize;
|
||||
@@ -1369,6 +1376,7 @@ static int scsi_cmnd_start(struct iscsi_cmnd *req)
|
||||
}
|
||||
req->target_task_tag = get_next_ttt(conn);
|
||||
req->sg = scst_cmd_get_sg(scst_cmd);
|
||||
req->sg_cnt = scst_cmd_get_sg_cnt(scst_cmd);
|
||||
req->bufflen = scst_cmd_get_bufflen(scst_cmd);
|
||||
if (unlikely(req->r2t_length > req->bufflen)) {
|
||||
PRINT_ERROR("req->r2t_length %d > req->bufflen %d",
|
||||
@@ -1903,10 +1911,12 @@ static void noop_out_exec(struct iscsi_cmnd *req)
|
||||
|
||||
if (req->sg) {
|
||||
rsp->sg = req->sg;
|
||||
rsp->sg_cnt = req->sg_cnt;
|
||||
rsp->bufflen = req->bufflen;
|
||||
}
|
||||
|
||||
sBUG_ON(get_pgcnt(req->pdu.datasize, 0) > ISCSI_CONN_IOV_MAX);
|
||||
|
||||
rsp->pdu.datasize = req->pdu.datasize;
|
||||
iscsi_cmnd_init_write(rsp,
|
||||
ISCSI_INIT_WRITE_REMOVE_HASH | ISCSI_INIT_WRITE_WAKE);
|
||||
@@ -2529,9 +2539,11 @@ static int iscsi_xmit_response(struct scst_cmd *scst_cmd)
|
||||
|
||||
req->bufflen = scst_cmd_get_resp_data_len(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,
|
||||
resp_flags, req->bufflen, req->sg);
|
||||
TRACE_DBG("req %p, resp_flags=%x, req->bufflen=%d, req->sg=%p, "
|
||||
"req->sg_cnt %d", req, resp_flags, req->bufflen, req->sg,
|
||||
req->sg_cnt);
|
||||
|
||||
if (unlikely((req->bufflen != 0) &&
|
||||
!(resp_flags & SCST_TSC_FLAG_STATUS))) {
|
||||
|
||||
@@ -302,6 +302,7 @@ struct iscsi_cmnd {
|
||||
struct iscsi_pdu pdu;
|
||||
|
||||
struct scatterlist *sg;
|
||||
int sg_cnt;
|
||||
int bufflen;
|
||||
u32 r2t_sn;
|
||||
u32 r2t_length;
|
||||
@@ -312,7 +313,6 @@ struct iscsi_cmnd {
|
||||
u32 hdigest;
|
||||
u32 ddigest;
|
||||
|
||||
int sg_cnt; /* valid only if own_sg is 1 */
|
||||
struct list_head cmd_list_entry;
|
||||
};
|
||||
|
||||
|
||||
@@ -90,14 +90,12 @@ again:
|
||||
sBUG_ON(cmnd->parent_req != NULL);
|
||||
|
||||
if (cmnd->sg != NULL) {
|
||||
int sg_cnt, i;
|
||||
|
||||
sg_cnt = get_pgcnt(cmnd->bufflen,
|
||||
cmnd->sg[0].offset);
|
||||
int i;
|
||||
|
||||
if (cmnd_get_check(cmnd))
|
||||
continue;
|
||||
for(i = 0; i < sg_cnt; i++) {
|
||||
|
||||
for(i = 0; i < cmnd->sg_cnt; i++) {
|
||||
struct page *page = sg_page(&cmnd->sg[i]);
|
||||
TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, "
|
||||
"_count %d", page, page->net_priv,
|
||||
@@ -125,15 +123,12 @@ again:
|
||||
atomic_read(&rsp->net_ref_cnt), rsp->sg);
|
||||
|
||||
if ((rsp->sg != cmnd->sg) && (rsp->sg != NULL)) {
|
||||
int sg_cnt, i;
|
||||
|
||||
sg_cnt = get_pgcnt(rsp->bufflen,
|
||||
rsp->sg[0].offset);
|
||||
sBUG_ON(rsp->sg_cnt != sg_cnt);
|
||||
int i;
|
||||
|
||||
if (cmnd_get_check(rsp))
|
||||
continue;
|
||||
for(i = 0; i < sg_cnt; i++) {
|
||||
|
||||
for(i = 0; i < rsp->sg_cnt; i++) {
|
||||
struct page *page = sg_page(&rsp->sg[i]);
|
||||
TRACE_CONN_CLOSE_DBG(" page %p, net_priv %p, "
|
||||
"_count %d", page, page->net_priv,
|
||||
@@ -383,10 +378,8 @@ static void close_conn(struct iscsi_conn *conn)
|
||||
TRACE_CONN_CLOSE_DBG("net_ref_cnt %d, sg %p",
|
||||
atomic_read(&cmnd->net_ref_cnt), cmnd->sg);
|
||||
if (cmnd->sg != NULL) {
|
||||
int sg_cnt, i;
|
||||
sg_cnt = get_pgcnt(cmnd->bufflen,
|
||||
cmnd->sg[0].offset);
|
||||
for(i = 0; i < sg_cnt; i++) {
|
||||
int i;
|
||||
for(i = 0; i < cmnd->sg_cnt; i++) {
|
||||
struct page *page = sg_page(&cmnd->sg[i]);
|
||||
TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, _count %d",
|
||||
page, page->net_priv,
|
||||
@@ -402,11 +395,8 @@ static void close_conn(struct iscsi_conn *conn)
|
||||
"sg %p", rsp, atomic_read(&rsp->ref_cnt),
|
||||
atomic_read(&rsp->net_ref_cnt), rsp->sg);
|
||||
if ((rsp->sg != cmnd->sg) && (rsp->sg != NULL)) {
|
||||
int sg_cnt, i;
|
||||
sg_cnt = get_pgcnt(rsp->bufflen,
|
||||
rsp->sg[0].offset);
|
||||
sBUG_ON(rsp->sg_cnt != sg_cnt);
|
||||
for(i = 0; i < sg_cnt; i++) {
|
||||
int i;
|
||||
for(i = 0; i < rsp->sg_cnt; i++) {
|
||||
TRACE_CONN_CLOSE_DBG(" page %p, net_priv %p, "
|
||||
"_count %d", sg_page(&rsp->sg[i]),
|
||||
sg_page(&rsp->sg[i])->net_priv,
|
||||
@@ -858,45 +848,62 @@ int istrd(void *arg)
|
||||
}
|
||||
|
||||
#ifdef NET_PAGE_CALLBACKS_DEFINED
|
||||
void iscsi_get_page_callback(struct page *page)
|
||||
static inline void __iscsi_get_page_callback(struct iscsi_cmnd *cmd)
|
||||
{
|
||||
struct iscsi_cmnd *cmd = (struct iscsi_cmnd*)page->net_priv;
|
||||
int v;
|
||||
|
||||
TRACE_NET_PAGE("cmd %p, page %p, _count %d, new net_ref_cnt %d",
|
||||
cmd, page, atomic_read(&page->_count),
|
||||
atomic_read(&cmd->net_ref_cnt)+1);
|
||||
TRACE_NET_PAGE("cmd %p, new net_ref_cnt %d",
|
||||
cmd, atomic_read(&cmd->net_ref_cnt)+1);
|
||||
|
||||
v = atomic_inc_return(&cmd->net_ref_cnt);
|
||||
if (v == 1) {
|
||||
TRACE_NET_PAGE("getting cmd %p for page %p", cmd, page);
|
||||
TRACE_NET_PAGE("getting cmd %p", cmd);
|
||||
cmnd_get(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void iscsi_get_page_callback(struct page *page)
|
||||
{
|
||||
struct iscsi_cmnd *cmd = (struct iscsi_cmnd*)page->net_priv;
|
||||
|
||||
TRACE_NET_PAGE("page %p, _count %d", page,
|
||||
atomic_read(&page->_count));
|
||||
|
||||
__iscsi_get_page_callback(cmd);
|
||||
}
|
||||
|
||||
static inline void __iscsi_put_page_callback(struct iscsi_cmnd *cmd)
|
||||
{
|
||||
TRACE_NET_PAGE("cmd %p, new net_ref_cnt %d", cmd,
|
||||
atomic_read(&cmd->net_ref_cnt)-1);
|
||||
|
||||
if (atomic_dec_and_test(&cmd->net_ref_cnt)) {
|
||||
int i, sg_cnt = cmd->sg_cnt;
|
||||
for(i = 0; i < sg_cnt; i++) {
|
||||
struct page *page = sg_page(&cmd->sg[i]);
|
||||
TRACE_NET_PAGE("Clearing page %p", page);
|
||||
if (page->net_priv == cmd)
|
||||
page->net_priv = NULL;
|
||||
}
|
||||
cmnd_put(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void iscsi_put_page_callback(struct page *page)
|
||||
{
|
||||
struct iscsi_cmnd *cmd = (struct iscsi_cmnd*)page->net_priv;
|
||||
|
||||
TRACE_NET_PAGE("cmd %p, page %p, _count %d, new net_ref_cnt %d",
|
||||
cmd, page, atomic_read(&page->_count),
|
||||
atomic_read(&cmd->net_ref_cnt)-1);
|
||||
TRACE_NET_PAGE("page %p, _count %d", page,
|
||||
atomic_read(&page->_count));
|
||||
|
||||
if (atomic_dec_and_test(&cmd->net_ref_cnt)) {
|
||||
int i, sg_cnt = get_pgcnt(cmd->bufflen, cmd->sg[0].offset);
|
||||
for(i = 0; i < sg_cnt; i++) {
|
||||
TRACE_NET_PAGE("Clearing page %p", sg_page(&cmd->sg[i]));
|
||||
sg_page(&cmd->sg[i])->net_priv = NULL;
|
||||
}
|
||||
cmnd_put(cmd);
|
||||
}
|
||||
__iscsi_put_page_callback(cmd);
|
||||
}
|
||||
|
||||
static void check_net_priv(struct iscsi_cmnd *cmd, struct page *page)
|
||||
{
|
||||
if (atomic_read(&cmd->net_ref_cnt) == 0) {
|
||||
TRACE_DBG("%s", "sendpage() not called get_page(), "
|
||||
"zeroing net_priv");
|
||||
if ((atomic_read(&cmd->net_ref_cnt) == 1) && (page->net_priv == cmd)) {
|
||||
TRACE_DBG("sendpage() not called get_page(), zeroing net_priv "
|
||||
"%p (page %p)", page->net_priv, page);
|
||||
page->net_priv = NULL;
|
||||
}
|
||||
}
|
||||
@@ -910,6 +917,7 @@ static int write_data(struct iscsi_conn *conn)
|
||||
mm_segment_t oldfs;
|
||||
struct file *file;
|
||||
struct socket *sock;
|
||||
ssize_t (*sock_sendpage)(struct socket *, struct page *, int, size_t, int);
|
||||
ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int);
|
||||
struct iscsi_cmnd *write_cmnd = conn->write_cmnd;
|
||||
struct iscsi_cmnd *ref_cmd;
|
||||
@@ -918,6 +926,9 @@ static int write_data(struct iscsi_conn *conn)
|
||||
int saved_size, size, sendsize;
|
||||
int offset, idx;
|
||||
int flags, res, count;
|
||||
bool do_put = false;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
iscsi_extracheck_is_wr_thread(conn);
|
||||
|
||||
@@ -967,7 +978,7 @@ retry:
|
||||
set_fs(oldfs);
|
||||
TRACE_WRITE("%#Lx:%u: %d(%ld)",
|
||||
(unsigned long long)conn->session->sid, conn->cid,
|
||||
res, (long) iop->iov_len);
|
||||
res, (long)iop->iov_len);
|
||||
if (unlikely(res <= 0)) {
|
||||
if (res == -EAGAIN) {
|
||||
conn->write_iop = iop;
|
||||
@@ -975,7 +986,7 @@ retry:
|
||||
goto out_iov;
|
||||
} else if (res == -EINTR)
|
||||
goto retry;
|
||||
goto err;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
rest = res;
|
||||
@@ -1000,58 +1011,86 @@ retry:
|
||||
|
||||
sg = write_cmnd->sg;
|
||||
if (unlikely(sg == NULL)) {
|
||||
PRINT_ERROR("%s", "warning data missing!");
|
||||
return 0;
|
||||
PRINT_INFO("WARNING: Data missed (cmd %p)!", write_cmnd);
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
offset = conn->write_offset;
|
||||
|
||||
/* To protect from too early transfer completion race */
|
||||
__iscsi_get_page_callback(ref_cmd);
|
||||
do_put = true;
|
||||
|
||||
offset = conn->write_offset + sg[0].offset;
|
||||
idx = offset >> PAGE_SHIFT;
|
||||
offset &= ~PAGE_MASK;
|
||||
|
||||
sock = conn->sock;
|
||||
|
||||
#ifdef NET_PAGE_CALLBACKS_DEFINED
|
||||
sendpage = sock->ops->sendpage;
|
||||
sock_sendpage = sock->ops->sendpage;
|
||||
#else
|
||||
if ((write_cmnd->parent_req->scst_cmd != NULL) &&
|
||||
scst_cmd_get_data_buff_alloced(write_cmnd->parent_req->scst_cmd))
|
||||
sendpage = sock_no_sendpage;
|
||||
sock_sendpage = sock_no_sendpage;
|
||||
else
|
||||
sendpage = sock->ops->sendpage;
|
||||
sock_sendpage = sock->ops->sendpage;
|
||||
#endif
|
||||
|
||||
flags = MSG_DONTWAIT;
|
||||
|
||||
while (1) {
|
||||
sendpage = sock_sendpage;
|
||||
|
||||
#ifdef NET_PAGE_CALLBACKS_DEFINED
|
||||
if (unlikely((sg_page(&sg[idx])->net_priv != NULL) &&
|
||||
(sg_page(&sg[idx])->net_priv != ref_cmd))) {
|
||||
PRINT_CRIT_ERROR("net_priv isn't NULL and != ref_cmd "
|
||||
"(write_cmnd %p, ref_cmd %p, sg %p, idx %d, "
|
||||
"net_priv %p)", write_cmnd, ref_cmd, sg, idx,
|
||||
sg_page(&sg[idx])->net_priv);
|
||||
sBUG();
|
||||
{
|
||||
static spinlock_t net_priv_lock = SPIN_LOCK_UNLOCKED;
|
||||
spin_lock(&net_priv_lock);
|
||||
if (sg_page(&sg[idx])->net_priv != NULL) {
|
||||
if (sg_page(&sg[idx])->net_priv != ref_cmd) {
|
||||
/*
|
||||
* This might happen if user space supplies
|
||||
* to scst_user the same pages in different
|
||||
* commands or in case of zero-copy FILEIO,
|
||||
* when several initiators request the same
|
||||
* data simultaneously.
|
||||
*/
|
||||
TRACE_DBG("net_priv isn't NULL and != "
|
||||
"ref_cmd (write_cmnd %p, ref_cmd %p, "
|
||||
"sg %p, idx %d, page %p, net_priv %p)",
|
||||
write_cmnd, ref_cmd, sg, idx,
|
||||
sg_page(&sg[idx]),
|
||||
sg_page(&sg[idx])->net_priv);
|
||||
sendpage = sock_no_sendpage;
|
||||
}
|
||||
} else
|
||||
sg_page(&sg[idx])->net_priv = ref_cmd;
|
||||
spin_unlock(&net_priv_lock);
|
||||
}
|
||||
sg_page(&sg[idx])->net_priv = ref_cmd;
|
||||
#endif
|
||||
sendsize = PAGE_SIZE - offset;
|
||||
if (size <= sendsize) {
|
||||
retry2:
|
||||
res = sendpage(sock, sg_page(&sg[idx]), offset, size, flags);
|
||||
TRACE_WRITE("%s %#Lx:%u: %d(%lu,%u,%u)",
|
||||
sock->ops->sendpage ? "sendpage" : "sock_no_sendpage",
|
||||
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,
|
||||
res, sg_page(&sg[idx])->index, offset, size);
|
||||
res, sg_page(&sg[idx])->index, offset, size,
|
||||
write_cmnd, sg_page(&sg[idx]));
|
||||
if (unlikely(res <= 0)) {
|
||||
if (res == -EINTR)
|
||||
goto retry2;
|
||||
else
|
||||
goto out_res;
|
||||
}
|
||||
|
||||
check_net_priv(ref_cmd, sg_page(&sg[idx]));
|
||||
if (res == size) {
|
||||
conn->write_size = 0;
|
||||
return saved_size;
|
||||
res = saved_size;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
offset += res;
|
||||
size -= res;
|
||||
continue;
|
||||
@@ -1060,40 +1099,55 @@ retry2:
|
||||
retry1:
|
||||
res = sendpage(sock, sg_page(&sg[idx]), offset, sendsize,
|
||||
flags | MSG_MORE);
|
||||
TRACE_WRITE("%s %#Lx:%u: %d(%lu,%u,%u)",
|
||||
sock->ops->sendpage ? "sendpage" : "sock_no_sendpage",
|
||||
(unsigned long long ) conn->session->sid, conn->cid,
|
||||
res, sg_page(&sg[idx])->index, offset, sendsize);
|
||||
TRACE_WRITE("%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,
|
||||
res, sg_page(&sg[idx])->index, offset, sendsize,
|
||||
write_cmnd, sg_page(&sg[idx]));
|
||||
if (unlikely(res <= 0)) {
|
||||
if (res == -EINTR)
|
||||
goto retry1;
|
||||
else
|
||||
goto out_res;
|
||||
}
|
||||
|
||||
check_net_priv(ref_cmd, sg_page(&sg[idx]));
|
||||
if (res == sendsize) {
|
||||
idx++;
|
||||
offset = 0;
|
||||
EXTRACHECKS_BUG_ON(idx >= ref_cmd->sg_cnt);
|
||||
} else
|
||||
offset += res;
|
||||
|
||||
size -= res;
|
||||
}
|
||||
out:
|
||||
conn->write_offset = (idx << PAGE_SHIFT) + offset;
|
||||
|
||||
out_off:
|
||||
conn->write_offset = (idx << PAGE_SHIFT) + offset - sg[0].offset;
|
||||
|
||||
out_iov:
|
||||
conn->write_size = size;
|
||||
if ((saved_size == size) && res == -EAGAIN)
|
||||
return res;
|
||||
goto out_put;
|
||||
|
||||
return saved_size - size;
|
||||
res = saved_size - size;
|
||||
|
||||
out_put:
|
||||
if (do_put)
|
||||
__iscsi_put_page_callback(ref_cmd);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
out_res:
|
||||
check_net_priv(ref_cmd, sg_page(&sg[idx]));
|
||||
if (res == -EAGAIN)
|
||||
goto out;
|
||||
goto out_off;
|
||||
/* else go through */
|
||||
|
||||
err:
|
||||
out_err:
|
||||
#ifndef DEBUG
|
||||
if (!conn->closing)
|
||||
#endif
|
||||
@@ -1105,7 +1159,7 @@ err:
|
||||
if (ref_cmd->scst_cmd != NULL)
|
||||
scst_set_delivery_status(ref_cmd->scst_cmd,
|
||||
SCST_CMD_DELIVERY_FAILED);
|
||||
return res;
|
||||
goto out_put;
|
||||
}
|
||||
|
||||
static int exit_tx(struct iscsi_conn *conn, int res)
|
||||
|
||||
@@ -124,8 +124,8 @@
|
||||
#define TRACE_ALL 0xffffffff
|
||||
/* Flags 0xXXXX0000 are local for users */
|
||||
|
||||
#define PRINT(log_flag, format, args...) printk(log_flag format "\n", ## args);
|
||||
#define PRINTN(log_flag, format, args...) printk(log_flag format, ## args);
|
||||
#define PRINT(log_flag, format, args...) printk("%s" format "\n", log_flag, ## args);
|
||||
#define PRINTN(log_flag, format, args...) printk("%s" format, log_flag, ## args);
|
||||
|
||||
#ifdef LOG_PREFIX
|
||||
#define __LOG_PREFIX LOG_PREFIX
|
||||
@@ -141,17 +141,18 @@
|
||||
#define ___unlikely(a) unlikely(a)
|
||||
#endif
|
||||
|
||||
extern int debug_print_prefix(unsigned long trace_flag, const char *prefix,
|
||||
const char *func, int line);
|
||||
extern void debug_print_buffer(const void *data, int len);
|
||||
extern int debug_print_prefix(unsigned long trace_flag, const char *log_level,
|
||||
const char *prefix, const char *func, int line);
|
||||
extern void debug_print_buffer(const char *log_level, const void *data,
|
||||
int len);
|
||||
|
||||
#define TRACE(trace, format, args...) \
|
||||
do { \
|
||||
if (___unlikely(trace_flag & (trace))) \
|
||||
{ \
|
||||
char *__tflag = LOG_FLAG; \
|
||||
if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \
|
||||
__LINE__) > 0) \
|
||||
if (debug_print_prefix(trace_flag, __tflag, __LOG_PREFIX, \
|
||||
__FUNCTION__, __LINE__) > 0) \
|
||||
{ \
|
||||
__tflag = NO_FLAG; \
|
||||
} \
|
||||
@@ -162,21 +163,21 @@ do { \
|
||||
#define PRINT_BUFFER(message, buff, len) \
|
||||
do { \
|
||||
PRINT(NO_FLAG, "%s:", message); \
|
||||
debug_print_buffer(buff, len); \
|
||||
debug_print_buffer(INFO_FLAG, buff, len); \
|
||||
} while(0)
|
||||
|
||||
#define PRINT_BUFF_FLAG(flag, message, buff, len) \
|
||||
do { \
|
||||
if (___unlikely(trace_flag & (flag))) \
|
||||
{ \
|
||||
char *__tflag = LOG_FLAG; \
|
||||
if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \
|
||||
char *__tflag = INFO_FLAG; \
|
||||
if (debug_print_prefix(trace_flag, __tflag, NULL, __FUNCTION__, \
|
||||
__LINE__) > 0) \
|
||||
{ \
|
||||
__tflag = NO_FLAG; \
|
||||
} \
|
||||
PRINT(NO_FLAG, "%s%s:", __tflag, message); \
|
||||
debug_print_buffer(buff, len); \
|
||||
debug_print_buffer(INFO_FLAG, buff, len); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
@@ -195,7 +196,7 @@ do { \
|
||||
if (trace_flag & (trace)) \
|
||||
{ \
|
||||
char *__tflag = LOG_FLAG; \
|
||||
if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \
|
||||
if (debug_print_prefix(trace_flag, __tflag, NULL, __FUNCTION__, \
|
||||
__LINE__) > 0) \
|
||||
{ \
|
||||
__tflag = NO_FLAG; \
|
||||
@@ -216,13 +217,13 @@ do { \
|
||||
if (trace_flag & TRACE_BUFF) \
|
||||
{ \
|
||||
char *__tflag = LOG_FLAG; \
|
||||
if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \
|
||||
if (debug_print_prefix(trace_flag, __tflag, NULL, __FUNCTION__, \
|
||||
__LINE__) > 0) \
|
||||
{ \
|
||||
__tflag = NO_FLAG; \
|
||||
} \
|
||||
PRINT(NO_FLAG, "%s%s:", __tflag, message); \
|
||||
debug_print_buffer(buff, len); \
|
||||
debug_print_buffer(LOG_FLAG, buff, len); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
@@ -231,21 +232,21 @@ do { \
|
||||
if (trace_flag & (flag)) \
|
||||
{ \
|
||||
char *__tflag = LOG_FLAG; \
|
||||
if (debug_print_prefix(trace_flag, NULL, __FUNCTION__, \
|
||||
if (debug_print_prefix(trace_flag, __tflag, NULL, __FUNCTION__, \
|
||||
__LINE__) > 0) \
|
||||
{ \
|
||||
__tflag = NO_FLAG; \
|
||||
} \
|
||||
PRINT(NO_FLAG, "%s%s:", __tflag, message); \
|
||||
debug_print_buffer(buff, len); \
|
||||
debug_print_buffer(LOG_FLAG, buff, len); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define PRINT_LOG_FLAG(log_flag, format, args...) \
|
||||
do { \
|
||||
char *__tflag = log_flag; \
|
||||
if (debug_print_prefix(trace_flag, __LOG_PREFIX, __FUNCTION__, \
|
||||
__LINE__) > 0) \
|
||||
if (debug_print_prefix(trace_flag, __tflag, __LOG_PREFIX, \
|
||||
__FUNCTION__, __LINE__) > 0) \
|
||||
{ \
|
||||
__tflag = NO_FLAG; \
|
||||
} \
|
||||
@@ -263,14 +264,13 @@ do { \
|
||||
|
||||
#define PRINT_CRIT_ERROR(format, args...) \
|
||||
do { \
|
||||
if (strcmp(CRIT_FLAG, LOG_FLAG)) \
|
||||
/* if (strcmp(CRIT_FLAG, LOG_FLAG)) \
|
||||
{ \
|
||||
PRINT_LOG_FLAG(LOG_FLAG, "***CRITICAL ERROR*** " format, args); \
|
||||
} \
|
||||
}*/ \
|
||||
PRINT_LOG_FLAG(CRIT_FLAG, "***CRITICAL ERROR*** " format, args); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define PRINT_INFO(format, args...) \
|
||||
do { \
|
||||
if (strcmp(INFO_FLAG, LOG_FLAG)) \
|
||||
|
||||
@@ -328,6 +328,7 @@ static struct page *dev_user_alloc_pages(struct scatterlist *sg,
|
||||
gfp_t gfp_mask, void *priv)
|
||||
{
|
||||
struct scst_user_cmd *ucmd = (struct scst_user_cmd*)priv;
|
||||
int offset = 0;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -339,7 +340,7 @@ static struct page *dev_user_alloc_pages(struct scatterlist *sg,
|
||||
if (ucmd->cur_data_page == 0) {
|
||||
TRACE_MEM("ucmd->first_page_offset %d",
|
||||
ucmd->first_page_offset);
|
||||
sg->offset = ucmd->first_page_offset;
|
||||
offset = ucmd->first_page_offset;
|
||||
ucmd_get(ucmd, 0);
|
||||
}
|
||||
|
||||
@@ -347,10 +348,11 @@ static struct page *dev_user_alloc_pages(struct scatterlist *sg,
|
||||
goto out;
|
||||
|
||||
sg_set_page(sg, ucmd->data_pages[ucmd->cur_data_page],
|
||||
PAGE_SIZE - sg->offset, 0);
|
||||
PAGE_SIZE - offset, offset);
|
||||
ucmd->cur_data_page++;
|
||||
|
||||
TRACE_MEM("page=%p, length=%d", sg_page(sg), sg->length);
|
||||
TRACE_MEM("page=%p, length=%d, offset=%d", sg_page(sg), sg->length,
|
||||
sg->offset);
|
||||
TRACE_BUFFER("Page data", sg_virt(sg), sg->length);
|
||||
|
||||
out:
|
||||
@@ -498,10 +500,6 @@ static int dev_user_alloc_sg(struct scst_user_cmd *ucmd, int cached_buff)
|
||||
ucmd->ubuff = buf_ucmd->ubuff;
|
||||
ucmd->buf_ucmd = buf_ucmd;
|
||||
|
||||
TRACE_MEM("Buf alloced (ucmd %p, cached_buff %d, ubuff %lx, "
|
||||
"last_len %d, l %d)", ucmd, cached_buff, ucmd->ubuff,
|
||||
last_len, cmd->sg[cmd->sg_cnt-1].length);
|
||||
|
||||
EXTRACHECKS_BUG_ON((ucmd->data_pages != NULL) &&
|
||||
(ucmd != buf_ucmd));
|
||||
|
||||
@@ -510,6 +508,10 @@ static int dev_user_alloc_sg(struct scst_user_cmd *ucmd, int cached_buff)
|
||||
cmd->sg[cmd->sg_cnt-1].length = last_len;
|
||||
}
|
||||
|
||||
TRACE_MEM("Buf alloced (ucmd %p, cached_buff %d, ubuff %lx, "
|
||||
"last_len %d, l %d)", ucmd, cached_buff, ucmd->ubuff,
|
||||
last_len, cmd->sg[cmd->sg_cnt-1].length);
|
||||
|
||||
if (unlikely(cmd->sg_cnt > cmd->tgt_dev->max_sg_cnt)) {
|
||||
static int ll;
|
||||
if (ll < 10) {
|
||||
|
||||
@@ -28,8 +28,18 @@
|
||||
static char trace_buf[TRACE_BUF_SIZE];
|
||||
static spinlock_t trace_buf_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
||||
int debug_print_prefix(unsigned long trace_flag, const char *prefix,
|
||||
const char *func, int line)
|
||||
static inline int get_current_tid(void)
|
||||
{
|
||||
/* Code should be the same as in sys_gettid() */
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
|
||||
return current->pid;
|
||||
#else
|
||||
return task_pid_vnr(current);
|
||||
#endif
|
||||
}
|
||||
|
||||
int debug_print_prefix(unsigned long trace_flag, const char *log_level,
|
||||
const char *prefix, const char *func, int line)
|
||||
{
|
||||
int i = 0;
|
||||
unsigned long flags;
|
||||
@@ -38,7 +48,7 @@ int debug_print_prefix(unsigned long trace_flag, const char *prefix,
|
||||
|
||||
if (trace_flag & TRACE_PID)
|
||||
i += snprintf(&trace_buf[i], TRACE_BUF_SIZE, "[%d]: ",
|
||||
current->pid);
|
||||
get_current_tid());
|
||||
if (prefix != NULL)
|
||||
i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s: ", prefix);
|
||||
if (trace_flag & TRACE_FUNCTION)
|
||||
@@ -47,14 +57,14 @@ int debug_print_prefix(unsigned long trace_flag, const char *prefix,
|
||||
i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%i:", line);
|
||||
|
||||
if (i > 0)
|
||||
PRINTN(LOG_FLAG, "%s", trace_buf);
|
||||
PRINTN(log_level, "%s", trace_buf);
|
||||
|
||||
spin_unlock_irqrestore(&trace_buf_lock, flags);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void debug_print_buffer(const void *data, int len)
|
||||
void debug_print_buffer(const char *log_level, const void *data, int len)
|
||||
{
|
||||
int z, z1, i;
|
||||
const unsigned char *buf = (const unsigned char *) data;
|
||||
@@ -100,7 +110,7 @@ void debug_print_buffer(const void *data, int len)
|
||||
}
|
||||
trace_buf[i] = '\0';
|
||||
if (f) {
|
||||
PRINT(LOG_FLAG, "%s", trace_buf)
|
||||
PRINT(log_level, "%s", trace_buf)
|
||||
} else {
|
||||
PRINT(NO_FLAG, "%s", trace_buf);
|
||||
}
|
||||
|
||||
@@ -658,7 +658,10 @@ static int scst_prepare_space(struct scst_cmd *cmd)
|
||||
}
|
||||
|
||||
alloc:
|
||||
r = scst_alloc_space(cmd);
|
||||
if (!cmd->data_buf_alloced)
|
||||
r = scst_alloc_space(cmd);
|
||||
else
|
||||
TRACE_MEM("%s", "data_buf_alloced set, returning");
|
||||
|
||||
check:
|
||||
if (r != 0) {
|
||||
|
||||
Reference in New Issue
Block a user