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;
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];
{
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;
}
}
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;
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);
break;
}
+ TRACE_DBG("pdusize %d, offset %d, size %d", pdusize, offset,
+ size);
+
iscsi_set_datasize(rsp, offset, pdusize);
size -= pdusize;
}
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",
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);
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))) {
struct iscsi_pdu pdu;
struct scatterlist *sg;
+ int sg_cnt;
int bufflen;
u32 r2t_sn;
u32 r2t_length;
u32 hdigest;
u32 ddigest;
- int sg_cnt; /* valid only if own_sg is 1 */
struct list_head cmd_list_entry;
};
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,
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,
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,
"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,
}
#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_put_page_callback(struct page *page)
+void iscsi_get_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),
+ 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 = get_pgcnt(cmd->bufflen, cmd->sg[0].offset);
+ int i, sg_cnt = cmd->sg_cnt;
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;
+ 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("page %p, _count %d", page,
+ atomic_read(&page->_count));
+
+ __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;
}
}
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;
int saved_size, size, sendsize;
int offset, idx;
int flags, res, count;
+ bool do_put = false;
+
+ TRACE_ENTRY();
iscsi_extracheck_is_wr_thread(conn);
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;
goto out_iov;
} else if (res == -EINTR)
goto retry;
- goto err;
+ goto out_err;
}
rest = res;
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;
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;
+
+ res = saved_size - size;
+
+out_put:
+ if (do_put)
+ __iscsi_put_page_callback(ref_cmd);
- return saved_size - size;
+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
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)
#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
#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; \
} \
#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)
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; \
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)
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; \
} \
#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)) \
gfp_t gfp_mask, void *priv)
{
struct scst_user_cmd *ucmd = (struct scst_user_cmd*)priv;
+ int offset = 0;
TRACE_ENTRY();
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);
}
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:
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));
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) {
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;
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)
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;
}
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);
}
}
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) {