iscsi bugfixes and small cleanups
Subsystems (4)
The following patches are some small bug fixes or cleanups we have had in our tree. The patches are not critical and could just go into scsi-misc. The patches are also small and not adding features so I guess they could also go to scsi-rc-fixes if more patches are being sent for 2.6.21.
The patches were made over scsi-misc.
PATCH 1/7 flush iscsi work before freeing connection
From: Mike Christie <[email protected]>
It's possible that we call iscsi_xmitworker after iscsi_conn_release which causes a oops. This patch flushes the workqueue.
--- drivers/scsi/libiscsi.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/scsi/libiscsi.c +3 -0
@@ -1597,6 +1597,9 @@ void iscsi_conn_teardown(struct iscsi_clwake_up (&conn->ehwait); } +/* flush queued up work because we free the connection below */ +scsi_flush_work (session->host); +spin_lock_bh (&session->lock);kfree (conn->data);kfree (conn->persistent_address);
Signature · 1 line
1.4.1.1
PATCH 2/7 clear mtask
From: Mike Christie <[email protected]>
Consolidate the mtask clearing code.
--- drivers/scsi/libiscsi.c | 19 ++++++++----------- 1 files changed, 8 insertions(+), 11 deletions(-)
drivers/scsi/libiscsi.c +8 -11
@@ -577,7 +577,7 @@ void iscsi_conn_failure(struct iscsi_con }EXPORT_SYMBOL_GPL (iscsi_conn_failure); -static int iscsi_xmit_imm_task (struct iscsi_conn *conn) +static int iscsi_xmit_mtask (struct iscsi_conn *conn) {struct iscsi_hdr *hdr = conn->mtask->hdr;int rc, was_logout =0 ;
@@ -591,6 +591,9 @@ static int iscsi_xmit_imm_task(struct isif (rc)return rc; +/* done with this in-progress mtask */ + conn->mtask =NULL ; +if (was_logout) {set_bit (ISCSI_SUSPEND_BIT , &conn->suspend_tx);return -ENODATA ;
@@ -643,11 +646,9 @@ static int iscsi_data_xmit(struct iscsi_ conn->ctask =NULL ; }if (conn->mtask) { - rc =iscsi_xmit_imm_task (conn); + rc =iscsi_xmit_mtask (conn);if (rc) goto again; -/* done with this in-progress mtask */ - conn->mtask =NULL ; }/* process immediate first */
@@ -658,12 +659,10 @@ static int iscsi_data_xmit(struct iscsi_list_add_tail (&conn->mtask->running, &conn->mgmt_run_list);spin_unlock_bh (&conn->session->lock); - rc =iscsi_xmit_imm_task (conn); + rc =iscsi_xmit_mtask (conn);if (rc) goto again; } -/* done with this mtask */ - conn->mtask =NULL ; }/* process command queue */
@@ -701,12 +700,10 @@ static int iscsi_data_xmit(struct iscsi_list_add_tail (&conn->mtask->running, &conn->mgmt_run_list);spin_unlock_bh (&conn->session->lock); - rc = tt->xmit_mgmt_task (conn, conn->mtask); -if (rc) + rc =iscsi_xmit_mtask (conn); +if (rc) goto again; } -/* done with this mtask */ - conn->mtask =NULL ; }return -ENODATA ;
Signature · 1 line
1.4.1.1
PATCH 3/7 rename DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH
From: Mike Christie <[email protected]>
This patch renames DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH to avoid confusion with the drivers default values (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH is the iscsi RFC specific default).
--- drivers/infiniband/ulp/iser/iser_initiator.c | 2 +- drivers/scsi/iscsi_tcp.c | 6 +++--- drivers/scsi/libiscsi.c | 2 +- include/scsi/iscsi_proto.h | 12 +++++++++++- 4 files changed, 16 insertions(+), 6 deletions(-)
drivers/infiniband/ulp/iser/iser_initiator.c +1 -1
@@ -201,7 +201,7 @@ static int iser_post_receive_control(str* what's common for both schemes is that the connection is not started */ if (conn->c_stage !=ISCSI_CONN_STARTED ) - rx_data_size =DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH ; + rx_data_size =ISCSI_DEF_MAX_RECV_SEG_LEN ;else /* FIXME till user space sets conn->max_recv_dlength correctly */ rx_data_size =128 ;
drivers/scsi/iscsi_tcp.c +3 -3
@@ -527,12 +527,12 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *co* than 8K, but there are no targets that currently do this. * For now we fail until we find a vendor that needs it */ -if (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH < +if (ISCSI_DEF_MAX_RECV_SEG_LEN < tcp_conn->in.datalen) {printk (KERN_ERR "iscsi_tcp: received buffer of len %u " "but conn buffer is only %u (opcode %0x)\n" , tcp_conn->in.datalen, -DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH , opcode); +ISCSI_DEF_MAX_RECV_SEG_LEN , opcode); rc =ISCSI_ERR_PROTO ;break ; }
@@ -1762,7 +1762,7 @@ iscsi_tcp_conn_create(struct iscsi_cls_s* due to strange issues with iser these are not set * in iscsi_conn_setup */ - conn->max_recv_dlength =DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH ; + conn->max_recv_dlength =ISCSI_DEF_MAX_RECV_SEG_LEN ; tcp_conn =kzalloc (sizeof (*tcp_conn),GFP_KERNEL );if (!tcp_conn)
drivers/scsi/libiscsi.c +1 -1
@@ -1520,7 +1520,7 @@ iscsi_conn_setup(struct iscsi_cls_sessio }spin_unlock_bh (&session->lock); - data =kmalloc (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH ,GFP_KERNEL ); + data =kmalloc (ISCSI_DEF_MAX_RECV_SEG_LEN ,GFP_KERNEL );if (!data) goto login_mtask_data_alloc_fail; conn->login_mtask->data = conn->data = data;
include/scsi/iscsi_proto.h +11 -1
@@ -588,7 +588,17 @@ #define KEY_MAXLEN 64#define VALUE_MAXLEN 255#define TARGET_NAME_MAXLEN VALUE_MAXLEN -#define DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH 8192 +#define ISCSI_DEF_MAX_RECV_SEG_LEN 8192 +#define ISCSI_MIN_MAX_RECV_SEG_LEN 512 +#define ISCSI_MAX_MAX_RECV_SEG_LEN 16777215 + +#define ISCSI_DEF_FIRST_BURST_LEN 65536 +#define ISCSI_MIN_FIRST_BURST_LEN 512 +#define ISCSI_MAX_FIRST_BURST_LEN 16777215 + +#define ISCSI_DEF_MAX_BURST_LEN 262144 +#define ISCSI_MIN_MAX_BURST_LEN 512 +#define ISCSI_MAX_MAX_BURST_LEN 16777215/************************* RFC 3720 End *****************************/
Signature · 1 line
1.4.1.1
PATCH 4/7 use atomic for session_nr allocations
From: Mike Christie <[email protected]>
qla4xxx and iscsi_tcp or iser could be creating
sessions at the same time, so make session_nr id
allocation atomic.
--- drivers/scsi/scsi_transport_iscsi.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
drivers/scsi/scsi_transport_iscsi.c +4 -2
@@ -49,7 +49,7 @@ struct iscsi_internal {struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS +1 ]; }; -static int iscsi_session_nr;/* sysfs session id for next new session */ +static atomic_t iscsi_session_nr;/* sysfs session id for next new session */ /* * list of registered transports and lock that must
@@ -300,7 +300,7 @@ int iscsi_add_session(struct iscsi_cls_sint err; ihost = shost->shost_data; - session->sid = iscsi_session_nr++; + session->sid =atomic_add_return (1 , &iscsi_session_nr); session->target_id = target_id; snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
@@ -1419,6 +1419,8 @@ static __init int iscsi_transport_init(vprintk (KERN_INFO "Loading iSCSI transport class v%s.\n" ,ISCSI_TRANSPORT_VERSION ); +atomic_set (&iscsi_session_nr,0 ); + err =class_register (&iscsi_transport_class);if (err)return err;
Signature · 1 line
1.4.1.1
PATCH 5/7 use get_unaligned
From: Mike Christie <[email protected]>
Dave Miller meantioned that the data buffer in a past sense fixup patch was not gauranteed to be aligned properly for ia64. This patch has libiscsi use get_unalinged to make sure. There are a couple more places in the digest handling we may need to do this, but we are in the middle of fixing that code for big endien systems so just the sense access is fixed here.
--- drivers/scsi/libiscsi.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/libiscsi.c +3 -2
@@ -25,6 +25,7 @@ #include <linux/types.h>#include <linux/mutex.h> #include <linux/kfifo.h> #include <linux/delay.h> +#include <asm/unaligned.h> #include <net/tcp.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_device.h>
@@ -269,14 +270,14 @@ invalid_datalen: goto out; } - senselen =be16_to_cpu (*(__be16 *)data); + senselen =be16_to_cpu (get_unaligned ((__be16 *) data));if (datalen < senselen) goto invalid_datalen;memcpy (sc->sense_buffer, data +2 ,min_t (uint16_t, senselen,SCSI_SENSE_BUFFERSIZE ));debug_scsi ("copied %d bytes of sense\n" , -min (senselen,SCSI_SENSE_BUFFERSIZE )); +min_t (uint16_t, senselen,SCSI_SENSE_BUFFERSIZE )); }if (sc->sc_data_direction ==DMA_TO_DEVICE )
Signature · 1 line
1.4.1.1
PATCH 6/7 Increase iscsi tcp max_sectors
From: Mike Christie <[email protected]>
For a while now, the block layer has seperated max sectors and max hw sectors. Software iscsi has no limit so this patch increases max hw sectors, so we can support large pass through commands.
--- drivers/scsi/iscsi_tcp.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/scsi/iscsi_tcp.c +1 -0
@@ -2138,6 +2138,7 @@ static struct scsi_host_template iscsi_s .change_queue_depth = iscsi_change_queue_depth, .can_queue = ISCSI_XMIT_CMDS_MAX - 1, .sg_tablesize = ISCSI_SG_TABLESIZE, + .max_sectors = 0xFFFF, .cmd_per_lun = ISCSI_DEF_CMD_PER_LUN, .eh_abort_handler = iscsi_eh_abort, .eh_host_reset_handler = iscsi_eh_host_reset,
Signature · 1 line
1.4.1.1
PATCH 7/7 Print useful error message when iscsi crc23c allocation fails
From: Mike Christie <[email protected]>
People do not read the README and seem to like to unselect the crc32c module even though iscsi_tcp selects it for them. This patch spits a error that tells the user that they really do need the module. Hopefully, we will get less people asking about this now.
--- drivers/scsi/iscsi_tcp.c | 14 ++++++++++++-- 1 files changed, 12 insertions(+), 2 deletions(-)
drivers/scsi/iscsi_tcp.c +12 -2
@@ -1777,14 +1777,24 @@ iscsi_tcp_conn_create(struct iscsi_cls_s tcp_conn->tx_hash.tfm =crypto_alloc_hash ("crc32c" ,0 ,CRYPTO_ALG_ASYNC ); tcp_conn->tx_hash.flags =0 ; -if (IS_ERR (tcp_conn->tx_hash.tfm)) +if (IS_ERR (tcp_conn->tx_hash.tfm)) { +printk (KERN_ERR "Could not create connection due to crc32c " +"loading error %ld. Make sure the crc32c module is " +"built as a module or into the kernel\n" , +PTR_ERR (tcp_conn->tx_hash.tfm)); goto free_tcp_conn; + } tcp_conn->rx_hash.tfm =crypto_alloc_hash ("crc32c" ,0 ,CRYPTO_ALG_ASYNC ); tcp_conn->rx_hash.flags =0 ; -if (IS_ERR (tcp_conn->rx_hash.tfm)) +if (IS_ERR (tcp_conn->rx_hash.tfm)) { +printk (KERN_ERR "Could not create connection due to crc32c " +"loading error %ld. Make sure the crc32c module is " +"built as a module or into the kernel\n" , +PTR_ERR (tcp_conn->rx_hash.tfm)); goto free_tx_tfm; + }return cls_conn;
Signature · 1 line
1.4.1.1