- Update to work on 2.6.24

- Minor cleanups


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@251 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Vladislav Bolkhovitin
2008-01-31 18:28:43 +00:00
parent d2d1b2ccf1
commit 7d18a8a3e2
15 changed files with 236 additions and 154 deletions
+5 -10
View 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);
+22 -4
View 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);
#else
nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv, NULL,
nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv,
THIS_MODULE);
#else
#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");
+8 -7
View 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;
+32 -30
View 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 */
+7 -6
View 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 "
+3 -3
View File
@@ -69,10 +69,10 @@
#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 */
+2 -2
View 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",
+86 -2
View File
@@ -36,6 +36,10 @@
#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;
+5 -6
View 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)
+28 -12
View 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) {
int len, bytes, off, thislen;
struct page *page;
page = sgl[j].page;
off = sgl[j].offset;
len = sgl[j].length;
length = scst_get_buf_first(cmd, &address);
while(length > 0) {
int len, bytes, off, thislen;
uint8_t *addr;
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 */
-38
View 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)
+1 -2
View 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);
+33 -27
View 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);
-1
View 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;
};
+4 -4
View 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);
}
}