Skip to content

Commit

Permalink
scsi: fcoe: Embed fc_rport_priv in fcoe_rport structure
Browse files Browse the repository at this point in the history
commit 023358b136d490ca91735ac6490db3741af5a8bd 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: Hannes Reinecke <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
hreinecke authored and gregkh committed Aug 9, 2019
1 parent cc4c818 commit 93d6f08
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 32 deletions.
51 changes: 20 additions & 31 deletions drivers/scsi/fcoe/fcoe_ctlr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2017,7 +2017,7 @@ EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
*/
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);
}

/**
Expand Down Expand Up @@ -2281,24 +2281,20 @@ static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip)
*/
static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
struct sk_buff *skb,
struct fc_rport_priv *rdata)
struct fcoe_rport *frport)
{
struct fip_header *fiph;
struct fip_desc *desc = NULL;
struct fip_mac_desc *macd = NULL;
struct fip_wwn_desc *wwn = NULL;
struct fip_vn_desc *vn = NULL;
struct fip_size_desc *size = NULL;
struct fcoe_rport *frport;
size_t rlen;
size_t dlen;
u32 desc_mask = 0;
u32 dtype;
u8 sub;

memset(rdata, 0, sizeof(*rdata) + sizeof(*frport));
frport = fcoe_ctlr_rport(rdata);

fiph = (struct fip_header *)skb->data;
frport->flags = ntohs(fiph->fip_flags);

Expand Down Expand Up @@ -2361,15 +2357,17 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip,
if (dlen != sizeof(struct fip_wwn_desc))
goto len_err;
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;
case FIP_DT_VN_ID:
if (dlen != sizeof(struct fip_vn_desc))
goto len_err;
vn = (struct fip_vn_desc *)desc;
memcpy(frport->vn_mac, vn->fd_mac, ETH_ALEN);
rdata->ids.port_id = ntoh24(vn->fd_fc_id);
rdata->ids.port_name = get_unaligned_be64(&vn->fd_wwpn);
frport->rdata.ids.port_id = ntoh24(vn->fd_fc_id);
frport->rdata.ids.port_name =
get_unaligned_be64(&vn->fd_wwpn);
break;
case FIP_DT_FC4F:
if (dlen != sizeof(struct fip_fc4_feat))
Expand Down Expand Up @@ -2750,10 +2748,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
struct fip_header *fiph;
enum fip_vn2vn_subcode sub;
struct {
struct fc_rport_priv rdata;
struct fcoe_rport frport;
} buf;
struct fcoe_rport frport = { };
int rc, vlan_id = 0;

fiph = (struct fip_header *)skb->data;
Expand All @@ -2769,7 +2764,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
goto drop;
}

rc = fcoe_ctlr_vn_parse(fip, skb, &buf.rdata);
rc = fcoe_ctlr_vn_parse(fip, skb, &frport);
if (rc) {
LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc);
goto drop;
Expand All @@ -2778,19 +2773,19 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
mutex_lock(&fip->ctlr_mutex);
switch (sub) {
case FIP_SC_VN_PROBE_REQ:
fcoe_ctlr_vn_probe_req(fip, &buf.rdata);
fcoe_ctlr_vn_probe_req(fip, &frport.rdata);
break;
case FIP_SC_VN_PROBE_REP:
fcoe_ctlr_vn_probe_reply(fip, &buf.rdata);
fcoe_ctlr_vn_probe_reply(fip, &frport.rdata);
break;
case FIP_SC_VN_CLAIM_NOTIFY:
fcoe_ctlr_vn_claim_notify(fip, &buf.rdata);
fcoe_ctlr_vn_claim_notify(fip, &frport.rdata);
break;
case FIP_SC_VN_CLAIM_REP:
fcoe_ctlr_vn_claim_resp(fip, &buf.rdata);
fcoe_ctlr_vn_claim_resp(fip, &frport.rdata);
break;
case FIP_SC_VN_BEACON:
fcoe_ctlr_vn_beacon(fip, &buf.rdata);
fcoe_ctlr_vn_beacon(fip, &frport.rdata);
break;
default:
LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub);
Expand All @@ -2814,22 +2809,18 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
*/
static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip,
struct sk_buff *skb,
struct fc_rport_priv *rdata)
struct fcoe_rport *frport)
{
struct fip_header *fiph;
struct fip_desc *desc = NULL;
struct fip_mac_desc *macd = NULL;
struct fip_wwn_desc *wwn = NULL;
struct fcoe_rport *frport;
size_t rlen;
size_t dlen;
u32 desc_mask = 0;
u32 dtype;
u8 sub;

memset(rdata, 0, sizeof(*rdata) + sizeof(*frport));
frport = fcoe_ctlr_rport(rdata);

fiph = (struct fip_header *)skb->data;
frport->flags = ntohs(fiph->fip_flags);

Expand Down Expand Up @@ -2883,7 +2874,8 @@ static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip,
if (dlen != sizeof(struct fip_wwn_desc))
goto len_err;
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;
default:
LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x "
Expand Down Expand Up @@ -2994,22 +2986,19 @@ static int fcoe_ctlr_vlan_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
struct fip_header *fiph;
enum fip_vlan_subcode sub;
struct {
struct fc_rport_priv rdata;
struct fcoe_rport frport;
} buf;
struct fcoe_rport frport = { };
int rc;

fiph = (struct fip_header *)skb->data;
sub = fiph->fip_subcode;
rc = fcoe_ctlr_vlan_parse(fip, skb, &buf.rdata);
rc = fcoe_ctlr_vlan_parse(fip, skb, &frport);
if (rc) {
LIBFCOE_FIP_DBG(fip, "vlan_recv vlan_parse error %d\n", rc);
goto drop;
}
mutex_lock(&fip->ctlr_mutex);
if (sub == FIP_SC_VL_REQ)
fcoe_ctlr_vlan_disc_reply(fip, &buf.rdata);
fcoe_ctlr_vlan_disc_reply(fip, &frport.rdata);
mutex_unlock(&fip->ctlr_mutex);

drop:
Expand Down
5 changes: 4 additions & 1 deletion drivers/scsi/libfc/fc_rport.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,17 @@ EXPORT_SYMBOL(fc_rport_lookup);
struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id)
{
struct fc_rport_priv *rdata;
size_t rport_priv_size = sizeof(*rdata);

lockdep_assert_held(&lport->disc.disc_mutex);

rdata = fc_rport_lookup(lport, port_id);
if (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)
return NULL;

Expand Down
1 change: 1 addition & 0 deletions include/scsi/libfcoe.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ struct fcoe_fcf {
* @vn_mac: VN_Node assigned MAC address for data
*/
struct fcoe_rport {
struct fc_rport_priv rdata;
unsigned long time;
u16 fcoe_len;
u16 flags;
Expand Down

0 comments on commit 93d6f08

Please sign in to comment.