- Update to work on 2.6.24
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 31 Jan 2008 18:28:43 +0000 (18:28 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 31 Jan 2008 18:28:43 +0000 (18:28 +0000)
 - Minor cleanups

git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@251 d57e44dd-8a1f-0410-8b47-8ef2f437770f

15 files changed:
iscsi-scst/kernel/digest.c
iscsi-scst/kernel/event.c
iscsi-scst/kernel/iscsi.c
iscsi-scst/kernel/nthread.c
qla2x00t/qla2x00-target/qla2x00t.c
qla2x00t/qla2x00-target/qla2x00t.h
qla2x00t/qla_attr.c
scst/include/scsi_tgt.h
scst/src/dev_handlers/scst_user.c
scst/src/dev_handlers/scst_vdisk.c
scst/src/scst_lib.c
scst/src/scst_main.c
scst/src/scst_mem.c
scst/src/scst_mem.h
scst/src/scst_targ.c

index 6cef263..8a2bf5c 100644 (file)
@@ -56,13 +56,6 @@ int digest_init(struct iscsi_conn *conn)
        return 0;
 }
 
-/* Copied from linux-iscsi initiator and slightly adjusted */
-#define SETSG(sg, p, l) do {                                   \
-       (sg).page = virt_to_page((p));                          \
-       (sg).offset = ((unsigned long)(p) & ~PAGE_MASK);        \
-       (sg).length = (l);                                      \
-} while (0)
-
 static u32 evaluate_crc32_from_sg(struct scatterlist *sg, int total,
        int pad_bytes)
 {
@@ -80,7 +73,7 @@ static u32 evaluate_crc32_from_sg(struct scatterlist *sg, int total,
                int d = min(min(total, (int)(sg->length)),
                        (int)(PAGE_SIZE - sg->offset));
 
-               crc = crc32c(crc, page_address(sg->page) + sg->offset, d);
+               crc = crc32c(crc, sg_virt(sg), d);
                total -= d;
                sg++;
        }
@@ -103,9 +96,11 @@ static u32 digest_header(struct iscsi_pdu *pdu)
        struct scatterlist sg[2];
        unsigned int nbytes = sizeof(struct iscsi_hdr);
 
-       SETSG(sg[0], &pdu->bhs, nbytes);
+       sg_init_table(sg, 2);
+
+       sg_set_buf(&sg[0], &pdu->bhs, nbytes);
        if (pdu->ahssize) {
-               SETSG(sg[1], pdu->ahs, pdu->ahssize);
+               sg_set_buf(&sg[1], pdu->ahs, pdu->ahssize);
                nbytes += pdu->ahssize;
        }
        return evaluate_crc32_from_sg(sg, nbytes, 0);
index 0a4575c..5e2cb20 100644 (file)
@@ -39,7 +39,11 @@ static int event_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        return 0;
 }
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
 static int event_recv_skb(struct sk_buff *skb)
+#else
+static void event_recv_skb(struct sk_buff *skb)
+#endif
 {
        int err;
        struct nlmsghdr *nlh;
@@ -48,7 +52,7 @@ static int event_recv_skb(struct sk_buff *skb)
        while (skb->len >= NLMSG_SPACE(0)) {
                nlh = (struct nlmsghdr *)skb->data;
                if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
-                       return 0;
+                       goto out;
                rlen = NLMSG_ALIGN(nlh->nlmsg_len);
                if (rlen > skb->len)
                        rlen = skb->len;
@@ -58,9 +62,16 @@ static int event_recv_skb(struct sk_buff *skb)
                        netlink_ack(skb, nlh, 0);
                skb_pull(skb, rlen);
        }
+
+out:
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
        return 0;
+#else
+       return;
+#endif
 }
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
 static void event_recv(struct sock *sk, int length)
 {
        struct sk_buff *skb;
@@ -72,6 +83,7 @@ static void event_recv(struct sock *sk, int length)
                        kfree_skb(skb);
        }
 }
+#endif
 
 static int notify(void *data, int len, int gfp_mask)
 {
@@ -107,10 +119,16 @@ int event_send(u32 tid, u64 sid, u32 cid, u32 state, int atomic)
 int __init event_init(void)
 {
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
-       nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv, THIS_MODULE);
+       nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv,
+               THIS_MODULE);
 #else
-       nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv, NULL,
+  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
+       nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv, NULL,
                THIS_MODULE);
