]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: zfcp: unrecoverable port on D_ID change. | |
3 | References: bnc#499845,LTC#53175 | |
4 | ||
5 | Symptom: Remote storage port remains offline. | |
6 | Problem: If, for whatever reason, the destination ID of a | |
7 | remote storage port changes, it won't become available | |
8 | again. The problem is that in such a situation the | |
9 | mapping between the WWPN and D_ID is breaking. Since | |
10 | all communication in a SAN is done via the D_ID, the | |
11 | zfcp driver is treating this "new" D_ID as an unknown | |
12 | reference leading to no further action. | |
13 | Solution: Trigger a port reopen in situations which could be | |
14 | the result of a changed D_ID and trigger a port reopen | |
15 | for all ports having no D_ID on RSCN receiption. | |
16 | ||
17 | Acked-by: John Jolly <jjolly@suse.de> | |
18 | ||
19 | --- | |
20 | drivers/s390/scsi/zfcp_dbf.c | 4 ++-- | |
21 | drivers/s390/scsi/zfcp_erp.c | 10 ++++++++-- | |
22 | drivers/s390/scsi/zfcp_fc.c | 7 ++++++- | |
23 | 3 files changed, 16 insertions(+), 5 deletions(-) | |
24 | ||
25 | Index: linux-sles11/drivers/s390/scsi/zfcp_erp.c | |
26 | =================================================================== | |
27 | --- linux-sles11.orig/drivers/s390/scsi/zfcp_erp.c | |
28 | +++ linux-sles11/drivers/s390/scsi/zfcp_erp.c | |
29 | @@ -892,7 +892,6 @@ static int zfcp_erp_port_strategy_open_c | |
30 | return zfcp_erp_port_strategy_open_port(act); | |
31 | ||
32 | case ZFCP_ERP_STEP_PORT_OPENING: | |
33 | - /* D_ID might have changed during open */ | |
34 | if (p_status & ZFCP_STATUS_COMMON_OPEN) { | |
35 | if (p_status & ZFCP_STATUS_PORT_DID_DID) | |
36 | return ZFCP_ERP_SUCCEEDED; | |
37 | @@ -900,8 +899,15 @@ static int zfcp_erp_port_strategy_open_c | |
38 | act->step = ZFCP_ERP_STEP_PORT_CLOSING; | |
39 | return ZFCP_ERP_CONTINUES; | |
40 | } | |
41 | - /* fall through otherwise */ | |
42 | } | |
43 | + if ((atomic_read(&port->status) & ZFCP_STATUS_PORT_DID_DID) && | |
44 | + !(p_status & ZFCP_STATUS_COMMON_NOESC)) { | |
45 | + atomic_clear_mask(ZFCP_STATUS_PORT_DID_DID, | |
46 | + &port->status); | |
47 | + _zfcp_erp_port_reopen(port, 0, 56, NULL); | |
48 | + return ZFCP_ERP_EXIT; | |
49 | + } | |
50 | + /* fall through otherwise */ | |
51 | } | |
52 | return ZFCP_ERP_FAILED; | |
53 | } | |
54 | Index: linux-sles11/drivers/s390/scsi/zfcp_dbf.c | |
55 | =================================================================== | |
56 | --- linux-sles11.orig/drivers/s390/scsi/zfcp_dbf.c | |
57 | +++ linux-sles11/drivers/s390/scsi/zfcp_dbf.c | |
58 | @@ -545,8 +545,8 @@ static const char *zfcp_rec_dbf_ids[] = | |
59 | [53] = "port boxed fcp", | |
60 | [54] = "unit boxed fcp", | |
61 | [55] = "port access denied", | |
62 | - [56] = "", | |
63 | - [57] = "", | |
64 | + [56] = "port d_id changed", | |
65 | + [57] = "port reopen on RSCN reception", | |
66 | [58] = "", | |
67 | [59] = "unit access denied", | |
68 | [60] = "shared unit access denied open unit", | |
69 | Index: linux-sles11/drivers/s390/scsi/zfcp_fc.c | |
70 | =================================================================== | |
71 | --- linux-sles11.orig/drivers/s390/scsi/zfcp_fc.c | |
72 | +++ linux-sles11/drivers/s390/scsi/zfcp_fc.c | |
73 | @@ -127,9 +127,14 @@ static void _zfcp_fc_incoming_rscn(struc | |
74 | struct zfcp_port *port; | |
75 | ||
76 | read_lock_irqsave(&zfcp_data.config_lock, flags); | |
77 | - list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) | |
78 | + list_for_each_entry(port, &fsf_req->adapter->port_list_head, list) { | |
79 | if ((port->d_id & range) == (elem->nport_did & range)) | |
80 | zfcp_test_link(port); | |
81 | + if (!(atomic_read(&port->status) & ZFCP_STATUS_PORT_DID_DID)) | |
82 | + zfcp_erp_port_reopen(port, | |
83 | + ZFCP_STATUS_COMMON_ERP_FAILED, 57, | |
84 | + 0); | |
85 | + } | |
86 | ||
87 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | |
88 | } |