Skip to content

Commit 94a7f73

Browse files
steffen-maierZhengShunQian
authored andcommitted
scsi: zfcp: fix missing REC trigger trace on terminate_rport_io early return
commit 96d9270 upstream. get_device() and its internally used kobject_get() only return NULL if they get passed NULL as argument. zfcp_get_port_by_wwpn() loops over adapter->port_list so the iteration variable port is always non-NULL. Struct device is embedded in struct zfcp_port so &port->dev is always non-NULL. This is the argument to get_device(). However, if we get an fc_rport in terminate_rport_io() for which we cannot find a match within zfcp_get_port_by_wwpn(), the latter can return NULL. v2.6.30 commit 7093293 ("[SCSI] zfcp: Fix oops when port disappears") introduced an early return without adding a trace record for this case. Even if we don't need recovery in this case, for debugging we should still see that our callback was invoked originally by scsi_transport_fc. Example trace record formatted with zfcpdbf from s390-tools: Timestamp : ... Area : REC Subarea : 00 Level : 1 Exception : - CPU ID : .. Caller : 0x... Record ID : 1 Tag : sctrpin SCSI terminate rport I/O, no zfcp port LUN : 0xffffffffffffffff none (invalid) WWPN : 0x<wwpn> WWPN D_ID : 0x<n_port_id> N_Port-ID Adapter status : 0x... Port status : 0xffffffff unknown (-1) LUN status : 0x00000000 none (invalid) Ready count : 0x... Running count : 0x... ERP want : 0x03 ZFCP_ERP_ACTION_REOPEN_PORT_FORCED ERP need : 0xc0 ZFCP_ERP_ACTION_NONE Signed-off-by: Steffen Maier <[email protected]> Fixes: 7093293 ("[SCSI] zfcp: Fix oops when port disappears") Cc: <[email protected]> #2.6.38+ Reviewed-by: Benjamin Block <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b80eddf commit 94a7f73

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

drivers/s390/scsi/zfcp_erp.c

+20
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,26 @@ static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
282282
return retval;
283283
}
284284

285+
void zfcp_erp_port_forced_no_port_dbf(char *id, struct zfcp_adapter *adapter,
286+
u64 port_name, u32 port_id)
287+
{
288+
unsigned long flags;
289+
static /* don't waste stack */ struct zfcp_port tmpport;
290+
291+
write_lock_irqsave(&adapter->erp_lock, flags);
292+
/* Stand-in zfcp port with fields just good enough for
293+
* zfcp_dbf_rec_trig() and zfcp_dbf_set_common().
294+
* Under lock because tmpport is static.
295+
*/
296+
atomic_set(&tmpport.status, -1); /* unknown */
297+
tmpport.wwpn = port_name;
298+
tmpport.d_id = port_id;
299+
zfcp_dbf_rec_trig(id, adapter, &tmpport, NULL,
300+
ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
301+
ZFCP_ERP_ACTION_NONE);
302+
write_unlock_irqrestore(&adapter->erp_lock, flags);
303+
}
304+
285305
static int _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
286306
int clear_mask, char *id)
287307
{

drivers/s390/scsi/zfcp_ext.h

+3
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ extern void zfcp_dbf_scsi_eh(char *tag, struct zfcp_adapter *adapter,
5858
/* zfcp_erp.c */
5959
extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
6060
extern void zfcp_erp_clear_adapter_status(struct zfcp_adapter *, u32);
61+
extern void zfcp_erp_port_forced_no_port_dbf(char *id,
62+
struct zfcp_adapter *adapter,
63+
u64 port_name, u32 port_id);
6164
extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *);
6265
extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *);
6366
extern void zfcp_erp_set_port_status(struct zfcp_port *, u32);

drivers/s390/scsi/zfcp_scsi.c

+5
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,11 @@ static void zfcp_scsi_terminate_rport_io(struct fc_rport *rport)
603603
if (port) {
604604
zfcp_erp_port_forced_reopen(port, 0, "sctrpi1");
605605
put_device(&port->dev);
606+
} else {
607+
zfcp_erp_port_forced_no_port_dbf(
608+
"sctrpin", adapter,
609+
rport->port_name /* zfcp_scsi_rport_register */,
610+
rport->port_id /* zfcp_scsi_rport_register */);
606611
}
607612
}
608613

0 commit comments

Comments
 (0)