Commit 30a6c652 authored by Mike Christie's avatar Mike Christie Committed by James Bottomley

[SCSI] iscsi: fix up iscsi eh

The current iscsi_tcp eh is not nicely setup for dm-multipath
and performs some extra task management functions when they
are not needed.

The attached patch:

- Fixes the TMF issues. If a session is rebuilt
then we do not send aborts.

- Fixes the problem where if the host reset fired, we would
return SUCCESS even though we had not really done anything
yet. This ends up causing problem with scsi_error.c's TUR.

- If someone has turned on the userspace nop daemon code to try
and detect network problems before the scsi command timeout
we can now drop and clean up the session before the scsi command
timesout and fires the eh speeding up the time it takes for a
command to go from one patch to another. For network problems
we fail the command with DID_BUS_BUSY so if failfast is set
scsi_decide_disposition fails the command up to dm for it to
try on another path.

- And we had to add some basic iscsi session block code. Previously
if we were trying to repair a session we would retrun a MLQUEUE code
in the queuecommand. This worked but it was not the most efficient
or pretty thing to do since it would take a while to relogin
to the target. For iscsi_tcp/open-iscsi a lot of the iscsi error handler
is in userspace the block code is pretty bare. We will be
adding to that for qla4xxx.
Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent fd7255f5
This diff is collapsed.
...@@ -159,6 +159,7 @@ struct iscsi_conn { ...@@ -159,6 +159,7 @@ struct iscsi_conn {
struct kfifo *immqueue; /* immediate xmit queue */ struct kfifo *immqueue; /* immediate xmit queue */
struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */ struct kfifo *mgmtqueue; /* mgmt (control) xmit queue */
struct kfifo *xmitqueue; /* data-path cmd queue */ struct kfifo *xmitqueue; /* data-path cmd queue */
struct list_head run_list; /* list of cmds in progress */
struct work_struct xmitwork; /* per-conn. xmit workqueue */ struct work_struct xmitwork; /* per-conn. xmit workqueue */
struct mutex xmitmutex; /* serializes connection xmit, struct mutex xmitmutex; /* serializes connection xmit,
* access to kfifos: * * access to kfifos: *
...@@ -228,6 +229,7 @@ struct iscsi_session { ...@@ -228,6 +229,7 @@ struct iscsi_session {
* - mgmtpool, * * - mgmtpool, *
* - r2tpool */ * - r2tpool */
int state; /* session state */ int state; /* session state */
int recovery_failed;
struct list_head item; struct list_head item;
void *auth_client; void *auth_client;
int conn_cnt; int conn_cnt;
...@@ -310,6 +312,7 @@ struct iscsi_cmd_task { ...@@ -310,6 +312,7 @@ struct iscsi_cmd_task {
struct iscsi_conn *conn; /* used connection */ struct iscsi_conn *conn; /* used connection */
struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */ struct iscsi_mgmt_task *mtask; /* tmf mtask in progr */
struct list_head running; /* running cmd list */
struct iscsi_r2t_info *r2t; /* in progress R2T */ struct iscsi_r2t_info *r2t; /* in progress R2T */
struct iscsi_queue r2tpool; struct iscsi_queue r2tpool;
struct kfifo *r2tqueue; struct kfifo *r2tqueue;
......
This diff is collapsed.
...@@ -174,6 +174,7 @@ enum iscsi_param { ...@@ -174,6 +174,7 @@ enum iscsi_param {
ISCSI_PARAM_TPGT, ISCSI_PARAM_TPGT,
ISCSI_PARAM_PERSISTENT_ADDRESS, ISCSI_PARAM_PERSISTENT_ADDRESS,
ISCSI_PARAM_PERSISTENT_PORT, ISCSI_PARAM_PERSISTENT_PORT,
ISCSI_PARAM_SESS_RECOVERY_TMO,
/* pased in through bind conn using transport_fd */ /* pased in through bind conn using transport_fd */
ISCSI_PARAM_CONN_PORT, ISCSI_PARAM_CONN_PORT,
...@@ -201,6 +202,7 @@ enum iscsi_param { ...@@ -201,6 +202,7 @@ enum iscsi_param {
#define ISCSI_TPGT (1 << ISCSI_PARAM_TPGT) #define ISCSI_TPGT (1 << ISCSI_PARAM_TPGT)
#define ISCSI_PERSISTENT_ADDRESS (1 << ISCSI_PARAM_PERSISTENT_ADDRESS) #define ISCSI_PERSISTENT_ADDRESS (1 << ISCSI_PARAM_PERSISTENT_ADDRESS)
#define ISCSI_PERSISTENT_PORT (1 << ISCSI_PARAM_PERSISTENT_PORT) #define ISCSI_PERSISTENT_PORT (1 << ISCSI_PARAM_PERSISTENT_PORT)
#define ISCSI_SESS_RECOVERY_TMO (1 << ISCSI_PARAM_SESS_RECOVERY_TMO)
#define ISCSI_CONN_PORT (1 << ISCSI_PARAM_CONN_PORT) #define ISCSI_CONN_PORT (1 << ISCSI_PARAM_CONN_PORT)
#define ISCSI_CONN_ADDRESS (1 << ISCSI_PARAM_CONN_ADDRESS) #define ISCSI_CONN_ADDRESS (1 << ISCSI_PARAM_CONN_ADDRESS)
......
...@@ -90,6 +90,7 @@ struct iscsi_transport { ...@@ -90,6 +90,7 @@ struct iscsi_transport {
char *data, uint32_t data_size); char *data, uint32_t data_size);
void (*get_stats) (struct iscsi_cls_conn *conn, void (*get_stats) (struct iscsi_cls_conn *conn,
struct iscsi_stats *stats); struct iscsi_stats *stats);
void (*session_recovery_timedout) (struct iscsi_cls_session *session);
}; };
/* /*
...@@ -130,12 +131,20 @@ struct iscsi_cls_conn { ...@@ -130,12 +131,20 @@ struct iscsi_cls_conn {
struct iscsi_cls_session { struct iscsi_cls_session {
struct list_head sess_list; /* item in session_list */ struct list_head sess_list; /* item in session_list */
struct list_head host_list;
struct iscsi_transport *transport; struct iscsi_transport *transport;
/* iSCSI values used as unique id by userspace. */ /* iSCSI values used as unique id by userspace. */
char *targetname; char *targetname;
int tpgt; int tpgt;
/* recovery fields */
int recovery_tmo;
struct work_struct recovery_work;
int target_id;
int channel;
int sid; /* session id */ int sid; /* session id */
void *dd_data; /* LLD private data */ void *dd_data; /* LLD private data */
struct device dev; /* sysfs transport/container device */ struct device dev; /* sysfs transport/container device */
...@@ -147,15 +156,23 @@ struct iscsi_cls_session { ...@@ -147,15 +156,23 @@ struct iscsi_cls_session {
#define iscsi_session_to_shost(_session) \ #define iscsi_session_to_shost(_session) \
dev_to_shost(_session->dev.parent) dev_to_shost(_session->dev.parent)
struct iscsi_host {
int next_target_id;
struct list_head sessions;
struct mutex mutex;
};
/* /*
* session and connection functions that can be used by HW iSCSI LLDs * session and connection functions that can be used by HW iSCSI LLDs
*/ */
extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost, extern struct iscsi_cls_session *iscsi_create_session(struct Scsi_Host *shost,
struct iscsi_transport *t); struct iscsi_transport *t, int channel);
extern int iscsi_destroy_session(struct iscsi_cls_session *session); extern int iscsi_destroy_session(struct iscsi_cls_session *session);
extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
uint32_t cid); uint32_t cid);
extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn);
extern void iscsi_unblock_session(struct iscsi_cls_session *session);
extern void iscsi_block_session(struct iscsi_cls_session *session);
/* /*
* session functions used by software iscsi * session functions used by software iscsi
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment