Commit 53dd4af3 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by Khalid Elmously

scsi: fcoe: Embed fc_rport_priv in fcoe_rport structure

BugLink: https://bugs.launchpad.net/bugs/1845038

commit 023358b1 upstream.

Gcc-9 complains for a memset across pointer boundaries, which happens as
the code tries to allocate a flexible array on the stack.  Turns out we
cannot do this without relying on gcc-isms, so with this patch we'll embed
the fc_rport_priv structure into fcoe_rport, can use the normal
'container_of' outcast, and will only have to do a memset over one
structure.
Signed-off-by: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarConnor Kuehl <connor.kuehl@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent 5efe1ed4
...@@ -1973,7 +1973,7 @@ EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac); ...@@ -1973,7 +1973,7 @@ EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
*/ */
static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata) static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata)
{ {
return (struct fcoe_rport *)(rdata + 1); return container_of(rdata, struct fcoe_rport, rdata);
} }
/** /**
...@@ -2233,7 +2233,7 @@ static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip) ...@@ -2233,7 +2233,7 @@ static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip)
*/ */
static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
struct sk_buff *skb, struct sk_buff *skb,
struct fc_rport_priv *rdata) struct fcoe_rport *frport)
{ {
struct fip_header *fiph; struct fip_header *fiph;
struct fip_desc *desc = NULL; struct fip_desc *desc = NULL;
...@@ -2241,16 +2241,12 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, ...@@ -2241,16 +2241,12 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
struct fip_wwn_desc *wwn = NULL; struct fip_wwn_desc *wwn = NULL;
struct fip_vn_desc *vn = NULL; struct fip_vn_desc *vn = NULL;
struct fip_size_desc *size = NULL; struct fip_size_desc *size = NULL;
struct fcoe_rport *frport;
size_t rlen; size_t rlen;
size_t dlen; size_t dlen;
u32 desc_mask = 0; u32 desc_mask = 0;
u32 dtype; u32 dtype;
u8 sub; u8 sub;
memset(rdata, 0, sizeof(*rdata) + sizeof(*frport));
frport = fcoe_ctlr_rport(rdata);
fiph = (struct fip_header *)skb->data; fiph = (struct fip_header *)skb->data;
frport->flags = ntohs(fiph->fip_flags); frport->flags = ntohs(fiph->fip_flags);
...@@ -2313,15 +2309,17 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, ...@@ -2313,15 +2309,17 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
if (dlen != sizeof(struct fip_wwn_desc)) if (dlen != sizeof(struct fip_wwn_desc))
goto len_err; goto len_err;
wwn = (struct fip_wwn_desc *)desc; wwn = (struct fip_wwn_desc *)desc;
rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn); frport->rdata.ids.node_name =
get_unaligned_be64(&wwn->fd_wwn);
break; break;
case FIP_DT_VN_ID: case FIP_DT_VN_ID:
if (dlen != sizeof(struct fip_vn_desc)) if (dlen != sizeof(struct fip_vn_desc))
goto len_err; goto len_err;
vn = (struct fip_vn_desc *)desc; vn = (struct fip_vn_desc *)desc;
memcpy(frport->vn_mac, vn->fd_mac, ETH_ALEN); memcpy(frport->vn_mac, vn->fd_mac, ETH_ALEN);
rdata->ids.port_id = ntoh24(vn->fd_fc_id); frport->rdata.ids.port_id = ntoh24(vn->fd_fc_id);
rdata->ids.port_name = get_unaligned_be64(&vn->fd_wwpn); frport->rdata.ids.port_name =
get_unaligned_be64(&vn->fd_wwpn);
break; break;
case FIP_DT_FC4F: case FIP_DT_FC4F:
if (dlen != sizeof(struct fip_fc4_feat)) if (dlen != sizeof(struct fip_fc4_feat))
...@@ -2664,16 +2662,13 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) ...@@ -2664,16 +2662,13 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{ {
struct fip_header *fiph; struct fip_header *fiph;
enum fip_vn2vn_subcode sub; enum fip_vn2vn_subcode sub;
struct { struct fcoe_rport frport = { };
struct fc_rport_priv rdata;
struct fcoe_rport frport;
} buf;
int rc; int rc;
fiph = (struct fip_header *)skb->data; fiph = (struct fip_header *)skb->data;
sub = fiph->fip_subcode; sub = fiph->fip_subcode;
rc = fcoe_ctlr_vn_parse(fip, skb, &buf.rdata); rc = fcoe_ctlr_vn_parse(fip, skb, &frport);
if (rc) { if (rc) {
LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc); LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc);
goto drop; goto drop;
...@@ -2682,19 +2677,19 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) ...@@ -2682,19 +2677,19 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
mutex_lock(&fip->ctlr_mutex); mutex_lock(&fip->ctlr_mutex);
switch (sub) { switch (sub) {
case FIP_SC_VN_PROBE_REQ: case FIP_SC_VN_PROBE_REQ:
fcoe_ctlr_vn_probe_req(fip, &buf.rdata); fcoe_ctlr_vn_probe_req(fip, &frport.rdata);
break; break;
case FIP_SC_VN_PROBE_REP: case FIP_SC_VN_PROBE_REP:
fcoe_ctlr_vn_probe_reply(fip, &buf.rdata); fcoe_ctlr_vn_probe_reply(fip, &frport.rdata);
break; break;
case FIP_SC_VN_CLAIM_NOTIFY: case FIP_SC_VN_CLAIM_NOTIFY:
fcoe_ctlr_vn_claim_notify(fip, &buf.rdata); fcoe_ctlr_vn_claim_notify(fip, &frport.rdata);
break; break;
case FIP_SC_VN_CLAIM_REP: case FIP_SC_VN_CLAIM_REP:
fcoe_ctlr_vn_claim_resp(fip, &buf.rdata); fcoe_ctlr_vn_claim_resp(fip, &frport.rdata);
break; break;
case FIP_SC_VN_BEACON: case FIP_SC_VN_BEACON:
fcoe_ctlr_vn_beacon(fip, &buf.rdata); fcoe_ctlr_vn_beacon(fip, &frport.rdata);
break; break;
default: default:
LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub); LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub);
......
...@@ -121,12 +121,15 @@ static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, ...@@ -121,12 +121,15 @@ static struct fc_rport_priv *fc_rport_create(struct fc_lport *lport,
u32 port_id) u32 port_id)
{ {
struct fc_rport_priv *rdata; struct fc_rport_priv *rdata;
size_t rport_priv_size = sizeof(*rdata);
rdata = lport->tt.rport_lookup(lport, port_id); rdata = lport->tt.rport_lookup(lport, port_id);
if (rdata) if (rdata)
return rdata; return rdata;
rdata = kzalloc(sizeof(*rdata) + lport->rport_priv_size, GFP_KERNEL); if (lport->rport_priv_size > 0)
rport_priv_size = lport->rport_priv_size;
rdata = kzalloc(rport_priv_size, GFP_KERNEL);
if (!rdata) if (!rdata)
return NULL; return NULL;
......
...@@ -236,6 +236,7 @@ struct fcoe_fcf { ...@@ -236,6 +236,7 @@ struct fcoe_fcf {
* @vn_mac: VN_Node assigned MAC address for data * @vn_mac: VN_Node assigned MAC address for data
*/ */
struct fcoe_rport { struct fcoe_rport {
struct fc_rport_priv rdata;
unsigned long time; unsigned long time;
u16 fcoe_len; u16 fcoe_len;
u16 flags; u16 flags;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment