diff options
author | Hannes Reinecke <hare@suse.de> | 2019-07-24 05:00:55 -0400 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2019-07-29 21:12:35 -0400 |
commit | 023358b136d490ca91735ac6490db3741af5a8bd (patch) | |
tree | be5370ccb0eb4ca07c29875a25de42d56d8e6416 | |
parent | f3e4ff28b8685d856f381ee6bcf88b6149a6db5b (diff) |
scsi: fcoe: Embed fc_rport_priv in fcoe_rport structure
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 <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/fcoe/fcoe_ctlr.c | 51 | ||||
-rw-r--r-- | drivers/scsi/libfc/fc_rport.c | 5 | ||||
-rw-r--r-- | include/scsi/libfcoe.h | 1 |
3 files changed, 25 insertions, 32 deletions
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 1a85fe9e4b7b..fc32b5d76821 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c | |||
@@ -2005,7 +2005,7 @@ EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac); | |||
2005 | */ | 2005 | */ |
2006 | static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata) | 2006 | static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata) |
2007 | { | 2007 | { |
2008 | return (struct fcoe_rport *)(rdata + 1); | 2008 | return container_of(rdata, struct fcoe_rport, rdata); |
2009 | } | 2009 | } |
2010 | 2010 | ||
2011 | /** | 2011 | /** |
@@ -2269,7 +2269,7 @@ static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip) | |||
2269 | */ | 2269 | */ |
2270 | static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, | 2270 | static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, |
2271 | struct sk_buff *skb, | 2271 | struct sk_buff *skb, |
2272 | struct fc_rport_priv *rdata) | 2272 | struct fcoe_rport *frport) |
2273 | { | 2273 | { |
2274 | struct fip_header *fiph; | 2274 | struct fip_header *fiph; |
2275 | struct fip_desc *desc = NULL; | 2275 | struct fip_desc *desc = NULL; |
@@ -2277,16 +2277,12 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, | |||
2277 | struct fip_wwn_desc *wwn = NULL; | 2277 | struct fip_wwn_desc *wwn = NULL; |
2278 | struct fip_vn_desc *vn = NULL; | 2278 | struct fip_vn_desc *vn = NULL; |
2279 | struct fip_size_desc *size = NULL; | 2279 | struct fip_size_desc *size = NULL; |
2280 | struct fcoe_rport *frport; | ||
2281 | size_t rlen; | 2280 | size_t rlen; |
2282 | size_t dlen; | 2281 | size_t dlen; |
2283 | u32 desc_mask = 0; | 2282 | u32 desc_mask = 0; |
2284 | u32 dtype; | 2283 | u32 dtype; |
2285 | u8 sub; | 2284 | u8 sub; |
2286 | 2285 | ||
2287 | memset(rdata, 0, sizeof(*rdata) + sizeof(*frport)); | ||
2288 | frport = fcoe_ctlr_rport(rdata); | ||
2289 | |||
2290 | fiph = (struct fip_header *)skb->data; | 2286 | fiph = (struct fip_header *)skb->data; |
2291 | frport->flags = ntohs(fiph->fip_flags); | 2287 | frport->flags = ntohs(fiph->fip_flags); |
2292 | 2288 | ||
@@ -2349,15 +2345,17 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, | |||
2349 | if (dlen != sizeof(struct fip_wwn_desc)) | 2345 | if (dlen != sizeof(struct fip_wwn_desc)) |
2350 | goto len_err; | 2346 | goto len_err; |
2351 | wwn = (struct fip_wwn_desc *)desc; | 2347 | wwn = (struct fip_wwn_desc *)desc; |
2352 | rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn); | 2348 | frport->rdata.ids.node_name = |
2349 | get_unaligned_be64(&wwn->fd_wwn); | ||
2353 | break; | 2350 | break; |
2354 | case FIP_DT_VN_ID: | 2351 | case FIP_DT_VN_ID: |
2355 | if (dlen != sizeof(struct fip_vn_desc)) | 2352 | if (dlen != sizeof(struct fip_vn_desc)) |
2356 | goto len_err; | 2353 | goto len_err; |
2357 | vn = (struct fip_vn_desc *)desc; | 2354 | vn = (struct fip_vn_desc *)desc; |
2358 | memcpy(frport->vn_mac, vn->fd_mac, ETH_ALEN); | 2355 | memcpy(frport->vn_mac, vn->fd_mac, ETH_ALEN); |
2359 | rdata->ids.port_id = ntoh24(vn->fd_fc_id); | 2356 | frport->rdata.ids.port_id = ntoh24(vn->fd_fc_id); |
2360 | rdata->ids.port_name = get_unaligned_be64(&vn->fd_wwpn); | 2357 | frport->rdata.ids.port_name = |
2358 | get_unaligned_be64(&vn->fd_wwpn); | ||
2361 | break; | 2359 | break; |
2362 | case FIP_DT_FC4F: | 2360 | case FIP_DT_FC4F: |
2363 | if (dlen != sizeof(struct fip_fc4_feat)) | 2361 | if (dlen != sizeof(struct fip_fc4_feat)) |
@@ -2738,10 +2736,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
2738 | { | 2736 | { |
2739 | struct fip_header *fiph; | 2737 | struct fip_header *fiph; |
2740 | enum fip_vn2vn_subcode sub; | 2738 | enum fip_vn2vn_subcode sub; |
2741 | struct { | 2739 | struct fcoe_rport frport = { }; |
2742 | struct fc_rport_priv rdata; | ||
2743 | struct fcoe_rport frport; | ||
2744 | } buf; | ||
2745 | int rc, vlan_id = 0; | 2740 | int rc, vlan_id = 0; |
2746 | 2741 | ||
2747 | fiph = (struct fip_header *)skb->data; | 2742 | fiph = (struct fip_header *)skb->data; |
@@ -2757,7 +2752,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
2757 | goto drop; | 2752 | goto drop; |
2758 | } | 2753 | } |
2759 | 2754 | ||
2760 | rc = fcoe_ctlr_vn_parse(fip, skb, &buf.rdata); | 2755 | rc = fcoe_ctlr_vn_parse(fip, skb, &frport); |
2761 | if (rc) { | 2756 | if (rc) { |
2762 | LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc); | 2757 | LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc); |
2763 | goto drop; | 2758 | goto drop; |
@@ -2766,19 +2761,19 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
2766 | mutex_lock(&fip->ctlr_mutex); | 2761 | mutex_lock(&fip->ctlr_mutex); |
2767 | switch (sub) { | 2762 | switch (sub) { |
2768 | case FIP_SC_VN_PROBE_REQ: | 2763 | case FIP_SC_VN_PROBE_REQ: |
2769 | fcoe_ctlr_vn_probe_req(fip, &buf.rdata); | 2764 | fcoe_ctlr_vn_probe_req(fip, &frport.rdata); |
2770 | break; | 2765 | break; |
2771 | case FIP_SC_VN_PROBE_REP: | 2766 | case FIP_SC_VN_PROBE_REP: |
2772 | fcoe_ctlr_vn_probe_reply(fip, &buf.rdata); | 2767 | fcoe_ctlr_vn_probe_reply(fip, &frport.rdata); |
2773 | break; | 2768 | break; |
2774 | case FIP_SC_VN_CLAIM_NOTIFY: | 2769 | case FIP_SC_VN_CLAIM_NOTIFY: |
2775 | fcoe_ctlr_vn_claim_notify(fip, &buf.rdata); | 2770 | fcoe_ctlr_vn_claim_notify(fip, &frport.rdata); |
2776 | break; | 2771 | break; |
2777 | case FIP_SC_VN_CLAIM_REP: | 2772 | case FIP_SC_VN_CLAIM_REP: |
2778 | fcoe_ctlr_vn_claim_resp(fip, &buf.rdata); | 2773 | fcoe_ctlr_vn_claim_resp(fip, &frport.rdata); |
2779 | break; | 2774 | break; |
2780 | case FIP_SC_VN_BEACON: | 2775 | case FIP_SC_VN_BEACON: |
2781 | fcoe_ctlr_vn_beacon(fip, &buf.rdata); | 2776 | fcoe_ctlr_vn_beacon(fip, &frport.rdata); |
2782 | break; | 2777 | break; |
2783 | default: | 2778 | default: |
2784 | LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub); | 2779 | LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub); |
@@ -2802,22 +2797,18 @@ drop: | |||
2802 | */ | 2797 | */ |
2803 | static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip, | 2798 | static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip, |
2804 | struct sk_buff *skb, | 2799 | struct sk_buff *skb, |
2805 | struct fc_rport_priv *rdata) | 2800 | struct fcoe_rport *frport) |
2806 | { | 2801 | { |
2807 | struct fip_header *fiph; | 2802 | struct fip_header *fiph; |
2808 | struct fip_desc *desc = NULL; | 2803 | struct fip_desc *desc = NULL; |
2809 | struct fip_mac_desc *macd = NULL; | 2804 | struct fip_mac_desc *macd = NULL; |
2810 | struct fip_wwn_desc *wwn = NULL; | 2805 | struct fip_wwn_desc *wwn = NULL; |
2811 | struct fcoe_rport *frport; | ||
2812 | size_t rlen; | 2806 | size_t rlen; |
2813 | size_t dlen; | 2807 | size_t dlen; |
2814 | u32 desc_mask = 0; | 2808 | u32 desc_mask = 0; |
2815 | u32 dtype; | 2809 | u32 dtype; |
2816 | u8 sub; | 2810 | u8 sub; |
2817 | 2811 | ||
2818 | memset(rdata, 0, sizeof(*rdata) + sizeof(*frport)); | ||
2819 | frport = fcoe_ctlr_rport(rdata); | ||
2820 | |||
2821 | fiph = (struct fip_header *)skb->data; | 2812 | fiph = (struct fip_header *)skb->data; |
2822 | frport->flags = ntohs(fiph->fip_flags); | 2813 | frport->flags = ntohs(fiph->fip_flags); |
2823 | 2814 | ||
@@ -2871,7 +2862,8 @@ static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip, | |||
2871 | if (dlen != sizeof(struct fip_wwn_desc)) | 2862 | if (dlen != sizeof(struct fip_wwn_desc)) |
2872 | goto len_err; | 2863 | goto len_err; |
2873 | wwn = (struct fip_wwn_desc *)desc; | 2864 | wwn = (struct fip_wwn_desc *)desc; |
2874 | rdata->ids.node_name = get_unaligned_be64(&wwn->fd_wwn); | 2865 | frport->rdata.ids.node_name = |
2866 | get_unaligned_be64(&wwn->fd_wwn); | ||
2875 | break; | 2867 | break; |
2876 | default: | 2868 | default: |
2877 | LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x " | 2869 | LIBFCOE_FIP_DBG(fip, "unexpected descriptor type %x " |
@@ -2982,22 +2974,19 @@ static int fcoe_ctlr_vlan_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) | |||
2982 | { | 2974 | { |
2983 | struct fip_header *fiph; | 2975 | struct fip_header *fiph; |
2984 | enum fip_vlan_subcode sub; | 2976 | enum fip_vlan_subcode sub; |
2985 | struct { | 2977 | struct fcoe_rport frport = { }; |
2986 | struct fc_rport_priv rdata; | ||
2987 | struct fcoe_rport frport; | ||
2988 | } buf; | ||
2989 | int rc; | 2978 | int rc; |
2990 | 2979 | ||
2991 | fiph = (struct fip_header *)skb->data; | 2980 | fiph = (struct fip_header *)skb->data; |
2992 | sub = fiph->fip_subcode; | 2981 | sub = fiph->fip_subcode; |
2993 | rc = fcoe_ctlr_vlan_parse(fip, skb, &buf.rdata); | 2982 | rc = fcoe_ctlr_vlan_parse(fip, skb, &frport); |
2994 | if (rc) { | 2983 | if (rc) { |
2995 | LIBFCOE_FIP_DBG(fip, "vlan_recv vlan_parse error %d\n", rc); | 2984 | LIBFCOE_FIP_DBG(fip, "vlan_recv vlan_parse error %d\n", rc); |
2996 | goto drop; | 2985 | goto drop; |
2997 | } | 2986 | } |
2998 | mutex_lock(&fip->ctlr_mutex); | 2987 | mutex_lock(&fip->ctlr_mutex); |
2999 | if (sub == FIP_SC_VL_REQ) | 2988 | if (sub == FIP_SC_VL_REQ) |
3000 | fcoe_ctlr_vlan_disc_reply(fip, &buf.rdata); | 2989 | fcoe_ctlr_vlan_disc_reply(fip, &frport.rdata); |
3001 | mutex_unlock(&fip->ctlr_mutex); | 2990 | mutex_unlock(&fip->ctlr_mutex); |
3002 | 2991 | ||
3003 | drop: | 2992 | drop: |
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index e0f3852fdad1..da6e97d8dc3b 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c | |||
@@ -128,6 +128,7 @@ EXPORT_SYMBOL(fc_rport_lookup); | |||
128 | struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id) | 128 | struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id) |
129 | { | 129 | { |
130 | struct fc_rport_priv *rdata; | 130 | struct fc_rport_priv *rdata; |
131 | size_t rport_priv_size = sizeof(*rdata); | ||
131 | 132 | ||
132 | lockdep_assert_held(&lport->disc.disc_mutex); | 133 | lockdep_assert_held(&lport->disc.disc_mutex); |
133 | 134 | ||
@@ -135,7 +136,9 @@ struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id) | |||
135 | if (rdata) | 136 | if (rdata) |
136 | return rdata; | 137 | return rdata; |
137 | 138 | ||
138 | rdata = kzalloc(sizeof(*rdata) + lport->rport_priv_size, GFP_KERNEL); | 139 | if (lport->rport_priv_size > 0) |
140 | rport_priv_size = lport->rport_priv_size; | ||
141 | rdata = kzalloc(rport_priv_size, GFP_KERNEL); | ||
139 | if (!rdata) | 142 | if (!rdata) |
140 | return NULL; | 143 | return NULL; |
141 | 144 | ||
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h index dc14b52577f7..2568cb0627ec 100644 --- a/include/scsi/libfcoe.h +++ b/include/scsi/libfcoe.h | |||
@@ -229,6 +229,7 @@ struct fcoe_fcf { | |||
229 | * @vn_mac: VN_Node assigned MAC address for data | 229 | * @vn_mac: VN_Node assigned MAC address for data |
230 | */ | 230 | */ |
231 | struct fcoe_rport { | 231 | struct fcoe_rport { |
232 | struct fc_rport_priv rdata; | ||
232 | unsigned long time; | 233 | unsigned long time; |
233 | u16 fcoe_len; | 234 | u16 fcoe_len; |
234 | u16 flags; | 235 | u16 flags; |