summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2019-07-24 05:00:55 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2019-07-29 21:12:35 -0400
commit023358b136d490ca91735ac6490db3741af5a8bd (patch)
treebe5370ccb0eb4ca07c29875a25de42d56d8e6416
parentf3e4ff28b8685d856f381ee6bcf88b6149a6db5b (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.c51
-rw-r--r--drivers/scsi/libfc/fc_rport.c5
-rw-r--r--include/scsi/libfcoe.h1
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 */
2006static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata) 2006static 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 */
2270static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, 2270static 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 */
2803static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip, 2798static 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
3003drop: 2992drop:
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);
128struct fc_rport_priv *fc_rport_create(struct fc_lport *lport, u32 port_id) 128struct 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 */
231struct fcoe_rport { 231struct 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;