Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] libfc: fix referencing to fc_fcp_pkt from the frame pointer via fr_fsp()

In commit 6a716a8, while releasing the DDP context in case frame_send() failed,
the frame may already be freed, so we should store the pointer to fc_fcp_pkt and
release the DDP context using the locally stored fsp instead of getting fsp from
the fr_fsp(fp) on a frame.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Reported-by: Bhanu Prakash Gollapudi <bprakash@broadcom.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>

authored by

Yi Zou and committed by
James Bottomley
3ee17f59 21cc0bd3

+6 -2
+6 -2
drivers/scsi/libfc/fc_exch.c
··· 1981 1981 struct fc_exch *ep; 1982 1982 struct fc_seq *sp = NULL; 1983 1983 struct fc_frame_header *fh; 1984 + struct fc_fcp_pkt *fsp = NULL; 1984 1985 int rc = 1; 1985 1986 1986 1987 ep = fc_exch_alloc(lport, fp); ··· 2004 2003 fc_exch_setup_hdr(ep, fp, ep->f_ctl); 2005 2004 sp->cnt++; 2006 2005 2007 - if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) 2006 + if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) { 2007 + fsp = fr_fsp(fp); 2008 2008 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); 2009 + } 2009 2010 2010 2011 if (unlikely(lport->tt.frame_send(lport, fp))) 2011 2012 goto err; ··· 2021 2018 spin_unlock_bh(&ep->ex_lock); 2022 2019 return sp; 2023 2020 err: 2024 - fc_fcp_ddp_done(fr_fsp(fp)); 2021 + if (fsp) 2022 + fc_fcp_ddp_done(fsp); 2025 2023 rc = fc_exch_done_locked(ep); 2026 2024 spin_unlock_bh(&ep->ex_lock); 2027 2025 if (!rc)