mirror of
https://github.com/SCST-project/scst.git
synced 2026-07-20 06:52:18 +00:00
- Update for 2.6.37
- Docs updated - Returning of DIRECT contexts by scst_estimate_context() disabled (see comment in the patch why) git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3203 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
Summary of changes between versions 2.0.0 and 2.1.0
|
||||
---------------------------------------------------
|
||||
|
||||
- Update to 2.6.37
|
||||
|
||||
- Assigning CPU affinity to RD/WR threads added
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
|
||||
--- a/include/linux/mm_types.h
|
||||
+++ b/include/linux/mm_types.h
|
||||
diff -upkr linux-2.6.37/include/linux/mm_types.h linux-2.6.37/include/linux/mm_types.h
|
||||
--- linux-2.6.37/include/linux/mm_types.h 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/include/linux/mm_types.h 2011-01-08 16:43:27.966430897 +0300
|
||||
@@ -100,6 +100,18 @@ struct page {
|
||||
*/
|
||||
void *shadow;
|
||||
@@ -20,9 +20,9 @@ diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
|
||||
};
|
||||
|
||||
/*
|
||||
diff --git a/include/linux/net.h b/include/linux/net.h
|
||||
--- a/include/linux/net.h
|
||||
+++ b/include/linux/net.h
|
||||
diff -upkr linux-2.6.37/include/linux/net.h linux-2.6.37/include/linux/net.h
|
||||
--- linux-2.6.37/include/linux/net.h 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/include/linux/net.h 2011-01-08 16:43:27.966430897 +0300
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <linux/socket.h>
|
||||
@@ -31,7 +31,7 @@ diff --git a/include/linux/net.h b/include/linux/net.h
|
||||
|
||||
#define NPROTO AF_MAX
|
||||
|
||||
@@ -293,5 +294,44 @@ extern int kernel_sock_shutdown(struct socket *sock,
|
||||
@@ -293,5 +294,44 @@ extern int kernel_sock_shutdown(struct s
|
||||
extern struct ratelimit_state net_ratelimit_state;
|
||||
#endif
|
||||
|
||||
@@ -76,9 +76,9 @@ diff --git a/include/linux/net.h b/include/linux/net.h
|
||||
+
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _LINUX_NET_H */
|
||||
diff --git a/net/core/dev.c b/net/core/dev.c
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
diff -upkr linux-2.6.37/net/core/dev.c linux-2.6.37/net/core/dev.c
|
||||
--- linux-2.6.37/net/core/dev.c 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/net/core/dev.c 2011-01-08 16:43:27.970432318 +0300
|
||||
@@ -3225,7 +3225,7 @@ pull:
|
||||
skb_shinfo(skb)->frags[0].size -= grow;
|
||||
|
||||
@@ -88,10 +88,10 @@ diff --git a/net/core/dev.c b/net/core/dev.c
|
||||
memmove(skb_shinfo(skb)->frags,
|
||||
skb_shinfo(skb)->frags + 1,
|
||||
--skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t));
|
||||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
--- a/net/core/skbuff.c
|
||||
+++ b/net/core/skbuff.c
|
||||
@@ -76,13 +76,13 @@ static struct kmem_cache *skbuff_fclone_cache __read_mostly;
|
||||
diff -upkr linux-2.6.37/net/core/skbuff.c linux-2.6.37/net/core/skbuff.c
|
||||
--- linux-2.6.37/net/core/skbuff.c 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/net/core/skbuff.c 2011-01-08 16:43:59.575095480 +0300
|
||||
@@ -76,13 +76,13 @@ static struct kmem_cache *skbuff_fclone_
|
||||
static void sock_pipe_buf_release(struct pipe_inode_info *pipe,
|
||||
struct pipe_buffer *buf)
|
||||
{
|
||||
@@ -107,7 +107,7 @@ diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
}
|
||||
|
||||
static int sock_pipe_buf_steal(struct pipe_inode_info *pipe,
|
||||
@@ -324,7 +324,7 @@ static void skb_release_data(struct sk_buff *skb)
|
||||
@@ -324,7 +324,7 @@ static void skb_release_data(struct sk_b
|
||||
if (skb_shinfo(skb)->nr_frags) {
|
||||
int i;
|
||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
|
||||
@@ -116,7 +116,7 @@ diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
}
|
||||
|
||||
if (skb_has_frag_list(skb))
|
||||
@@ -730,7 +730,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
|
||||
@@ -730,7 +730,7 @@ struct sk_buff *pskb_copy(struct sk_buff
|
||||
|
||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
|
||||
skb_shinfo(n)->frags[i] = skb_shinfo(skb)->frags[i];
|
||||
@@ -125,7 +125,7 @@ diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
}
|
||||
skb_shinfo(n)->nr_frags = i;
|
||||
}
|
||||
@@ -806,7 +806,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
|
||||
@@ -806,7 +806,7 @@ int pskb_expand_head(struct sk_buff *skb
|
||||
kfree(skb->head);
|
||||
} else {
|
||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
|
||||
@@ -179,7 +179,7 @@ diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
|
||||
return p;
|
||||
}
|
||||
@@ -1409,7 +1409,7 @@ static inline int spd_fill_page(struct splice_pipe_desc *spd,
|
||||
@@ -1409,7 +1409,7 @@ static inline int spd_fill_page(struct s
|
||||
if (!page)
|
||||
return 1;
|
||||
} else
|
||||
@@ -188,7 +188,7 @@ diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
|
||||
spd->pages[spd->nr_pages] = page;
|
||||
spd->partial[spd->nr_pages].len = *len;
|
||||
@@ -2042,7 +2042,7 @@ static inline void skb_split_no_header(struct sk_buff *skb,
|
||||
@@ -2042,7 +2042,7 @@ static inline void skb_split_no_header(s
|
||||
* where splitting is expensive.
|
||||
* 2. Split is accurately. We make this.
|
||||
*/
|
||||
@@ -197,7 +197,7 @@ diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
skb_shinfo(skb1)->frags[0].page_offset += len - pos;
|
||||
skb_shinfo(skb1)->frags[0].size -= len - pos;
|
||||
skb_shinfo(skb)->frags[i].size = len - pos;
|
||||
@@ -2164,7 +2164,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
|
||||
@@ -2164,7 +2164,7 @@ int skb_shift(struct sk_buff *tgt, struc
|
||||
to++;
|
||||
|
||||
} else {
|
||||
@@ -206,7 +206,7 @@ diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
fragto->page = fragfrom->page;
|
||||
fragto->page_offset = fragfrom->page_offset;
|
||||
fragto->size = todo;
|
||||
@@ -2186,7 +2186,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen)
|
||||
@@ -2186,7 +2186,7 @@ int skb_shift(struct sk_buff *tgt, struc
|
||||
fragto = &skb_shinfo(tgt)->frags[merge];
|
||||
|
||||
fragto->size += fragfrom->size;
|
||||
@@ -215,7 +215,7 @@ diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
}
|
||||
|
||||
/* Reposition in the original skb */
|
||||
@@ -2587,7 +2587,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
|
||||
@@ -2587,7 +2587,7 @@ struct sk_buff *skb_segment(struct sk_bu
|
||||
|
||||
while (pos < offset + len && i < nfrags) {
|
||||
*frag = skb_shinfo(skb)->frags[i];
|
||||
@@ -224,9 +224,9 @@ diff --git a/net/core/skbuff.c b/net/core/skbuff.c
|
||||
size = frag->size;
|
||||
|
||||
if (pos < offset) {
|
||||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
|
||||
--- a/net/ipv4/ip_output.c
|
||||
+++ b/net/ipv4/ip_output.c
|
||||
diff -upkr linux-2.6.37/net/ipv4/ip_output.c linux-2.6.37/net/ipv4/ip_output.c
|
||||
--- linux-2.6.37/net/ipv4/ip_output.c 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/net/ipv4/ip_output.c 2011-01-08 16:43:27.974431382 +0300
|
||||
@@ -1042,7 +1042,7 @@ alloc_new_skb:
|
||||
err = -EMSGSIZE;
|
||||
goto error;
|
||||
@@ -236,7 +236,7 @@ diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
|
||||
skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0);
|
||||
frag = &skb_shinfo(skb)->frags[i];
|
||||
}
|
||||
@@ -1201,7 +1201,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
|
||||
@@ -1201,7 +1201,7 @@ ssize_t ip_append_page(struct sock *sk,
|
||||
if (skb_can_coalesce(skb, i, page, offset)) {
|
||||
skb_shinfo(skb)->frags[i-1].size += len;
|
||||
} else if (i < MAX_SKB_FRAGS) {
|
||||
@@ -245,9 +245,9 @@ diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
|
||||
skb_fill_page_desc(skb, i, page, offset, len);
|
||||
} else {
|
||||
err = -EMSGSIZE;
|
||||
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
|
||||
--- a/net/ipv4/Makefile
|
||||
+++ b/net/ipv4/Makefile
|
||||
diff -upkr linux-2.6.37/net/ipv4/Makefile linux-2.6.37/net/ipv4/Makefile
|
||||
--- linux-2.6.37/net/ipv4/Makefile 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/net/ipv4/Makefile 2011-01-08 16:43:27.974431382 +0300
|
||||
@@ -50,6 +50,7 @@ obj-$(CONFIG_TCP_CONG_LP) += tcp_lp.o
|
||||
obj-$(CONFIG_TCP_CONG_YEAH) += tcp_yeah.o
|
||||
obj-$(CONFIG_TCP_CONG_ILLINOIS) += tcp_illinois.o
|
||||
@@ -256,9 +256,9 @@ diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
|
||||
|
||||
obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
|
||||
xfrm4_output.o
|
||||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
|
||||
--- a/net/ipv4/tcp.c
|
||||
+++ b/net/ipv4/tcp.c
|
||||
diff -upkr linux-2.6.37/net/ipv4/tcp.c linux-2.6.37/net/ipv4/tcp.c
|
||||
--- linux-2.6.37/net/ipv4/tcp.c 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/net/ipv4/tcp.c 2011-01-08 16:43:27.974431382 +0300
|
||||
@@ -806,7 +806,7 @@ new_segment:
|
||||
if (can_coalesce) {
|
||||
skb_shinfo(skb)->frags[i - 1].size += copy;
|
||||
@@ -289,10 +289,10 @@ diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
|
||||
TCP_PAGE(sk) = page;
|
||||
}
|
||||
}
|
||||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
|
||||
--- a/net/ipv4/tcp_output.c
|
||||
+++ b/net/ipv4/tcp_output.c
|
||||
@@ -1080,7 +1080,7 @@ static void __pskb_trim_head(struct sk_buff *skb, int len)
|
||||
diff -upkr linux-2.6.37/net/ipv4/tcp_output.c linux-2.6.37/net/ipv4/tcp_output.c
|
||||
--- linux-2.6.37/net/ipv4/tcp_output.c 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/net/ipv4/tcp_output.c 2011-01-08 16:43:27.974431382 +0300
|
||||
@@ -1082,7 +1082,7 @@ static void __pskb_trim_head(struct sk_b
|
||||
k = 0;
|
||||
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
|
||||
if (skb_shinfo(skb)->frags[i].size <= eat) {
|
||||
@@ -301,10 +301,9 @@ diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
|
||||
eat -= skb_shinfo(skb)->frags[i].size;
|
||||
} else {
|
||||
skb_shinfo(skb)->frags[k] = skb_shinfo(skb)->frags[i];
|
||||
diff --git a/net/ipv4/tcp_zero_copy.c b/net/ipv4/tcp_zero_copy.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/net/ipv4/tcp_zero_copy.c
|
||||
diff -upkr linux-2.6.37/net/ipv4/tcp_zero_copy.c linux-2.6.37/net/ipv4/tcp_zero_copy.c
|
||||
--- linux-2.6.37/net/ipv4/tcp_zero_copy.c 2011-01-10 18:06:50.466106393 +0300
|
||||
+++ linux-2.6.37/net/ipv4/tcp_zero_copy.c 2011-01-08 16:43:27.978431250 +0300
|
||||
@@ -0,0 +1,49 @@
|
||||
+/*
|
||||
+ * Support routines for TCP zero copy transmit
|
||||
@@ -355,10 +354,10 @@ new file mode 100644
|
||||
+ return res;
|
||||
+}
|
||||
+EXPORT_SYMBOL(net_set_get_put_page_callbacks);
|
||||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
|
||||
--- a/net/ipv6/ip6_output.c
|
||||
+++ b/net/ipv6/ip6_output.c
|
||||
@@ -1391,7 +1391,7 @@ alloc_new_skb:
|
||||
diff -upkr linux-2.6.37/net/ipv6/ip6_output.c linux-2.6.37/net/ipv6/ip6_output.c
|
||||
--- linux-2.6.37/net/ipv6/ip6_output.c 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/net/ipv6/ip6_output.c 2011-01-08 16:43:27.978431250 +0300
|
||||
@@ -1383,7 +1383,7 @@ alloc_new_skb:
|
||||
err = -EMSGSIZE;
|
||||
goto error;
|
||||
}
|
||||
@@ -367,9 +366,9 @@ diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
|
||||
skb_fill_page_desc(skb, i, page, sk->sk_sndmsg_off, 0);
|
||||
frag = &skb_shinfo(skb)->frags[i];
|
||||
}
|
||||
diff --git a/net/Kconfig b/net/Kconfig
|
||||
--- a/net/Kconfig
|
||||
+++ b/net/Kconfig
|
||||
diff -upkr linux-2.6.37/net/Kconfig linux-2.6.37/net/Kconfig
|
||||
--- linux-2.6.37/net/Kconfig 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/net/Kconfig 2011-01-08 16:43:27.978431250 +0300
|
||||
@@ -72,6 +72,18 @@ config INET
|
||||
|
||||
Short answer: say Y.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
Summary of changes between versions 2.0.0 and 2.1.0
|
||||
---------------------------------------------------
|
||||
|
||||
- Update to 2.6.37
|
||||
|
||||
- Complete NPIV support added. Particularly, now SCST core sees
|
||||
all the virtual targets and provide separate target-oriented access
|
||||
control for them. Thanks a lot to Uri Yanai and Dorit
|
||||
|
||||
+16
-6
@@ -129,10 +129,14 @@ static int qla2xxx_slave_alloc(struct scsi_device *);
|
||||
static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
|
||||
static void qla2xxx_scan_start(struct Scsi_Host *);
|
||||
static void qla2xxx_slave_destroy(struct scsi_device *);
|
||||
static int qla2x00_queuecommand(struct scsi_cmnd *cmd,
|
||||
static int qla2x00_queuecommand_lck(struct scsi_cmnd *cmd,
|
||||
void (*fn)(struct scsi_cmnd *));
|
||||
static int qla24xx_queuecommand(struct scsi_cmnd *cmd,
|
||||
static int qla24xx_queuecommand_lck(struct scsi_cmnd *cmd,
|
||||
void (*fn)(struct scsi_cmnd *));
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
|
||||
static DEF_SCSI_QCMD(qla2x00_queuecommand);
|
||||
static DEF_SCSI_QCMD(qla24xx_queuecommand);
|
||||
#endif
|
||||
static int qla2xxx_eh_abort(struct scsi_cmnd *);
|
||||
static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
|
||||
static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
|
||||
@@ -150,7 +154,11 @@ static int qla2x00_change_queue_type(struct scsi_device *, int);
|
||||
static struct scsi_host_template qla2x00_driver_template = {
|
||||
.module = THIS_MODULE,
|
||||
.name = QLA2XXX_DRIVER_NAME,
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
|
||||
.queuecommand = qla2x00_queuecommand_lck,
|
||||
#else
|
||||
.queuecommand = qla2x00_queuecommand,
|
||||
#endif
|
||||
|
||||
.eh_abort_handler = qla2xxx_eh_abort,
|
||||
.eh_device_reset_handler = qla2xxx_eh_device_reset,
|
||||
@@ -186,7 +194,11 @@ static struct scsi_host_template qla2x00_driver_template = {
|
||||
struct scsi_host_template qla24xx_driver_template = {
|
||||
.module = THIS_MODULE,
|
||||
.name = QLA2XXX_DRIVER_NAME,
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
|
||||
.queuecommand = qla24xx_queuecommand_lck,
|
||||
#else
|
||||
.queuecommand = qla24xx_queuecommand,
|
||||
#endif
|
||||
|
||||
.eh_abort_handler = qla2xxx_eh_abort,
|
||||
.eh_device_reset_handler = qla2xxx_eh_device_reset,
|
||||
@@ -415,7 +427,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *ha, fc_port_t *fcport,
|
||||
}
|
||||
|
||||
static int
|
||||
qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
|
||||
qla2x00_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
|
||||
{
|
||||
scsi_qla_host_t *ha = shost_priv(cmd->device->host);
|
||||
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
|
||||
@@ -479,9 +491,8 @@ qc_fail_command:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
|
||||
qla24xx_queuecommand_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
|
||||
{
|
||||
scsi_qla_host_t *ha = shost_priv(cmd->device->host);
|
||||
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
|
||||
@@ -546,7 +557,6 @@ qc24_fail_command:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* qla2x00_eh_wait_on_command
|
||||
* Waits for the command to be returned by the Firmware for some
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
Summary of changes between versions 2.0.0 and 2.1.0
|
||||
---------------------------------------------------
|
||||
|
||||
- Update to 2.6.37
|
||||
|
||||
- Assigning CPU affinity to threads and connections added
|
||||
|
||||
- Splitting of read/write CDBs for pass-through devices with sg_tablesize
|
||||
|
||||
+9
-6
@@ -217,13 +217,13 @@ allows to work directly over a block device, e.g. local IDE or SCSI disk
|
||||
or ever disk partition, where there is no file systems overhead. Using
|
||||
block devices comparing to sending SCSI commands directly to SCSI
|
||||
mid-level via scsi_do_req()/scsi_execute_async() has advantage that data
|
||||
are transferred via system cache, so it is possible to fully benefit from
|
||||
caching and read ahead performed by Linux's VM subsystem. The only
|
||||
are transferred via system cache, so it is possible to fully benefit
|
||||
from caching and read ahead performed by Linux's VM subsystem. The only
|
||||
disadvantage here that in the FILEIO mode there is superfluous data
|
||||
copying between the cache and SCST's buffers. This issue is going to be
|
||||
addressed in the next release. Virtual CDROM's are useful for remote
|
||||
installation. See below for details how to setup and use VDISK device
|
||||
handler.
|
||||
addressed in one of the future releases. Virtual CDROM's are useful for
|
||||
remote installation. See below for details how to setup and use VDISK
|
||||
device handler.
|
||||
|
||||
SCST user space device handler provides an interface between SCST and
|
||||
the user space, which allows to create pure user space devices. The
|
||||
@@ -1437,7 +1437,10 @@ sessions, which is enough.
|
||||
device.
|
||||
|
||||
Note2: you need to restart SCST after you changed read-ahead settings
|
||||
on the target.
|
||||
on the target. It is a limitation of the Linux read ahead
|
||||
implementation. It reads RA values for each file only when the file
|
||||
is open and not updates them when the global RA parameters changed.
|
||||
Hence, the need for vdisk to reopen all its files/devices.
|
||||
|
||||
- You may need to increase amount of requests that OS on initiator
|
||||
sends to the target device. To do it on Linux initiators, run
|
||||
|
||||
+9
-6
@@ -118,13 +118,13 @@ allows to work directly over a block device, e.g. local IDE or SCSI disk
|
||||
or ever disk partition, where there is no file systems overhead. Using
|
||||
block devices comparing to sending SCSI commands directly to SCSI
|
||||
mid-level via scsi_do_req()/scsi_execute_async() has advantage that data
|
||||
are transferred via system cache, so it is possible to fully benefit from
|
||||
caching and read ahead performed by Linux's VM subsystem. The only
|
||||
are transferred via system cache, so it is possible to fully benefit
|
||||
from caching and read ahead performed by Linux's VM subsystem. The only
|
||||
disadvantage here that in the FILEIO mode there is superfluous data
|
||||
copying between the cache and SCST's buffers. This issue is going to be
|
||||
addressed in the next release. Virtual CDROM's are useful for remote
|
||||
installation. See below for details how to setup and use VDISK device
|
||||
handler.
|
||||
addressed in one of the future releases. Virtual CDROM's are useful for
|
||||
remote installation. See below for details how to setup and use VDISK
|
||||
device handler.
|
||||
|
||||
"Performance" device handlers for disks, MO disks and tapes in their
|
||||
exec() method skip (pretend to execute) all READ and WRITE operations
|
||||
@@ -1257,7 +1257,10 @@ sessions, which is enough.
|
||||
device.
|
||||
|
||||
Note2: you need to restart SCST after you changed read-ahead settings
|
||||
on the target.
|
||||
on the target. It is a limitation of the Linux read ahead
|
||||
implementation. It reads RA values for each file only when the file
|
||||
is open and not updates them when the global RA parameters changed.
|
||||
Hence, the need for vdisk to reopen all its files/devices.
|
||||
|
||||
- You may need to increase amount of requests that OS on initiator
|
||||
sends to the target device. To do it on Linux initiators, run
|
||||
|
||||
+25
-9
@@ -2819,17 +2819,21 @@ static inline void scst_sess_set_tgt_priv(struct scst_session *sess,
|
||||
/**
|
||||
* Returns TRUE if cmd is being executed in atomic context.
|
||||
*
|
||||
* Note: checkpatch will complain on the use of in_atomic() below. You can
|
||||
* safely ignore this warning since in_atomic() is used here only for debugging
|
||||
* purposes.
|
||||
* This function must be used outside of spinlocks and preempt/BH/IRQ
|
||||
* disabled sections, because of the EXTRACHECK in it.
|
||||
*/
|
||||
static inline bool scst_cmd_atomic(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = cmd->atomic;
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
/*
|
||||
* Checkpatch will complain on the use of in_atomic() below. You
|
||||
* can safely ignore this warning since in_atomic() is used here
|
||||
* only for debugging purposes.
|
||||
*/
|
||||
if (unlikely((in_atomic() || in_interrupt() || irqs_disabled()) &&
|
||||
!res)) {
|
||||
printk(KERN_ERR "ERROR: atomic context and non-atomic cmd\n");
|
||||
printk(KERN_ERR "ERROR: atomic context and non-atomic cmd!\n");
|
||||
dump_stack();
|
||||
cmd->atomic = 1;
|
||||
res = 1;
|
||||
@@ -2847,25 +2851,37 @@ static inline bool scst_cmd_prelim_completed(struct scst_cmd *cmd)
|
||||
return cmd->completed || test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags);
|
||||
}
|
||||
|
||||
static inline enum scst_exec_context __scst_estimate_context(bool direct)
|
||||
static inline enum scst_exec_context __scst_estimate_context(bool atomic)
|
||||
{
|
||||
if (in_irq())
|
||||
return SCST_CONTEXT_TASKLET;
|
||||
/*
|
||||
* We come here from many non reliable places, like the block layer, and don't
|
||||
* have any reliable way to detect if we called under atomic context or not
|
||||
* (in_atomic() isn't reliable), so let's be safe and disable this section
|
||||
* for now to unconditionally return thread context.
|
||||
*/
|
||||
#if 0
|
||||
else if (irqs_disabled())
|
||||
return SCST_CONTEXT_THREAD;
|
||||
else if (in_atomic())
|
||||
return SCST_CONTEXT_DIRECT_ATOMIC;
|
||||
else
|
||||
return direct ? SCST_CONTEXT_DIRECT :
|
||||
return atomic ? SCST_CONTEXT_DIRECT :
|
||||
SCST_CONTEXT_DIRECT_ATOMIC;
|
||||
#else
|
||||
return SCST_CONTEXT_THREAD;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline enum scst_exec_context scst_estimate_context(void)
|
||||
{
|
||||
return __scst_estimate_context(0);
|
||||
return __scst_estimate_context(false);
|
||||
}
|
||||
|
||||
static inline enum scst_exec_context scst_estimate_context_direct(void)
|
||||
static inline enum scst_exec_context scst_estimate_context_atomic(void)
|
||||
{
|
||||
return __scst_estimate_context(1);
|
||||
return __scst_estimate_context(true);
|
||||
}
|
||||
|
||||
/* Returns cmd's CDB */
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
diff --git a/block/blk-map.c b/block/blk-map.c
|
||||
index 5d5dbe4..bc036bc 100644
|
||||
--- a/block/blk-map.c
|
||||
+++ b/block/blk-map.c
|
||||
diff -upkr linux-2.6.37/block/blk-map.c linux-2.6.37/block/blk-map.c
|
||||
--- linux-2.6.37/block/blk-map.c 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/block/blk-map.c 2011-01-08 16:45:54.350430208 +0300
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/bio.h>
|
||||
@@ -11,7 +10,7 @@ index 5d5dbe4..bc036bc 100644
|
||||
#include <scsi/sg.h> /* for struct sg_iovec */
|
||||
|
||||
#include "blk.h"
|
||||
@@ -273,6 +275,337 @@ int blk_rq_unmap_user(struct bio *bio)
|
||||
@@ -274,6 +276,337 @@ int blk_rq_unmap_user(struct bio *bio)
|
||||
}
|
||||
EXPORT_SYMBOL(blk_rq_unmap_user);
|
||||
|
||||
@@ -349,11 +348,10 @@ index 5d5dbe4..bc036bc 100644
|
||||
/**
|
||||
* blk_rq_map_kern - map kernel data to a request, for REQ_TYPE_BLOCK_PC usage
|
||||
* @q: request queue where request should be inserted
|
||||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
|
||||
index aae86fd..c9a438e 100644
|
||||
--- a/include/linux/blkdev.h
|
||||
+++ b/include/linux/blkdev.h
|
||||
@@ -589,6 +589,8 @@ extern unsigned long blk_max_low_pfn, blk_max_pfn;
|
||||
diff -upkr linux-2.6.37/include/linux/blkdev.h linux-2.6.37/include/linux/blkdev.h
|
||||
--- linux-2.6.37/include/linux/blkdev.h 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/include/linux/blkdev.h 2011-01-08 16:45:54.350430208 +0300
|
||||
@@ -592,6 +592,8 @@ extern unsigned long blk_max_low_pfn, bl
|
||||
#define BLK_DEFAULT_SG_TIMEOUT (60 * HZ)
|
||||
#define BLK_MIN_SG_TIMEOUT (7 * HZ)
|
||||
|
||||
@@ -362,7 +360,7 @@ index aae86fd..c9a438e 100644
|
||||
#ifdef CONFIG_BOUNCE
|
||||
extern int init_emergency_isa_pool(void);
|
||||
extern void blk_queue_bounce(struct request_queue *q, struct bio **bio);
|
||||
@@ -706,6 +708,9 @@ extern int blk_rq_map_kern(struct request_queue *, struct request *, void *, uns
|
||||
@@ -709,6 +711,9 @@ extern int blk_rq_map_kern(struct reques
|
||||
extern int blk_rq_map_user_iov(struct request_queue *, struct request *,
|
||||
struct rq_map_data *, struct sg_iovec *, int,
|
||||
unsigned int, gfp_t);
|
||||
@@ -372,10 +370,9 @@ index aae86fd..c9a438e 100644
|
||||
extern int blk_execute_rq(struct request_queue *, struct gendisk *,
|
||||
struct request *, int);
|
||||
extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *,
|
||||
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
|
||||
index 9aaf5bf..0177996 100644
|
||||
--- a/include/linux/scatterlist.h
|
||||
+++ b/include/linux/scatterlist.h
|
||||
diff -upkr linux-2.6.37/include/linux/scatterlist.h linux-2.6.37/include/linux/scatterlist.h
|
||||
--- linux-2.6.37/include/linux/scatterlist.h 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/include/linux/scatterlist.h 2011-01-08 16:45:54.354431761 +0300
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <asm/types.h>
|
||||
@@ -384,7 +381,7 @@ index 9aaf5bf..0177996 100644
|
||||
#include <linux/mm.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/io.h>
|
||||
@@ -218,6 +219,10 @@ size_t sg_copy_from_buffer(struct scatterlist *sgl, unsigned int nents,
|
||||
@@ -218,6 +219,10 @@ size_t sg_copy_from_buffer(struct scatte
|
||||
size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents,
|
||||
void *buf, size_t buflen);
|
||||
|
||||
@@ -395,11 +392,10 @@ index 9aaf5bf..0177996 100644
|
||||
/*
|
||||
* Maximum number of entries that will be allocated in one piece, if
|
||||
* a list larger than this is required then chaining will be utilized.
|
||||
diff --git a/lib/scatterlist.c b/lib/scatterlist.c
|
||||
index 4ceb05d..caf58c4 100644
|
||||
--- a/lib/scatterlist.c
|
||||
+++ b/lib/scatterlist.c
|
||||
@@ -517,3 +517,132 @@ size_t sg_copy_to_buffer(struct scatterlist *sgl, unsigned int nents,
|
||||
diff -upkr linux-2.6.37/lib/scatterlist.c linux-2.6.37/lib/scatterlist.c
|
||||
--- linux-2.6.37/lib/scatterlist.c 2011-01-05 03:50:19.000000000 +0300
|
||||
+++ linux-2.6.37/lib/scatterlist.c 2011-01-08 16:45:54.401930472 +0300
|
||||
@@ -517,3 +517,132 @@ size_t sg_copy_to_buffer(struct scatterl
|
||||
return sg_copy_buffer(sgl, nents, buf, buflen, 1);
|
||||
}
|
||||
EXPORT_SYMBOL(sg_copy_to_buffer);
|
||||
@@ -532,3 +528,4 @@ index 4ceb05d..caf58c4 100644
|
||||
+ return res;
|
||||
+}
|
||||
+EXPORT_SYMBOL(sg_copy);
|
||||
|
||||
|
||||
@@ -3974,8 +3974,7 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic)
|
||||
* for debugging purposes.
|
||||
*/
|
||||
EXTRACHECKS_BUG_ON(in_irq() || irqs_disabled());
|
||||
EXTRACHECKS_WARN_ON((in_atomic() || in_interrupt() || irqs_disabled()) &&
|
||||
!atomic);
|
||||
EXTRACHECKS_WARN_ON((in_atomic() || in_interrupt()) && !atomic);
|
||||
|
||||
cmd->atomic = atomic;
|
||||
|
||||
|
||||
@@ -225,6 +225,24 @@ user space:
|
||||
For other connected initiators steps 3-6 should be repeated.
|
||||
|
||||
|
||||
Compilation options
|
||||
===================
|
||||
|
||||
There are the following compilation options, that could be commented
|
||||
in/out in Makefile:
|
||||
|
||||
- CONFIG_SCST_LOCAL_FORCE_DIRECT_PROCESSING - by default, when this option
|
||||
is not defined, scst_local reschedules all commands for processing in
|
||||
one of the SCST threads. If this option is defined, scst_local tries
|
||||
to not do it, if possible (sometimes queuecommand() called under
|
||||
various locks held), but instead process them in the submitter's
|
||||
context. This is to increase performance, but as on 2.6.37 and below
|
||||
Linux block layer doesn't work with such kind of reentrance, hence
|
||||
this option disabled by default. Note! At the moment in
|
||||
scst_estimate_context*() returning DIRECT contexts disabled, so this
|
||||
option doesn't have any real effect.
|
||||
|
||||
|
||||
Change log
|
||||
==========
|
||||
|
||||
|
||||
+26
-12
@@ -86,9 +86,6 @@ static unsigned long scst_local_trace_flag = SCST_LOCAL_DEFAULT_LOG_FLAGS;
|
||||
#define scsi_bufflen(cmd) ((cmd)->request_bufflen)
|
||||
#endif
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define SCST_LOCAL_VERSION "1.0.0"
|
||||
static const char *scst_local_version_date = "20100910";
|
||||
|
||||
@@ -795,7 +792,7 @@ static int scst_local_abort(struct scsi_cmnd *SCpnt)
|
||||
sess = to_scst_lcl_sess(scsi_get_device(SCpnt->device->host));
|
||||
|
||||
ret = scst_rx_mgmt_fn_tag(sess->scst_sess, SCST_ABORT_TASK, SCpnt->tag,
|
||||
FALSE, &dev_reset_completion);
|
||||
false, &dev_reset_completion);
|
||||
|
||||
/* Now wait for the completion ... */
|
||||
wait_for_completion_interruptible(&dev_reset_completion);
|
||||
@@ -823,7 +820,7 @@ static int scst_local_device_reset(struct scsi_cmnd *SCpnt)
|
||||
lun = cpu_to_be16(SCpnt->device->lun);
|
||||
|
||||
ret = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_LUN_RESET,
|
||||
(const uint8_t *)&lun, sizeof(lun), FALSE,
|
||||
(const uint8_t *)&lun, sizeof(lun), false,
|
||||
&dev_reset_completion);
|
||||
|
||||
/* Now wait for the completion ... */
|
||||
@@ -853,7 +850,7 @@ static int scst_local_target_reset(struct scsi_cmnd *SCpnt)
|
||||
lun = cpu_to_be16(SCpnt->device->lun);
|
||||
|
||||
ret = scst_rx_mgmt_fn_lun(sess->scst_sess, SCST_TARGET_RESET,
|
||||
(const uint8_t *)&lun, sizeof(lun), FALSE,
|
||||
(const uint8_t *)&lun, sizeof(lun), false,
|
||||
&dev_reset_completion);
|
||||
|
||||
/* Now wait for the completion ... */
|
||||
@@ -952,7 +949,7 @@ static int scst_local_queuecommand_lck(struct scsi_cmnd *SCpnt,
|
||||
if (!tgt_specific) {
|
||||
PRINT_ERROR("Unable to create tgt_specific (size %zu)",
|
||||
sizeof(*tgt_specific));
|
||||
return -ENOMEM;
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
}
|
||||
tgt_specific->cmnd = SCpnt;
|
||||
tgt_specific->done = done;
|
||||
@@ -967,13 +964,17 @@ static int scst_local_queuecommand_lck(struct scsi_cmnd *SCpnt,
|
||||
/*
|
||||
* Tell the target that we have a command ... but first we need
|
||||
* to get the LUN into a format that SCST understand
|
||||
*
|
||||
* NOTE! We need to call it with atomic parameter true to not
|
||||
* get into mem alloc deadlock when mounting file systems over
|
||||
* our devices.
|
||||
*/
|
||||
lun = cpu_to_be16(SCpnt->device->lun);
|
||||
scst_cmd = scst_rx_cmd(sess->scst_sess, (const uint8_t *)&lun,
|
||||
sizeof(lun), SCpnt->cmnd, SCpnt->cmd_len, TRUE);
|
||||
sizeof(lun), SCpnt->cmnd, SCpnt->cmd_len, true);
|
||||
if (!scst_cmd) {
|
||||
PRINT_ERROR("%s", "scst_rx_cmd() failed");
|
||||
return -ENOMEM;
|
||||
return SCSI_MLQUEUE_HOST_BUSY;
|
||||
}
|
||||
|
||||
scst_cmd_set_tag(scst_cmd, SCpnt->tag);
|
||||
@@ -1065,11 +1066,20 @@ static int scst_local_queuecommand_lck(struct scsi_cmnd *SCpnt,
|
||||
scst_cmd_set_tgt_priv(scst_cmd, SCpnt);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Although starting from 2.6.37 queuecommand() called with no host_lock
|
||||
* held, in reality without DEF_SCSI_QCMD() this doesn't work and leading
|
||||
* to various problems like commands lost under highload. So, until that fixed
|
||||
* we have to go ahead under host_lock, although absolutely don't need it.
|
||||
*
|
||||
* NOTE! At the moment in scst_estimate_context*() returning DIRECT contexts
|
||||
* disabled, so this option doesn't have any real effect.
|
||||
*/
|
||||
#ifdef CONFIG_SCST_LOCAL_FORCE_DIRECT_PROCESSING
|
||||
{
|
||||
struct Scsi_Host *h = SCpnt->device->host;
|
||||
spin_unlock_irq(h->host_lock);
|
||||
scst_cmd_init_done(scst_cmd, scst_estimate_context_direct());
|
||||
scst_cmd_init_done(scst_cmd, scst_estimate_context_atomic());
|
||||
spin_lock_irq(h->host_lock);
|
||||
}
|
||||
#else
|
||||
@@ -1085,6 +1095,10 @@ static int scst_local_queuecommand_lck(struct scsi_cmnd *SCpnt,
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)
|
||||
/*
|
||||
* See comment in scst_local_queuecommand_lck() near
|
||||
* CONFIG_SCST_LOCAL_FORCE_DIRECT_PROCESSING
|
||||
*/
|
||||
static DEF_SCSI_QCMD(scst_local_queuecommand)
|
||||
#endif
|
||||
|
||||
@@ -1554,7 +1568,7 @@ static void scst_local_release_adapter(struct device *dev)
|
||||
cancel_work_sync(&sess->aen_work);
|
||||
#endif
|
||||
|
||||
scst_unregister_session(sess->scst_sess, TRUE, NULL);
|
||||
scst_unregister_session(sess->scst_sess, true, NULL);
|
||||
|
||||
kfree(sess);
|
||||
|
||||
@@ -1655,7 +1669,7 @@ unregister_dev:
|
||||
#endif
|
||||
|
||||
unregister_session:
|
||||
scst_unregister_session(sess->scst_sess, TRUE, NULL);
|
||||
scst_unregister_session(sess->scst_sess, true, NULL);
|
||||
|
||||
out_free:
|
||||
kfree(sess);
|
||||
|
||||
Reference in New Issue
Block a user