- 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:
Vladislav Bolkhovitin
2008-04-17 15:25:39 +00:00
parent 67ea9c1d0a
commit b95fae3220
8 changed files with 203 additions and 119 deletions

View File

@@ -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];

View File

@@ -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))) {

View File

@@ -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;
};

View File

@@ -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)

View File

@@ -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)) \

View File

@@ -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) {

View File

@@ -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);
}

View File

@@ -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) {