diff options
| author | Maxim Shchetynin <maxim@de.ibm.com> | 2006-02-10 19:42:58 -0500 |
|---|---|---|
| committer | <jejb@mulgrave.il.steeleye.com> | 2006-02-12 12:12:20 -0500 |
| commit | ed829ad607a9c334cea490d3a8c0f874153fb42d (patch) | |
| tree | 7abbf2eb353ee64d330ac423fe42b3524f409eec /drivers/s390 | |
| parent | 2f8f3ed5fc566700cf45d422f4cf1624bd123d93 (diff) | |
[SCSI] zfcp: fix logging during device reset
Avoid access to old fsf_requests if device reset is logged.
Signed-off-by: Maxim Shchetynin <maxim@de.ibm.com>
Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/s390')
| -rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 76 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 6 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 5 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 6 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 15 |
5 files changed, 47 insertions, 61 deletions
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 4d7d47cf239..a5f2ba9a8fd 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
| @@ -710,10 +710,9 @@ static inline void | |||
| 710 | _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | 710 | _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, |
| 711 | struct zfcp_adapter *adapter, | 711 | struct zfcp_adapter *adapter, |
| 712 | struct scsi_cmnd *scsi_cmnd, | 712 | struct scsi_cmnd *scsi_cmnd, |
| 713 | struct zfcp_fsf_req *new_fsf_req) | 713 | struct zfcp_fsf_req *fsf_req, |
| 714 | struct zfcp_fsf_req *old_fsf_req) | ||
| 714 | { | 715 | { |
| 715 | struct zfcp_fsf_req *fsf_req = | ||
| 716 | (struct zfcp_fsf_req *)scsi_cmnd->host_scribble; | ||
| 717 | struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; | 716 | struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; |
| 718 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; | 717 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; |
| 719 | unsigned long flags; | 718 | unsigned long flags; |
| @@ -727,19 +726,20 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | |||
| 727 | if (offset == 0) { | 726 | if (offset == 0) { |
| 728 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); | 727 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); |
| 729 | strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); | 728 | strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); |
| 730 | if (scsi_cmnd->device) { | 729 | if (scsi_cmnd != NULL) { |
| 731 | rec->scsi_id = scsi_cmnd->device->id; | 730 | if (scsi_cmnd->device) { |
| 732 | rec->scsi_lun = scsi_cmnd->device->lun; | 731 | rec->scsi_id = scsi_cmnd->device->id; |
| 732 | rec->scsi_lun = scsi_cmnd->device->lun; | ||
| 733 | } | ||
| 734 | rec->scsi_result = scsi_cmnd->result; | ||
| 735 | rec->scsi_cmnd = (unsigned long)scsi_cmnd; | ||
| 736 | rec->scsi_serial = scsi_cmnd->serial_number; | ||
| 737 | memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd, | ||
| 738 | min((int)scsi_cmnd->cmd_len, | ||
| 739 | ZFCP_DBF_SCSI_OPCODE)); | ||
| 740 | rec->scsi_retries = scsi_cmnd->retries; | ||
| 741 | rec->scsi_allowed = scsi_cmnd->allowed; | ||
| 733 | } | 742 | } |
| 734 | rec->scsi_result = scsi_cmnd->result; | ||
| 735 | rec->scsi_cmnd = (unsigned long)scsi_cmnd; | ||
| 736 | rec->scsi_serial = scsi_cmnd->serial_number; | ||
| 737 | memcpy(rec->scsi_opcode, | ||
| 738 | &scsi_cmnd->cmnd, | ||
| 739 | min((int)scsi_cmnd->cmd_len, | ||
| 740 | ZFCP_DBF_SCSI_OPCODE)); | ||
| 741 | rec->scsi_retries = scsi_cmnd->retries; | ||
| 742 | rec->scsi_allowed = scsi_cmnd->allowed; | ||
| 743 | if (fsf_req != NULL) { | 743 | if (fsf_req != NULL) { |
| 744 | fcp_rsp = (struct fcp_rsp_iu *) | 744 | fcp_rsp = (struct fcp_rsp_iu *) |
| 745 | &(fsf_req->qtcb->bottom.io.fcp_rsp); | 745 | &(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 | rec->fsf_seqno = fsf_req->seq_no; | 772 | rec->fsf_seqno = fsf_req->seq_no; |
| 773 | rec->fsf_issued = fsf_req->issued; | 773 | rec->fsf_issued = fsf_req->issued; |
| 774 | } | 774 | } |
| 775 | if (new_fsf_req != NULL) { | 775 | rec->type.old_fsf_reqid = |
| 776 | rec->type.new_fsf_req.fsf_reqid = | 776 | (unsigned long) old_fsf_req; |
| 777 | (unsigned long) | ||
| 778 | new_fsf_req; | ||
| 779 | rec->type.new_fsf_req.fsf_seqno = | ||
| 780 | new_fsf_req->seq_no; | ||
| 781 | rec->type.new_fsf_req.fsf_issued = | ||
| 782 | new_fsf_req->issued; | ||
| 783 | } | ||
| 784 | } else { | 777 | } else { |
| 785 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); | 778 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); |
| 786 | dump->total_size = buflen; | 779 | dump->total_size = buflen; |
| @@ -801,19 +794,21 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, | |||
| 801 | inline void | 794 | inline void |
| 802 | zfcp_scsi_dbf_event_result(const char *tag, int level, | 795 | zfcp_scsi_dbf_event_result(const char *tag, int level, |
| 803 | struct zfcp_adapter *adapter, | 796 | struct zfcp_adapter *adapter, |
| 804 | struct scsi_cmnd *scsi_cmnd) | 797 | struct scsi_cmnd *scsi_cmnd, |
| 798 | struct zfcp_fsf_req *fsf_req) | ||
| 805 | { | 799 | { |
| 806 | _zfcp_scsi_dbf_event_common("rslt", | 800 | _zfcp_scsi_dbf_event_common("rslt", tag, level, |
| 807 | tag, level, adapter, scsi_cmnd, NULL); | 801 | adapter, scsi_cmnd, fsf_req, NULL); |
| 808 | } | 802 | } |
| 809 | 803 | ||
| 810 | inline void | 804 | inline void |
| 811 | zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, | 805 | zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, |
| 812 | struct scsi_cmnd *scsi_cmnd, | 806 | struct scsi_cmnd *scsi_cmnd, |
| 813 | struct zfcp_fsf_req *new_fsf_req) | 807 | struct zfcp_fsf_req *new_fsf_req, |
| 808 | struct zfcp_fsf_req *old_fsf_req) | ||
| 814 | { | 809 | { |
| 815 | _zfcp_scsi_dbf_event_common("abrt", | 810 | _zfcp_scsi_dbf_event_common("abrt", tag, 1, |
| 816 | tag, 1, adapter, scsi_cmnd, new_fsf_req); | 811 | adapter, scsi_cmnd, new_fsf_req, old_fsf_req); |
| 817 | } | 812 | } |
| 818 | 813 | ||
| 819 | inline void | 814 | inline void |
| @@ -823,7 +818,7 @@ zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, | |||
| 823 | struct zfcp_adapter *adapter = unit->port->adapter; | 818 | struct zfcp_adapter *adapter = unit->port->adapter; |
| 824 | 819 | ||
| 825 | _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst", | 820 | _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst", |
| 826 | tag, 1, adapter, scsi_cmnd, NULL); | 821 | tag, 1, adapter, scsi_cmnd, NULL, NULL); |
| 827 | } | 822 | } |
| 828 | 823 | ||
| 829 | static int | 824 | static int |
| @@ -856,6 +851,10 @@ zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, | |||
| 856 | rec->scsi_retries); | 851 | rec->scsi_retries); |
| 857 | len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x", | 852 | len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x", |
| 858 | rec->scsi_allowed); | 853 | rec->scsi_allowed); |
| 854 | if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) { | ||
| 855 | len += zfcp_dbf_view(out_buf + len, "old_fsf_reqid", "0x%0Lx", | ||
| 856 | rec->type.old_fsf_reqid); | ||
| 857 | } | ||
| 859 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", | 858 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", |
| 860 | rec->fsf_reqid); | 859 | rec->fsf_reqid); |
| 861 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", | 860 | 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 | min((int)rec->type.fcp.sns_info_len, | 882 | min((int)rec->type.fcp.sns_info_len, |
| 884 | ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, | 883 | ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, |
| 885 | rec->type.fcp.sns_info_len); | 884 | rec->type.fcp.sns_info_len); |
| 886 | } else if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) { | ||
| 887 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid_abort", "0x%0Lx", | ||
| 888 | rec->type.new_fsf_req.fsf_reqid); | ||
| 889 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno_abort", "0x%08x", | ||
| 890 | rec->type.new_fsf_req.fsf_seqno); | ||
| 891 | len += zfcp_dbf_stck(out_buf + len, "fsf_issued", | ||
| 892 | rec->type.new_fsf_req.fsf_issued); | ||
| 893 | } else if ((strncmp(rec->tag, "trst", ZFCP_DBF_TAG_SIZE) == 0) || | ||
| 894 | (strncmp(rec->tag, "lrst", ZFCP_DBF_TAG_SIZE) == 0)) { | ||
| 895 | len += zfcp_dbf_view(out_buf + len, "fsf_reqid_reset", "0x%0Lx", | ||
| 896 | rec->type.new_fsf_req.fsf_reqid); | ||
| 897 | len += zfcp_dbf_view(out_buf + len, "fsf_seqno_reset", "0x%08x", | ||
| 898 | rec->type.new_fsf_req.fsf_seqno); | ||
| 899 | len += zfcp_dbf_stck(out_buf + len, "fsf_issued", | ||
| 900 | rec->type.new_fsf_req.fsf_issued); | ||
| 901 | } | 885 | } |
| 902 | 886 | ||
| 903 | len += sprintf(out_buf + len, "\n"); | 887 | len += sprintf(out_buf + len, "\n"); |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index f031199c741..7f551d66f47 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
| @@ -424,11 +424,7 @@ struct zfcp_scsi_dbf_record { | |||
| 424 | u32 fsf_seqno; | 424 | u32 fsf_seqno; |
| 425 | u64 fsf_issued; | 425 | u64 fsf_issued; |
| 426 | union { | 426 | union { |
| 427 | struct { | 427 | u64 old_fsf_reqid; |
| 428 | u64 fsf_reqid; | ||
| 429 | u32 fsf_seqno; | ||
| 430 | u64 fsf_issued; | ||
| 431 | } new_fsf_req; | ||
| 432 | struct { | 428 | struct { |
| 433 | u8 rsp_validity; | 429 | u8 rsp_validity; |
| 434 | u8 rsp_scsi_status; | 430 | u8 rsp_scsi_status; |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index c1ba7cf1b49..700f5402a97 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
| @@ -194,9 +194,10 @@ extern void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *); | |||
| 194 | extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *); | 194 | extern void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *); |
| 195 | 195 | ||
| 196 | extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *, | 196 | extern void zfcp_scsi_dbf_event_result(const char *, int, struct zfcp_adapter *, |
| 197 | struct scsi_cmnd *); | 197 | struct scsi_cmnd *, |
| 198 | struct zfcp_fsf_req *); | ||
| 198 | extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, | 199 | extern void zfcp_scsi_dbf_event_abort(const char *, struct zfcp_adapter *, |
| 199 | struct scsi_cmnd *, | 200 | struct scsi_cmnd *, struct zfcp_fsf_req *, |
| 200 | struct zfcp_fsf_req *); | 201 | struct zfcp_fsf_req *); |
| 201 | extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, | 202 | extern void zfcp_scsi_dbf_event_devreset(const char *, u8, struct zfcp_unit *, |
| 202 | struct scsi_cmnd *); | 203 | struct scsi_cmnd *); |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index bd8cd4d4613..662ec571d73 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
| @@ -4211,11 +4211,11 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
| 4211 | ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); | 4211 | ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); |
| 4212 | 4212 | ||
| 4213 | if (scpnt->result != 0) | 4213 | if (scpnt->result != 0) |
| 4214 | zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt); | 4214 | zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt, fsf_req); |
| 4215 | else if (scpnt->retries > 0) | 4215 | else if (scpnt->retries > 0) |
| 4216 | zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt); | 4216 | zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt, fsf_req); |
| 4217 | else | 4217 | else |
| 4218 | zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt); | 4218 | zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt, fsf_req); |
| 4219 | 4219 | ||
| 4220 | /* cleanup pointer (need this especially for abort) */ | 4220 | /* cleanup pointer (need this especially for abort) */ |
| 4221 | scpnt->host_scribble = NULL; | 4221 | scpnt->host_scribble = NULL; |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index e0803757c0f..9f6b4d7a46f 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
| @@ -242,7 +242,7 @@ zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) | |||
| 242 | if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) | 242 | if ((scpnt->device != NULL) && (scpnt->device->host != NULL)) |
| 243 | zfcp_scsi_dbf_event_result("fail", 4, | 243 | zfcp_scsi_dbf_event_result("fail", 4, |
| 244 | (struct zfcp_adapter*) scpnt->device->host->hostdata[0], | 244 | (struct zfcp_adapter*) scpnt->device->host->hostdata[0], |
| 245 | scpnt); | 245 | scpnt, NULL); |
| 246 | /* return directly */ | 246 | /* return directly */ |
| 247 | scpnt->scsi_done(scpnt); | 247 | scpnt->scsi_done(scpnt); |
| 248 | } | 248 | } |
| @@ -446,7 +446,7 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
| 446 | old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble; | 446 | old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble; |
| 447 | if (!old_fsf_req) { | 447 | if (!old_fsf_req) { |
| 448 | write_unlock_irqrestore(&adapter->abort_lock, flags); | 448 | write_unlock_irqrestore(&adapter->abort_lock, flags); |
| 449 | zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, new_fsf_req); | 449 | zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, NULL); |
| 450 | retval = SUCCESS; | 450 | retval = SUCCESS; |
| 451 | goto out; | 451 | goto out; |
| 452 | } | 452 | } |
| @@ -460,6 +460,8 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
| 460 | adapter, unit, 0); | 460 | adapter, unit, 0); |
| 461 | if (!new_fsf_req) { | 461 | if (!new_fsf_req) { |
| 462 | ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n"); | 462 | ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n"); |
| 463 | zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL, | ||
| 464 | old_fsf_req); | ||
| 463 | retval = FAILED; | 465 | retval = FAILED; |
| 464 | goto out; | 466 | goto out; |
| 465 | } | 467 | } |
| @@ -470,13 +472,16 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
| 470 | 472 | ||
| 471 | /* status should be valid since signals were not permitted */ | 473 | /* status should be valid since signals were not permitted */ |
| 472 | if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) { | 474 | if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) { |
| 473 | zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req); | 475 | zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req, |
| 476 | NULL); | ||
| 474 | retval = SUCCESS; | 477 | retval = SUCCESS; |
| 475 | } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) { | 478 | } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) { |
| 476 | zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req); | 479 | zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req, |
| 480 | NULL); | ||
| 477 | retval = SUCCESS; | 481 | retval = SUCCESS; |
| 478 | } else { | 482 | } else { |
| 479 | zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req); | 483 | zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req, |
| 484 | NULL); | ||
| 480 | retval = FAILED; | 485 | retval = FAILED; |
| 481 | } | 486 | } |
| 482 | zfcp_fsf_req_free(new_fsf_req); | 487 | zfcp_fsf_req_free(new_fsf_req); |