+  #else
+       nl = netlink_kernel_create(&init_net, NETLINK_ISCSI_SCST, 1,
+               event_recv_skb, NULL, THIS_MODULE);
+  #endif
 #endif
        if (!nl) {
                PRINT_ERROR("%s", "netlink_kernel_create() failed");
index 3a6f3d0..8389223 100644 (file)
@@ -531,7 +531,7 @@ static void iscsi_set_datasize(struct iscsi_cmnd *cmnd, u32 offset, u32 size)
 
        if (cmnd->pdu.datasize & 3) {
                int idx = (offset + cmnd->pdu.datasize) >> PAGE_SHIFT;
-               u8 *p = (u8 *)page_address(cmnd->sg[idx].page) + 
+               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--) 
@@ -627,7 +627,7 @@ static struct iscsi_cmnd *create_status_rsp(struct iscsi_cmnd *req, int status,
                        /* ToDo(); */
                }
                rsp->own_sg = 1;
-               sense = (struct iscsi_sense_data *)page_address(sg[0].page);
+               sense = (struct iscsi_sense_data *)page_address(sg_page(&sg[0]));
                sense->length = cpu_to_be16(sense_len);
                memcpy(sense->data, sense_buf, sense_len);
                rsp->pdu.datasize = sizeof(struct iscsi_sense_data) + sense_len;
@@ -686,7 +686,7 @@ static void iscsi_cmnd_reject(struct iscsi_cmnd *req, int reason)
                /* ToDo(); */
        }
        rsp->own_sg = 1;
-       addr = page_address(sg[0].page);
+       addr = page_address(sg_page(&sg[0]));
        clear_page(addr);
        memcpy(addr, &req->pdu.bhs, sizeof(struct iscsi_hdr));
        rsp->bufflen = rsp->pdu.datasize = sizeof(struct iscsi_hdr);
@@ -817,6 +817,8 @@ static int cmnd_insert_hash(struct iscsi_cmnd *cmnd)
        TRACE_DBG("%p:%x", cmnd, itt);
        if (unlikely(itt == ISCSI_RESERVED_TAG)) {
                PRINT_ERROR("%s", "ITT is RESERVED_TAG");
+               PRINT_BUFFER("Incorrect BHS", &cmnd->pdu.bhs,
+                       sizeof(cmnd->pdu.bhs));
                err = -ISCSI_REASON_PROTOCOL_ERROR;
                goto out;
        }
@@ -894,7 +896,7 @@ static void cmnd_prepare_skip_pdu(struct iscsi_cmnd *cmnd)
                cmnd->bufflen = PAGE_SIZE;
        }
 
-       addr = page_address(sg[0].page);
+       addr = page_address(sg_page(&sg[0]));
        sBUG_ON(addr == NULL);
        size = (size + 3) & -4;
        conn->read_size = size;
@@ -975,8 +977,7 @@ static int cmnd_prepare_recv_pdu(struct iscsi_conn *conn,
 
        i = 0;
        while (1) {
-               sBUG_ON(sg[idx].page == NULL);
-               addr = page_address(sg[idx].page);
+               addr = page_address(sg_page(&sg[idx]));
                sBUG_ON(addr == NULL);
                conn->read_iov[i].iov_base = addr + offset;
                if (offset + size <= PAGE_SIZE) {
@@ -1162,7 +1163,7 @@ static int noop_out_start(struct iscsi_cmnd *cmnd)
 
                        for (i = 0; i < cmnd->sg_cnt; i++) {
                                conn->read_iov[i].iov_base =
-                                       page_address(sg[i].page);
+                                       page_address(sg_page(&sg[i]));
                                tmp = min_t(u32, size, PAGE_SIZE);
                                conn->read_iov[i].iov_len = tmp;
                                conn->read_size += tmp;
index 2cc9547..c32cebc 100644 (file)
@@ -96,17 +96,18 @@ again:
                        if (cmnd_get_check(cmnd))
                                continue;
                        for(i = 0; i < sg_cnt; i++) {
-                               TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, _count %d",
-                                       cmnd->sg[i].page, cmnd->sg[i].page->net_priv,
-                                       atomic_read(&cmnd->sg[i].page->_count));
+                               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(&page->_count));
 
-                               if (cmnd->sg[i].page->net_priv != NULL) {
+                               if (page->net_priv != NULL) {
                                        if (restart == 0) {
                                                spin_unlock_bh(&conn->cmd_list_lock);
                                                restart = 1;
                                        }
-                                       while(cmnd->sg[i].page->net_priv != NULL)
-                                               iscsi_put_page_callback(cmnd->sg[i].page);
+                                       while(page->net_priv != NULL)
+                                               iscsi_put_page_callback(page);
                                }
                        }
                        cmnd_put(cmnd);
@@ -131,19 +132,19 @@ again:
                                if (cmnd_get_check(rsp))
                                        continue;
                                for(i = 0; i < sg_cnt; i++) {
+                                       struct page *page = sg_page(&rsp->sg[i]);
                                        TRACE_CONN_CLOSE_DBG("    page %p, net_priv %p, "
-                                               "_count %d", rsp->sg[i].page,
-                                               rsp->sg[i].page->net_priv,
-                                               atomic_read(&rsp->sg[i].page->_count));
+                                               "_count %d", page, page->net_priv,
+                                               atomic_read(&page->_count));
 
-                                       if (rsp->sg[i].page->net_priv != NULL) {
+                                       if (page->net_priv != NULL) {
                                                if (restart == 0) {
                                                        spin_unlock_bh(&cmnd->rsp_cmd_lock);
                                                        spin_unlock_bh(&conn->cmd_list_lock);
                                                        restart = 1;
                                                }
-                                               while(rsp->sg[i].page->net_priv != NULL)
-                                                       iscsi_put_page_callback(rsp->sg[i].page);
+                                               while(page->net_priv != NULL)
+                                                       iscsi_put_page_callback(page);
                                        }
                                }
                                cmnd_put(rsp);
@@ -336,9 +337,10 @@ static void close_conn(struct iscsi_conn *conn)
                                        sg_cnt = get_pgcnt(cmnd->bufflen,
                                                cmnd->sg[0].offset);
                                        for(i = 0; i < sg_cnt; i++) {
+                                               struct page *page = sg_page(&cmnd->sg[i]);
                                                TRACE_CONN_CLOSE_DBG("page %p, net_priv %p, _count %d",
-                                                       cmnd->sg[i].page, cmnd->sg[i].page->net_priv,
-                                                       atomic_read(&cmnd->sg[i].page->_count));
+                                                       page, page->net_priv,
+                                                       atomic_read(&page->_count));
                                        }
                                }
 
@@ -356,9 +358,9 @@ static void close_conn(struct iscsi_conn *conn)
                                                sBUG_ON(rsp->sg_cnt != sg_cnt);
                                                for(i = 0; i < sg_cnt; i++) {
                                                        TRACE_CONN_CLOSE_DBG("    page %p, net_priv %p, "
-                                                               "_count %d", rsp->sg[i].page,
-                                                               rsp->sg[i].page->net_priv,
-                                                               atomic_read(&rsp->sg[i].page->_count));
+                                                               "_count %d", sg_page(&rsp->sg[i]),
+                                                               sg_page(&rsp->sg[i])->net_priv,
+                                                               atomic_read(&sg_page(&rsp->sg[i])->_count));
                                                }
                                        }
                                }
