Skip to content

Commit 3b64b18

Browse files
yizouJames Bottomley
authored andcommitted
[SCSI] libfc: fix lun reset failure bugs in fc_fcp_resp handling of FCP_RSP_INFO
In LUN RESET testing involving NetApp targets, it is observed that LUN RESET is failing. The fc_fcp_resp() is not completing the completion for the LUN RESET task since fc_fcp_resp assumes that the FCP_RSP_INFO is 8 bytes with the 4 byte reserved field, where in case of NetApp targets the FCP_RSP to LUN RESET only has 4 bytes of FCP_RSP_INFO. This leads fc_fcp_resp to error out w/o completing the task completion, eventually causing LUN RESET to be escalated to host reset, which is not very nice. Per FCP-3 r04, clause 9.5.15 and Table 23, the FCP_RSP_INFO field can be either 4 bytes or 8 bytes, with the last 4 bytes as "Reserved (if any)". Therefore it is valid to have 4 bytes FCP_RSP_INFO like some of the NetApp targets behave. Fixing this by validating the FCP_RSP_INFO against both the two spec allowed length. Reported-by: Frank Zhang <frank_1.zhang@intel.com> Signed-off-by: Yi Zou <yi.zou@intel.com> Tested-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
1 parent 31c37a6 commit 3b64b18

2 files changed

Lines changed: 8 additions & 1 deletion

File tree

drivers/scsi/libfc/fc_fcp.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,8 @@ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
851851
fc_rp_info = (struct fcp_resp_rsp_info *)(rp_ex + 1);
852852
if (flags & FCP_RSP_LEN_VAL) {
853853
respl = ntohl(rp_ex->fr_rsp_len);
854-
if (respl != sizeof(*fc_rp_info))
854+
if ((respl != FCP_RESP_RSP_INFO_LEN4) &&
855+
(respl != FCP_RESP_RSP_INFO_LEN8))
855856
goto len_err;
856857
if (fsp->wait_for_comp) {
857858
/* Abuse cdb_status for rsp code */

include/scsi/fc/fc_fcp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ struct fcp_txrdy {
127127
*
128128
* All response frames will always contain the fcp_resp template. Some
129129
* will also include the fcp_resp_len template.
130+
*
131+
* From Table 23, the FCP_RSP_INFO can either be 4 bytes or 8 bytes, both
132+
* are valid length.
130133
*/
131134
struct fcp_resp {
132135
__u8 _fr_resvd[8]; /* reserved */
@@ -156,6 +159,9 @@ struct fcp_resp_rsp_info {
156159
__u8 _fr_resvd2[4]; /* reserved */
157160
};
158161

162+
#define FCP_RESP_RSP_INFO_LEN4 4 /* without reserved field */
163+
#define FCP_RESP_RSP_INFO_LEN8 8 /* with reserved field */
164+
159165
struct fcp_resp_with_ext {
160166
struct fcp_resp resp;
161167
struct fcp_resp_ext ext;

0 commit comments

Comments
 (0)