diff options
author | John Soni Jose <sony.john-n@emulex.com> | 2012-08-20 23:00:55 +0530 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-09-14 17:59:27 +0100 |
commit | 0a513dd8736cdf96821d137b066b6fd44d3eb2cf (patch) | |
tree | 64d29a684c806f90bd42c4ae46f2838e87588f39 /drivers/scsi/be2iscsi/be_iscsi.c | |
parent | 6f72238e774742f618ba0332b76b1860762a40cb (diff) |
[SCSI] be2iscsi: Fix a kernel panic because of TCP RST/FIN received.
A TCP RST/FIN can be received even before the connection specific
structures are initialized.This fix checks for the conn structure
is intialized or not when RST/FIN is received.
Signed-off-by: John Soni Jose <sony.john-n@emulex.com>
Signed-off-by: Jayamohan Kallickal <jayamohan.kallickal@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/be2iscsi/be_iscsi.c')
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index ebb6c1fc1607..aedb0d9a9dae 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -1254,6 +1254,7 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) struct beiscsi_endpoint *beiscsi_ep; struct beiscsi_hba *phba; unsigned int tag; + uint8_t mgmt_invalidate_flag, tcp_upload_flag; unsigned short savecfg_flag = CMD_ISCSI_SESSION_SAVE_CFG_ON_FLASH; beiscsi_ep = ep->dd_data; @@ -1262,26 +1263,23 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) "BS_%d : In beiscsi_ep_disconnect for ep_cid = %d\n", beiscsi_ep->ep_cid); - if (!beiscsi_ep->conn) { - beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, - "BS_%d : In beiscsi_ep_disconnect, no " - "beiscsi_ep\n"); - return; + if (beiscsi_ep->conn) { + beiscsi_conn = beiscsi_ep->conn; + iscsi_suspend_queue(beiscsi_conn->conn); + mgmt_invalidate_flag = ~BEISCSI_NO_RST_ISSUE; + tcp_upload_flag = CONNECTION_UPLOAD_GRACEFUL; + } else { + mgmt_invalidate_flag = BEISCSI_NO_RST_ISSUE; + tcp_upload_flag = CONNECTION_UPLOAD_ABORT; } - beiscsi_conn = beiscsi_ep->conn; - iscsi_suspend_queue(beiscsi_conn->conn); - - beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, - "BS_%d : In beiscsi_ep_disconnect ep_cid = %d\n", - beiscsi_ep->ep_cid); tag = mgmt_invalidate_connection(phba, beiscsi_ep, - beiscsi_ep->ep_cid, 1, - savecfg_flag); + beiscsi_ep->ep_cid, + mgmt_invalidate_flag, + savecfg_flag); if (!tag) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, - "BS_%d : mgmt_invalidate_connection" - " Failed for cid=%d\n", + "BS_%d : mgmt_invalidate_connection Failed for cid=%d\n", beiscsi_ep->ep_cid); } else { wait_event_interruptible(phba->ctrl.mcc_wait[tag], @@ -1289,7 +1287,7 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) free_mcc_tag(&phba->ctrl, tag); } - beiscsi_close_conn(beiscsi_ep, CONNECTION_UPLOAD_GRACEFUL); + beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); beiscsi_free_ep(beiscsi_ep); beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); |