@@ -809,8 +811,8 @@ void iscsi_put_page_callback(struct page *page)
        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", cmd->sg[i].page);
-                       cmd->sg[i].page->net_priv = NULL;
+                       TRACE_NET_PAGE("Clearing page %p", sg_page(&cmd->sg[i]));
+                       sg_page(&cmd->sg[i])->net_priv = NULL;
                }
                cmnd_put(cmd);
        }
@@ -923,31 +925,31 @@ retry:
 
        while (1) {
 #ifdef NET_PAGE_CALLBACKS_DEFINED
-               if (unlikely((sg[idx].page->net_priv != NULL) &&
-                               (sg[idx].page->net_priv != ref_cmd))) {
+               if (unlikely((sg_page(&sg[idx])->net_priv != NULL) &&
+                               (sg_page(&sg[idx])->net_priv != ref_cmd))) {
                        PRINT_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[idx].page->net_priv);
+                               sg_page(&sg[idx])->net_priv);
                        sBUG();
                }
-               sg[idx].page->net_priv = ref_cmd;
+               sg_page(&sg[idx])->net_priv = ref_cmd;
 #endif
                sendsize = PAGE_SIZE - offset;
                if (size <= sendsize) {
 retry2:
-                       res = sendpage(sock, sg[idx].page, offset, size, flags);
+                       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",
                                (unsigned long long)conn->session->sid, conn->cid,
-                               res, sg[idx].page->index, offset, size);
+                               res, sg_page(&sg[idx])->index, offset, size);
                        if (unlikely(res <= 0)) {
                                if (res == -EINTR)
                                        goto retry2;
                                else
                                        goto out_res;
                        }
-                       check_net_priv(ref_cmd, sg[idx].page);
+                       check_net_priv(ref_cmd, sg_page(&sg[idx]));
                        if (res == size) {
                                conn->write_size = 0;
                                return saved_size;
@@ -958,19 +960,19 @@ retry2:
                }
 
 retry1:
-               res = sendpage(sock, sg[idx].page, offset, sendsize,
+               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[idx].page->index, offset, sendsize);
+                       res, sg_page(&sg[idx])->index, offset, sendsize);
                if (unlikely(res <= 0)) {
                        if (res == -EINTR)
                                goto retry1;
                        else
                                goto out_res;
                }
