From: <vl...@us...> - 2008-04-17 15:25:55
|
Revision: 336 http://scst.svn.sourceforge.net/scst/?rev=336&view=rev Author: vlnb Date: 2008-04-17 08:25:39 -0700 (Thu, 17 Apr 2008) Log Message: ----------- - Fixes scst_user brokennesses in various modes, especially in iSCSI-SCST - Minor debug logging fixes - Minor cleanups Modified Paths: -------------- trunk/iscsi-scst/kernel/digest.c trunk/iscsi-scst/kernel/iscsi.c trunk/iscsi-scst/kernel/iscsi.h trunk/iscsi-scst/kernel/nthread.c trunk/scst/include/scst_debug.h trunk/scst/src/dev_handlers/scst_user.c trunk/scst/src/scst_debug.c trunk/scst/src/scst_targ.c Modified: trunk/iscsi-scst/kernel/digest.c =================================================================== --- trunk/iscsi-scst/kernel/digest.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/iscsi-scst/kernel/digest.c 2008-04-17 15:25:39 UTC (rev 336) @@ -106,9 +106,9 @@ 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 @@ 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]; Modified: trunk/iscsi-scst/kernel/iscsi.c =================================================================== --- trunk/iscsi-scst/kernel/iscsi.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/iscsi-scst/kernel/iscsi.c 2008-04-17 15:25:39 UTC (rev 336) @@ -567,12 +567,13 @@ { 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 @@ 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 @@ 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 @@ break; } + TRACE_DBG("pdusize %d, offset %d, size %d", pdusize, offset, + size); + iscsi_set_datasize(rsp, offset, pdusize); size -= pdusize; @@ -1369,6 +1376,7 @@ } 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 @@ 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 @@ 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))) { Modified: trunk/iscsi-scst/kernel/iscsi.h =================================================================== --- trunk/iscsi-scst/kernel/iscsi.h 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/iscsi-scst/kernel/iscsi.h 2008-04-17 15:25:39 UTC (rev 336) @@ -302,6 +302,7 @@ struct iscsi_pdu pdu; struct scatterlist *sg; + int sg_cnt; int bufflen; u32 r2t_sn; u32 r2t_length; @@ -312,7 +313,6 @@ u32 hdigest; u32 ddigest; - int sg_cnt; /* valid only if own_sg is 1 */ struct list_head cmd_list_entry; }; Modified: trunk/iscsi-scst/kernel/nthread.c =================================================================== --- trunk/iscsi-scst/kernel/nthread.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/iscsi-scst/kernel/nthread.c 2008-04-17 15:25:39 UTC (rev 336) @@ -90,14 +90,12 @@ sBUG_ON(cmnd->parent_req != NULL); if (cmnd->sg != NULL) { - int sg_cnt, i; + int i; - sg_cnt = get_pgcnt(cmnd->bufflen, - cmnd->sg[0].offset); - 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 @@ atomic_read(&rsp->net_ref_cnt), rsp->sg); if ((rsp->sg != cmnd->sg) && (rsp->sg != NULL)) { - int sg_cnt, i; + int i; - sg_cnt = get_pgcnt(rsp->bufflen, - rsp->sg[0].offset); - sBUG_ON(rsp->sg_cnt != sg_cnt); - 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 @@ 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 @@ "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 @@ } #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; } } @@ -910,6 +917,7 @@ 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,7 +926,10 @@ int saved_size, size, sendsize; int offset, idx; int flags, res, count; + bool do_put = false; + TRACE_ENTRY(); + iscsi_extracheck_is_wr_thread(conn); if (write_cmnd->own_sg == 0) @@ -967,7 +978,7 @@ 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 @@ goto out_iov; } else if (res == -EINTR) goto retry; - goto err; + goto out_err; } rest = res; @@ -1000,58 +1011,86 @@ 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 @@ 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 @@ 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) Modified: trunk/scst/include/scst_debug.h =================================================================== --- trunk/scst/include/scst_debug.h 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/scst/include/scst_debug.h 2008-04-17 15:25:39 UTC (rev 336) @@ -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 @@ #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 @@ 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 @@ 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 @@ 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 @@ #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)) \ Modified: trunk/scst/src/dev_handlers/scst_user.c =================================================================== --- trunk/scst/src/dev_handlers/scst_user.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/scst/src/dev_handlers/scst_user.c 2008-04-17 15:25:39 UTC (rev 336) @@ -328,6 +328,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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) { Modified: trunk/scst/src/scst_debug.c =================================================================== --- trunk/scst/src/scst_debug.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/scst/src/scst_debug.c 2008-04-17 15:25:39 UTC (rev 336) @@ -28,9 +28,19 @@ 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 @@ 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 @@ 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 @@ } 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); } Modified: trunk/scst/src/scst_targ.c =================================================================== --- trunk/scst/src/scst_targ.c 2008-04-11 08:18:02 UTC (rev 335) +++ trunk/scst/src/scst_targ.c 2008-04-17 15:25:39 UTC (rev 336) @@ -658,7 +658,10 @@ } 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) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |