提交 ed829ad6 编写于 作者: M Maxim Shchetynin 提交者:

[SCSI] zfcp: fix logging during device reset

Avoid access to old fsf_requests if device reset is logged.
Signed-off-by: NMaxim Shchetynin <maxim@de.ibm.com>
Signed-off-by: NAndreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: NJames Bottomley <James.Bottomley@SteelEye.com>
上级 2f8f3ed5
...@@ -710,10 +710,9 @@ static inline void ...@@ -710,10 +710,9 @@ static inline void
_zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
struct zfcp_adapter *adapter, struct zfcp_adapter *adapter,
struct scsi_cmnd *scsi_cmnd, struct scsi_cmnd *scsi_cmnd,
struct zfcp_fsf_req *new_fsf_req) struct zfcp_fsf_req *fsf_req,
struct zfcp_fsf_req *old_fsf_req)
{ {
struct zfcp_fsf_req *fsf_req =
(struct zfcp_fsf_req *)scsi_cmnd->host_scribble;
struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;
struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
unsigned long flags; unsigned long flags;
...@@ -727,19 +726,20 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, ...@@ -727,19 +726,20 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
if (offset == 0) { if (offset == 0) {
strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
if (scsi_cmnd->device) { if (scsi_cmnd != NULL) {
rec->scsi_id = scsi_cmnd->device->id; if (scsi_cmnd->device) {
rec->scsi_lun = scsi_cmnd->device->lun; rec->scsi_id = scsi_cmnd->device->id;
rec->scsi_lun = scsi_cmnd->device->lun;
}
rec->scsi_result = scsi_cmnd->result;
rec->scsi_cmnd = (unsigned long)scsi_cmnd;
rec->scsi_serial = scsi_cmnd->serial_number;
memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd,
min((int)scsi_cmnd->cmd_len,
ZFCP_DBF_SCSI_OPCODE));
rec->scsi_retries = scsi_cmnd->retries;
rec->scsi_allowed = scsi_cmnd->allowed;
} }
rec->scsi_result = scsi_cmnd->result;
rec->scsi_cmnd = (unsigned long)scsi_cmnd;
rec->scsi_serial = scsi_cmnd->serial_number;
memcpy(rec->scsi_opcode,
&scsi_cmnd->cmnd,
min((int)scsi_cmnd->cmd_len,
ZFCP_DBF_SCSI_OPCODE));
rec->scsi_retries = scsi_cmnd->retries;
rec->scsi_allowed = scsi_cmnd->allowed;
if (fsf_req != NULL) { if (fsf_req != NULL) {
fcp_rsp = (struct fcp_rsp_iu *) fcp_rsp = (struct fcp_rsp_iu *)
&(fsf_req->qtcb->bottom.io.fcp_rsp); &(fsf_req->qtcb->bottom.io.fcp_rsp);
...@@ -772,15 +772,8 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, ...@@ -772,15 +772,8 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
rec->fsf_seqno = fsf_req->seq_no; rec->fsf_seqno = fsf_req->seq_no;
rec->fsf_issued = fsf_req->issued; rec->fsf_issued = fsf_req->issued;
} }
if (new_fsf_req != NULL) { rec->type.old_fsf_reqid =
rec->type.new_fsf_req.fsf_reqid = (unsigned long) old_fsf_req;
(unsigned long)
new_fsf_req;
rec->type.new_fsf_req.fsf_seqno =
new_fsf_req->seq_no;
rec->type.new_fsf_req.fsf_issued =
new_fsf_req->issued;
}
} else { } else {
strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
dump->total_size = buflen; dump->total_size = buflen;
...@@ -801,19 +794,21 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, ...@@ -801,19 +794,21 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
inline void inline void
zfcp_scsi_dbf_event_result(const char *tag, int level, zfcp_scsi_dbf_event_result(const char *tag, int level,
struct zfcp_adapter *adapter, struct zfcp_adapter *adapter,
struct scsi_cmnd *scsi_cmnd) struct scsi_cmnd *scsi_cmnd,
struct zfcp_fsf_req *fsf_req)
{ {
_zfcp_scsi_dbf_event_common("rslt", _zfcp_scsi_dbf_event_common("rslt", tag, level,
tag, level, adapter, scsi_cmnd, NULL); adapter, scsi_cmnd, fsf_req, NULL);
} }
inline void inline void
zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
struct scsi_cmnd *scsi_cmnd, struct scsi_cmnd *scsi_cmnd,
struct zfcp_fsf_req *new_fsf_req) struct zfcp_fsf_req *new_fsf_req,
struct zfcp_fsf_req *old_fsf_req)
{ {
_zfcp_scsi_dbf_event_common("abrt", _zfcp_scsi_dbf_event_common("abrt", tag, 1,
tag, 1, adapter, scsi_cmnd, new_fsf_req); adapter, scsi_cmnd, new_fsf_req, old_fsf_req);
} }
inline void inline void
...@@ -823,7 +818,7 @@ zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, ...@@ -823,7 +818,7 @@ zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
struct zfcp_adapter *adapter = unit->port->adapter; struct zfcp_adapter *adapter = unit->port->adapter;
_zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst", _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst",
tag, 1, adapter, scsi_cmnd, NULL); tag, 1, adapter, scsi_cmnd, NULL, NULL);
} }
static int static int
...@@ -856,6 +851,10 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, ...@@ -856,6 +851,10 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,
rec->scsi_retries); rec->scsi_retries);
len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x", len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x",
rec->scsi_allowed); rec->scsi_allowed);
if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) {
len += zfcp_dbf_view(out_buf + len, "old_fsf_reqid", "0x%0Lx",
rec->type.old_fsf_reqid);
}
len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
rec->fsf_reqid); rec->fsf_reqid);
len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
...@@ -883,21 +882,6 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, ...@@ -883,21 +882,6 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,
min((int)rec->type.fcp.sns_info_len, min((int)rec->type.fcp.sns_info_len,
ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,
rec->type.fcp.sns_info_len); rec->type.fcp.sns_info_len);
} else if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) {
len += zfcp_dbf_view(out_buf + len, "fsf_reqid_abort", "0x%0Lx",
rec->type.new_fsf_req.fsf_reqid);
len += zfcp_dbf_view(out_buf + len, "fsf_seqno_abort", "0x%08x",
rec->type.new_fsf_req.fsf_seqno);
len += zfcp_dbf_stck(out_buf + len, "fsf_issued",
rec->type.new_fsf_req.fsf_issued);
} else if ((strncmp(rec->tag, "trst", ZFCP_DBF_TAG_SIZE) == 0) ||
(strncmp(rec->tag, "lrst", ZFCP_DBF_TAG_SIZE) == 0)) {
len += zfcp_dbf_view(out_buf + len, "fsf_reqid_reset", "0x%0Lx",
rec->type.new_fsf_req.fsf_reqid);
len += zfcp_dbf_view(out_buf + len, "fsf_seqno_reset", "0x%08x",
rec->type.new_fsf_req.fsf_seqno);
len += zfcp_dbf_stck(out_buf + len, "fsf_issued",
rec->type.new_fsf_req.fsf_issued);
} }
len += sprintf(out_buf + len, "\n"); len += sprintf(out_buf + len, "\n");
......
...@@ -424,11 +424,7 @@ struct zfcp_scsi_dbf_record { ...@@ -424,11 +424,7 @@ struct zfcp_scsi_dbf_record {
u32 fsf_seqno; u32 fsf_seqno;
u64 fsf_issued; u64 fsf_issued;
union { union {
struct { u64 old_fsf_reqid;
u64 fsf_reqid;
u32 fsf_seqno;
u64 fsf_issued;
} new_fsf_req;
struct { struct {
u8 rsp_validity; u8 rsp_validity;
u8 rsp_scsi_status; u8 rsp_scsi_status;
......
...@@ -194,9 +194,10 @@ extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *); ...@@ -194,9 +194,10 @@ extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *);
extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *); extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *);
extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *, extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *,
struct scsi_cmnd *); struct scsi_cmnd *,
struct zfcp_fsf_req *);
extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *,
struct scsi_cmnd *, struct scsi_cmnd *, struct zfcp_fsf_req *,
struct zfcp_fsf_req *); struct zfcp_fsf_req *);
extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *,
struct scsi_cmnd *); struct scsi_cmnd *);
......
...@@ -4211,11 +4211,11 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) ...@@ -4211,11 +4211,11 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result);
if (scpnt->result != 0) if (scpnt->result != 0)
zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt); zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt, fsf_req);
else if (scpnt->retries > 0) else if (scpnt->retries > 0)
zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt); zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt, fsf_req);
else else
zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt); zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt, fsf_req);
/* cleanup pointer (need this especially for abort) */ /* cleanup pointer (need this especially for abort) */
scpnt->host_scribble = NULL; scpnt->host_scribble = NULL;
......
...@@ -242,7 +242,7 @@ zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) ...@@ -242,7 +242,7 @@ zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)
if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) if ((scpnt->device != NULL) && (scpnt->device->host != NULL))
zfcp_scsi_dbf_event_result("fail", 4, zfcp_scsi_dbf_event_result("fail", 4,
(struct zfcp_adapter*) scpnt->device->host->hostdata[0], (struct zfcp_adapter*) scpnt->device->host->hostdata[0],
scpnt); scpnt, NULL);
/* return directly */ /* return directly */
scpnt->scsi_done(scpnt); scpnt->scsi_done(scpnt);
} }
...@@ -446,7 +446,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) ...@@ -446,7 +446,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble; old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble;
if (!old_fsf_req) { if (!old_fsf_req) {
write_unlock_irqrestore(&adapter->abort_lock, flags); write_unlock_irqrestore(&adapter->abort_lock, flags);
zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, new_fsf_req); zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, NULL);
retval = SUCCESS; retval = SUCCESS;
goto out; goto out;
} }
...@@ -460,6 +460,8 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) ...@@ -460,6 +460,8 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
adapter, unit, 0); adapter, unit, 0);
if (!new_fsf_req) { if (!new_fsf_req) {
ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n"); ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n");
zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
old_fsf_req);
retval = FAILED; retval = FAILED;
goto out; goto out;
} }
...@@ -470,13 +472,16 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) ...@@ -470,13 +472,16 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
/* status should be valid since signals were not permitted */ /* status should be valid since signals were not permitted */
if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) { if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req); zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req,
NULL);
retval = SUCCESS; retval = SUCCESS;
} else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) { } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req); zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req,
NULL);
retval = SUCCESS; retval = SUCCESS;
} else { } else {
zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req); zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req,
NULL);
retval = FAILED; retval = FAILED;
} }
zfcp_fsf_req_free(new_fsf_req); zfcp_fsf_req_free(new_fsf_req);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册