-               check_net_priv(ref_cmd, sg[idx].page);
+               check_net_priv(ref_cmd, sg_page(&sg[idx]));
                if (res == sendsize) {
                        idx++;
                        offset = 0;
@@ -988,7 +990,7 @@ out_iov:
        return saved_size - size;
 
 out_res:
-       check_net_priv(ref_cmd, sg[idx].page);
+       check_net_priv(ref_cmd, sg_page(&sg[idx]));
        if (res == -EAGAIN)
                goto out;
        /* else go through */
index 4fa5a94..d43f812 100644 (file)
@@ -1016,8 +1016,8 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
                case CTIO_TIMEOUT:
                case CTIO_INVALID_RX_ID:
                        /* they are OK */
-                       TRACE_MGMT_DBG("qla2x00tgt(%ld): CTIO with status %#x "
-                               "received (LIP_RESET=e, ABORTED=2, "
+                       TRACE(TRACE_MGMT_MINOR, "qla2x00tgt(%ld): CTIO with "
+                               "status %#x received (LIP_RESET=e, ABORTED=2, "
                                "TARGET_RESET=17, TIMEOUT=b, "
                                "INVALID_RX_ID=8)", ha->instance, status);
                        break;
@@ -1052,7 +1052,7 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
                        goto out;
                }
                if (unlikely(err)) {
-                       PRINT_INFO("Found by handle failed CTIO scst_cmd "
+                       TRACE_MGMT_DBG("Found by handle failed CTIO scst_cmd "
                                "%p (op %x)", scst_cmd, scst_cmd->cdb[0]);
                }
        } else if (ctio != NULL) {
@@ -1075,7 +1075,7 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
                        goto out;
                }
                if (unlikely(err)) {
-                       PRINT_INFO("Found by ctio failed CTIO scst_cmd %p "
+                       TRACE_MGMT_DBG("Found by ctio failed CTIO scst_cmd %p "
                                "(op %x)", scst_cmd, scst_cmd->cdb[0]);
                }
 
@@ -1085,7 +1085,8 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
 
        cmd = (struct q2t_cmd *)scst_cmd_get_tgt_priv(scst_cmd);
        if (unlikely(err)) {
-               PRINT_INFO("Failed CTIO state %d", cmd->state);
+               TRACE(TRACE_MGMT_MINOR, "Failed CTIO state %d (err %x)",
+                       cmd->state, status);
        }
 
        if (cmd->state == Q2T_STATE_PROCESSED) {
@@ -1120,7 +1121,7 @@ static void q2t_do_ctio_completion(scsi_qla_host_t *ha,
 
                scst_rx_data(scst_cmd, rx_status, context);
        } else if (cmd->state == Q2T_STATE_ABORTED) {
-               TRACE_DBG("Aborted command %p finished", cmd);
+               TRACE_MGMT_DBG("Aborted command %p finished", cmd);
                goto out_free;
        } else {
                PRINT_ERROR("qla2x00tgt(%ld): A command in state (%d) should "
index 3dc7ba0..cfcea70 100644 (file)
 #define NOTIFY_ACK_TM_RESP_CODE_VALID BIT_4
 
 /* Command's states */
-#define Q2T_STATE_NEW               0  /* New command and SCST processes it */
+#define Q2T_STATE_NEW               0  /* New command and SCST processing it */
 #define Q2T_STATE_PROCESSED         1  /* SCST done processing */
-#define Q2T_STATE_NEED_DATA         2  /* SCST needs data to process */
-#define Q2T_STATE_DATA_IN           3  /* Data arrived and SCST processes it */
+#define Q2T_STATE_NEED_DATA         2  /* SCST needs data to continue */
+#define Q2T_STATE_DATA_IN           3  /* Data arrived and SCST processing them */
 #define Q2T_STATE_ABORTED           4  /* Command aborted */
 
 /* Misc */
index f22a958..c2edd9c 100644 (file)
@@ -61,14 +61,14 @@ qla2x00_store_tgt_enabled(struct class_device *cdev,
        case '0' : 
                if ((ha->flags.enable_target_mode) || force) {
                        qla_target.tgt_host_action(ha, DISABLE_TARGET_MODE);
+                       msleep_interruptible(10*1000);
                }
-               msleep_interruptible(3*1000);
                break;
        case '1' :
                if ((ha->flags.enable_target_mode == 0) || force) {
                        qla_target.tgt_host_action(ha, ENABLE_TARGET_MODE);
+                       msleep_interruptible(10*1000);
                }
-               msleep_interruptible(3*1000);
                break;
        default:
                printk("%s: Requested action not understood: %s\n",
index 91ded86..4379868 100644 (file)
 
 #include <scst_const.h>
 
+#ifndef DECLARE_MUTEX_LOCKED
+#define DECLARE_MUTEX_LOCKED(name)     __DECLARE_SEMAPHORE_GENERIC(name, 0)
+#endif
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
 typedef _Bool bool;
 #endif
@@ -2235,6 +2239,52 @@ static inline int scst_mgmt_cmd_get_status(struct scst_mgmt_cmd *mcmd)
        return mcmd->status;
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+
+static inline struct page *sg_page(struct scatterlist *sg)
+{
+       return sg->page;
+}
+
+static inline void *sg_virt(struct scatterlist *sg)
+{
+       return page_address(sg_page(sg)) + sg->offset;
+}
+
+static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
+{
+       memset(sgl, 0, sizeof(*sgl) * nents);
+}
+
+static inline void sg_assign_page(struct scatterlist *sg, struct page *page)
+{
+       sg->page = page;
+}
+
+static inline void sg_set_page(struct scatterlist *sg, struct page *page,
+                              unsigned int len, unsigned int offset)
+{
+       sg_assign_page(sg, page);
+       sg->offset = offset;
+       sg->length = len;
+}
+
+static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
+                             unsigned int buflen)
+{
+       sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
+}
+
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */
+
+static inline void sg_clear(struct scatterlist *sg)
+{
+       memset(sg, 0, sizeof(*sg));
+#ifdef CONFIG_DEBUG_SG
+       sg->sg_magic = SG_MAGIC;
+#endif
+}
+
 /*
  * Functions for access to the commands data (SG) buffer,
  * including HIGHMEM environment. Should be used instead of direct
@@ -2245,7 +2295,41 @@ static inline int scst_mgmt_cmd_get_status(struct scst_mgmt_cmd *mcmd)
  *
  * The "put" function unmaps the buffer.
  */
-int __scst_get_buf(struct scst_cmd *cmd, uint8_t **buf);
+static inline int __scst_get_buf(struct scst_cmd *cmd, uint8_t **buf)
+{
+       int res = 0;
+       struct scatterlist *sg = cmd->sg;
+       int i = cmd->get_sg_buf_entry_num;
+       
+       *buf = NULL;
+       
+       if ((i >= cmd->sg_cnt) || unlikely(sg == NULL))
+               goto out;
+#ifdef SCST_HIGHMEM /* HIGHMEM isn't currently supported */
+       /* 
+        * HIGHMEM pages not merged (clustered), so if it's 
+        * not HIGHMEM page, kmap() is the same as page_address()
+        */
+       if (scst_cmd_atomic(cmd)) {
+               enum km_type km;
+               if (in_softirq())
+                       km = KM_SOFTIRQ0;
+               else
+                       km = KM_USER0;
+               *buf = kmap_atomic(sg[i].page, km);
+       } else
+               *buf = kmap(sg[i].page);
+#else
+       *buf = page_address(sg_page(&sg[i]));
+#endif
+       *buf += sg[i].offset;
+       res = sg[i].length;
+       cmd->get_sg_buf_entry_num++;
+       
+out:
+       return res;
+}
+
 static inline int scst_get_buf_first(struct scst_cmd *cmd, uint8_t **buf)
 {
        cmd->get_sg_buf_entry_num = 0;
@@ -2260,7 +2344,7 @@ static inline int scst_get_buf_next(struct scst_cmd *cmd, uint8_t **buf)
 
 static inline void scst_put_buf(struct scst_cmd *cmd, void *buf)
 {
-#ifdef SCST_HIGHMEM
+#ifdef SCST_HIGHMEM /* HIGHMEM isn't currently supported */
        if (cmd->sg_cnt) {
                if (scst_cmd_atomic(cmd)) {
                        enum km_type km;
index 1ab385f..ea724fa 100644 (file)
@@ -346,17 +346,16 @@ static struct page *dev_user_alloc_pages(struct scatterlist *sg,
        if (ucmd->cur_data_page >= ucmd->num_data_pages)
                goto out;
 
-       sg->page = ucmd->data_pages[ucmd->cur_data_page];
-       sg->length = PAGE_SIZE - sg->offset;
-
+       sg_set_page(sg, ucmd->data_pages[ucmd->cur_data_page],
+               PAGE_SIZE - sg->offset, 0);
        ucmd->cur_data_page++;
 
-       TRACE_MEM("page=%p, length=%d", sg->page, sg->length);
-       TRACE_BUFFER("Page data", page_address(sg->page), sg->length);
+       TRACE_MEM("page=%p, length=%d", sg_page(sg), sg->length);
+       TRACE_BUFFER("Page data", sg_virt(sg), sg->length);
 
 out:
        TRACE_EXIT();
-       return sg->page;
+       return sg_page(sg);
 }
 
 static void dev_user_on_cached_mem_free(struct scst_user_cmd *ucmd)
index cb18b33..935d9d9 100644 (file)
@@ -2196,12 +2196,18 @@ static inline void blockio_check_finish(struct blockio_work *blockio_work)
        }
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
 static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error)
+#else
+static void blockio_endio(struct bio *bio, int error)
+#endif
 {
        struct blockio_work *blockio_work = bio->bi_private;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
        if (bio->bi_size)
                return 1;
+#endif
 
        error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO;
 
@@ -2224,7 +2230,11 @@ static int blockio_endio(struct bio *bio, unsigned int bytes_done, int error)
        blockio_check_finish(blockio_work);
 
        bio_put(bio);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
        return 0;
+#else
+       return;
+#endif
 }
 
 static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
@@ -2233,10 +2243,10 @@ static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
        struct scst_vdisk_dev *virt_dev = thr->virt_dev;
        struct block_device *bdev = thr->bdev;
        struct request_queue *q = bdev_get_queue(bdev);
-       int j, max_nr_vecs = 0;
+       int length, max_nr_vecs = 0;
+       uint8_t *address;
        struct bio *bio = NULL, *hbio = NULL, *tbio = NULL;
        int need_new_bio;
-       struct scatterlist *sgl = cmd->sg;
        struct blockio_work *blockio_work;
        int bios = 0;
 
@@ -2258,24 +2268,27 @@ static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
                max_nr_vecs = 1;
 
        need_new_bio = 1;
-       for (j = 0; j < cmd->sg_cnt; ++j) {
+
+       length = scst_get_buf_first(cmd, &address);
+       while(length > 0) {
                int len, bytes, off, thislen;
-               struct page *page;
+               uint8_t *addr;
 
-               page = sgl[j].page;
-               off = sgl[j].offset;
-               len = sgl[j].length;
+               addr = address;
+               off = offset_in_page(addr);
+               len = length;
                thislen = 0;
 
                while (len > 0) {
                        int rc;
+                       struct page *page = virt_to_page(addr);
 
                        if (need_new_bio) {
                                bio = bio_alloc(GFP_KERNEL, max_nr_vecs);
                                if (!bio) {
                                        PRINT_ERROR("Failed to create bio "
-                                                      "for data segment= %d "
-                                                      "cmd %p", j, cmd);
+                                               "for data segment= %d cmd %p",
+                                               cmd->get_sg_buf_entry_num, cmd);
                                        goto out_no_bio;
                                }
 
@@ -2306,13 +2319,16 @@ static void blockio_exec_rw(struct scst_cmd *cmd, struct scst_vdisk_thr *thr,
                                continue;
                        }
 
-                       page++;
+                       addr += PAGE_SIZE;
                        thislen += bytes;
                        len -= bytes;
                        off = 0;
                }
 
-               lba_start += sgl[j].length >> virt_dev->block_shift;
+               lba_start += length >> virt_dev->block_shift;
+
+               scst_put_buf(cmd, address);
+               length = scst_get_buf_next(cmd, &address);
        }
 
        /* +1 to prevent erroneous too early command completion */
index 53ad835..5f8725e 100644 (file)
@@ -1567,44 +1567,6 @@ out:
        return;
 }
 
-int __scst_get_buf(struct scst_cmd *cmd, uint8_t **buf)
-{
-       int res = 0;
-       struct scatterlist *sg = cmd->sg;
-       int i = cmd->get_sg_buf_entry_num;
-       
-       TRACE_ENTRY();
-       
-       *buf = NULL;
-       
-       if ((i >= cmd->sg_cnt) || unlikely(sg == NULL))
-               goto out;
-#ifdef SCST_HIGHMEM
-       /* 
-        * HIGHMEM pages not merged (clustered), so if it's 
-        * not HIGHMEM page, kmap() is the same as page_address()
-        */
-       if (scst_cmd_atomic(cmd)) {
-               enum km_type km;
-               if (in_softirq())
-                       km = KM_SOFTIRQ0;
-               else
-                       km = KM_USER0;
-               *buf = kmap_atomic(sg[i].page, km);
-       } else
-               *buf = kmap(sg[i].page);
-#else
-       *buf = page_address(sg[i].page);
-#endif
-       *buf += sg[i].offset;
-       res = sg[i].length;
-       cmd->get_sg_buf_entry_num++;
-       
-out:
-       TRACE_EXIT_RES(res);
-       return res;
-}
-
 static const int SCST_CDB_LENGTH[8] = { 6, 10, 10, -1, 16, 12, -1, -1 };
 
 #define SCST_CDB_GROUP(opcode)   ((opcode >> 5) & 0x7)
index 9365d02..0fe5be7 100644 (file)
@@ -296,7 +296,7 @@ struct scst_tgt *scst_register(struct scst_tgt_template *vtt,
 
        tgt = kzalloc(sizeof(*tgt), GFP_KERNEL);
        if (tgt == NULL) {
-               TRACE(TRACE_OUT_OF_MEM, "%s", "kzalloc() failed");
+               TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of tgt failed");
                goto out_err;
        }
 
@@ -1736,7 +1736,6 @@ EXPORT_SYMBOL(scst_proc_log_entry_write);
 EXPORT_SYMBOL(scst_create_proc_entry);
 EXPORT_SYMBOL(scst_single_seq_open);
 
-EXPORT_SYMBOL(__scst_get_buf);
 EXPORT_SYMBOL(scst_get);
 EXPORT_SYMBOL(scst_put);
 
index 88d869e..9cb04c2 100644 (file)
@@ -75,7 +75,7 @@ static int scst_check_clustering(struct scatterlist *sg, int cur, int hint)
 {
        int res = -1;
        int i = hint;
-       unsigned long pfn_cur = page_to_pfn(sg[cur].page);
+       unsigned long pfn_cur = page_to_pfn(sg_page(&sg[cur]));
        int len_cur = sg[cur].length;
        unsigned long pfn_cur_next = pfn_cur + (len_cur >> PAGE_SHIFT);
        int full_page_cur = (len_cur & (PAGE_SIZE - 1)) == 0;
@@ -95,7 +95,7 @@ static int scst_check_clustering(struct scatterlist *sg, int cur, int hint)
 
        /* check the hint first */
        if (i >= 0) {
-               pfn = page_to_pfn(sg[i].page);
+               pfn = page_to_pfn(sg_page(&sg[i]));
                pfn_next = pfn + (sg[i].length >> PAGE_SHIFT);
                full_page = (sg[i].length & (PAGE_SIZE - 1)) == 0;
                
@@ -108,7 +108,7 @@ static int scst_check_clustering(struct scatterlist *sg, int cur, int hint)
 
        /* ToDo: implement more intelligent search */
        for(i = cur - 1; i >= 0; i--) {
-               pfn = page_to_pfn(sg[i].page);
+               pfn = page_to_pfn(sg_page(&sg[i]));
                pfn_next = pfn + (sg[i].length >> PAGE_SHIFT);
                full_page = (sg[i].length & (PAGE_SIZE - 1)) == 0;
                
@@ -125,15 +125,15 @@ out:
 out_tail:
        TRACE_MEM("SG segment %d will be tail merged with segment %d", cur, i);
        sg[i].length += len_cur;
-       memset(&sg[cur], 0, sizeof(sg[cur]));
+       sg_clear(&sg[cur]);
        res = i;
        goto out;
 
 out_head:
        TRACE_MEM("SG segment %d will be head merged with segment %d", cur, i);
-       sg[i].page = sg[cur].page;
+       sg_assign_page(&sg[i], sg_page(&sg[cur]));
        sg[i].length += len_cur;
-       memset(&sg[cur], 0, sizeof(sg[cur]));
+       sg_clear(&sg[cur]);
        res = i;
        goto out;
 }
@@ -146,7 +146,7 @@ static void scst_free_sys_sg_entries(struct scatterlist *sg, int sg_count,
        TRACE_MEM("sg=%p, sg_count=%d", sg, sg_count);
 
        for(i = 0; i < sg_count; i++) {
-               struct page *p = sg[i].page;
+               struct page *p = sg_page(&sg[i]);
                int len = sg[i].length;
                int pages =
                        (len >> PAGE_SHIFT) + ((len & ~PAGE_MASK) != 0);
@@ -182,15 +182,15 @@ static void scst_free_sys_sg_entries(struct scatterlist *sg, int sg_count,
 static struct page *scst_alloc_sys_pages(struct scatterlist *sg,
        gfp_t gfp_mask, void *priv)
 {
-       sg->page = alloc_pages(gfp_mask, 0);
-       sg->offset = 0;
-       sg->length = PAGE_SIZE;
-       TRACE_MEM("page=%p, sg=%p, priv=%p", sg->page, sg, priv);
-       if (sg->page == NULL) {
+       struct page *page = alloc_pages(gfp_mask, 0);
+
+       sg_set_page(sg, page, PAGE_SIZE, 0);
+       TRACE_MEM("page=%p, sg=%p, priv=%p", page, sg, priv);
+       if (page == NULL) {
                TRACE(TRACE_OUT_OF_MEM, "%s", "Allocation of "
                        "sg page failed");
        }
-       return sg->page;
+       return page;
 }
 
 static int scst_alloc_sg_entries(struct scatterlist *sg, int pages,
@@ -265,7 +265,7 @@ static int sgv_alloc_arrays(struct sgv_pool_obj *obj,
 
        sz = pages_to_alloc * sizeof(obj->sg_entries[0]);
 
-       obj->sg_entries = (struct scatterlist*)kzalloc(sz, gfp_mask);
+       obj->sg_entries = (struct scatterlist*)kmalloc(sz, gfp_mask);
        if (unlikely(obj->sg_entries == NULL)) {
                TRACE(TRACE_OUT_OF_MEM, "Allocation of sgv_pool_obj "
                        "SG vector failed (size %d)", sz);
@@ -273,6 +273,8 @@ static int sgv_alloc_arrays(struct sgv_pool_obj *obj,
                goto out;
        }
 
+       sg_init_table(obj->sg_entries, pages_to_alloc);
+
        if (obj->owner_pool->clustered) {
                if (order <= sgv_pools_mgr.sgv_max_trans_order) {
                        obj->trans_tbl = (struct trans_tbl_ent*)obj->sg_entries_data;
@@ -528,7 +530,6 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size,
                if (obj->sg_count != 0) {
                        TRACE_MEM("Cached sgv_obj %p", obj);
                        EXTRACHECKS_BUG_ON(obj->order != order);
-                       atomic_inc(&pool->acc.hit_alloc);
                        atomic_inc(&pool->cache_acc[order].hit_alloc);
                        goto success;
                }
@@ -540,9 +541,8 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size,
                TRACE_MEM("Brand new sgv_obj %p", obj);
                if (order <= sgv_pools_mgr.sgv_max_local_order) {
                        obj->sg_entries = obj->sg_entries_data;
+                       sg_init_table(obj->sg_entries, pages_to_alloc);
                        TRACE_MEM("sg_entries %p", obj->sg_entries);
-                       memset(obj->sg_entries, 0,
-                               pages_to_alloc*sizeof(obj->sg_entries[0]));
                        if (pool->clustered) {
                                obj->trans_tbl = (struct trans_tbl_ent*)
                                        (obj->sg_entries + pages_to_alloc);
@@ -572,16 +572,19 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size,
                        goto out_return2;
                cache = NULL;
                sz = sizeof(*obj) + pages*sizeof(obj->sg_entries[0]);
-               obj = kzalloc(sz, gfp_mask);
+               obj = kmalloc(sz, gfp_mask);
                if (unlikely(obj == NULL)) {
                        TRACE(TRACE_OUT_OF_MEM, "Allocation of "
                                "sgv_pool_obj failed (size %d)", size);
                        goto out_fail;
                }
+               memset(obj, 0, sizeof(*obj));
                obj->owner_pool = pool;
                obj->order = -1 - order;
-               obj->sg_entries = obj->sg_entries_data;
                obj->allocator_priv = priv;
+
+               obj->sg_entries = obj->sg_entries_data;
+               sg_init_table(obj->sg_entries, pages);
                
                if (sgv_pool_hiwmk_check(pages_to_alloc, no_fail) != 0)
                        goto out_fail_free_sg_entries;
@@ -600,7 +603,6 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size,
        }
 
 success:
-       atomic_inc(&pool->acc.total_alloc);
        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);
@@ -728,10 +730,12 @@ struct scatterlist *scst_alloc(int size, unsigned long gfp_mask, int *count)
                goto out;
        }
 
-       res = kzalloc(pages*sizeof(*res), gfp_mask);
+       res = kmalloc(pages*sizeof(*res), gfp_mask);
        if (res == NULL)
                goto out;
 
+       sg_init_table(res, pages);
+
        /*
         * If we allow use clustering here, we will have troubles in
         * scst_free() to figure out how many pages are in the SG vector.
@@ -791,8 +795,6 @@ int sgv_pool_init(struct sgv_pool *pool, const char *name, int clustered)
 
        atomic_set(&pool->acc.other_alloc, 0);
        atomic_set(&pool->acc.big_alloc, 0);
-       atomic_set(&pool->acc.total_alloc, 0);
-       atomic_set(&pool->acc.hit_alloc, 0);
 
        pool->clustered = clustered;
        pool->alloc_fns.alloc_pages_fn = scst_alloc_sys_pages;
@@ -1058,8 +1060,8 @@ int scst_sgv_pools_init(unsigned long mem_hwmark, unsigned long mem_lwmark)
        int res;
        struct scst_sgv_pools_manager *pools = &sgv_pools_mgr;
 
-
        TRACE_ENTRY();
+
        memset(pools, 0, sizeof(*pools));
 
        sgv_pools_mgr.mgr.thr.hi_wmk = mem_hwmark >> PAGE_SHIFT;
@@ -1154,11 +1156,15 @@ void scst_sgv_pools_deinit(void)
 
 static void scst_do_sgv_read(struct seq_file *seq, const struct sgv_pool *pool)
 {
-       int i;
+       int i, total = 0, hit = 0;
+       for(i = 0; i < SGV_POOL_ELEMENTS; i++) {
+               hit += atomic_read(&pool->cache_acc[i].hit_alloc);
+               total += atomic_read(&pool->cache_acc[i].total_alloc);
+       }
 
        seq_printf(seq, "\n%-30s %-11d %-11d %d/%d (P/O)\n", pool->name,
-               atomic_read(&pool->acc.hit_alloc),
-               atomic_read(&pool->acc.total_alloc),
+               hit, total,
                pool->acc.cached_pages,
                pool->acc.cached_entries);
 
index e1da646..42a4268 100644 (file)
@@ -52,7 +52,6 @@ struct sgv_pool_obj
 
 struct sgv_pool_acc
 {
-       atomic_t total_alloc, hit_alloc;
        u32 cached_pages, cached_entries;
        atomic_t big_alloc, other_alloc;
 };
index 772fa7f..5f3fccc 100644 (file)
@@ -1211,10 +1211,10 @@ static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state)
                        int i;
                        struct scatterlist *sg = cmd->sg;
                        TRACE_RECV_TOP("Exec'd %d S/G(s) at %p sg[0].page at "
-                               "%p", cmd->sg_cnt, sg, (void*)sg[0].page);
+                               "%p", cmd->sg_cnt, sg, (void*)sg_page(&sg[0]));
                        for(i = 0; i < cmd->sg_cnt; ++i) {
                                TRACE_BUFF_FLAG(TRACE_RCV_TOP, 
-                                       "Exec'd sg", page_address(sg[i].page),
+                                       "Exec'd sg", sg_virt(&sg[i]),
                                        sg[i].length);
                        }
                }
@@ -2553,10 +2553,10 @@ static int scst_xmit_response(struct scst_cmd *cmd)
                        int i;
                        struct scatterlist *sg = cmd->sg;
                        TRACE_SEND_BOT("Xmitting %d S/G(s) at %p sg[0].page at %p",
-                             cmd->sg_cnt, sg, (void*)sg[0].page);
+                             cmd->sg_cnt, sg, (void*)sg_page(&sg[0]));
                        for(i = 0; i < cmd->sg_cnt; ++i) {
                                TRACE_BUFF_FLAG(TRACE_SND_BOT,
-                                   "Xmitting sg", page_address(sg[i].page),
+                                   "Xmitting sg", sg_virt(&sg[i]),
                                    sg[i].length);
                        }
                }