]> www.infradead.org Git - users/hch/misc.git/commitdiff
smb: client, common: Avoid multiple -Wflex-array-member-not-at-end warnings
authorGustavo A. R. Silva <gustavoars@kernel.org>
Tue, 11 Feb 2025 10:21:25 +0000 (20:51 +1030)
committerSteve French <stfrench@microsoft.com>
Wed, 19 Feb 2025 16:39:32 +0000 (10:39 -0600)
-Wflex-array-member-not-at-end was introduced in GCC-14, and we are
getting ready to enable it, globally.

So, in order to avoid ending up with flexible-array members in the
middle of other structs, we use the `__struct_group()` helper to
separate the flexible arrays from the rest of the members in the
flexible structures. We then use the newly created tagged `struct
smb2_file_link_info_hdr` and `struct smb2_file_rename_info_hdr`
to replace the type of the objects causing trouble: `rename_info`
and `link_info` in `struct smb2_compound_vars`.

We also want to ensure that when new members need to be added to the
flexible structures, they are always included within the newly created
tagged structs. For this, we use `static_assert()`. This ensures that the
memory layout for both the flexible structure and the new tagged struct
is the same after any changes.

So, with these changes, fix 86 of the following warnings:

fs/smb/client/cifsglob.h:2335:36: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
fs/smb/client/cifsglob.h:2334:38: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]

Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Acked-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/cifsglob.h
fs/smb/common/smb2pdu.h

index 4bdd6a43e5215effcdd34218fa6af367eb987030..bc06b8ae2ebd49cdc071610adf47565b13ee1680 100644 (file)
@@ -2324,8 +2324,8 @@ struct smb2_compound_vars {
        struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
        struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
        struct kvec close_iov;
-       struct smb2_file_rename_info rename_info;
-       struct smb2_file_link_info link_info;
+       struct smb2_file_rename_info_hdr rename_info;
+       struct smb2_file_link_info_hdr link_info;
        struct kvec ea_iov;
 };
 
index 3336df2ea5d4a50d2c24318fe520e389a4b05af7..c7a0efda440367c18f85c40638e34b4606b0ec9f 100644 (file)
@@ -1707,23 +1707,33 @@ struct smb2_file_internal_info {
 } __packed; /* level 6 Query */
 
 struct smb2_file_rename_info { /* encoding of request for level 10 */
-       __u8   ReplaceIfExists; /* 1 = replace existing target with new */
-                               /* 0 = fail if target already exists */
-       __u8   Reserved[7];
-       __u64  RootDirectory;  /* MBZ for network operations (why says spec?) */
-       __le32 FileNameLength;
+       /* New members MUST be added within the struct_group() macro below. */
+       __struct_group(smb2_file_rename_info_hdr, __hdr, __packed,
+               __u8   ReplaceIfExists; /* 1 = replace existing target with new */
+                                       /* 0 = fail if target already exists */
+               __u8   Reserved[7];
+               __u64  RootDirectory;  /* MBZ for network operations (why says spec?) */
+               __le32 FileNameLength;
+       );
        char   FileName[];     /* New name to be assigned */
        /* padding - overall struct size must be >= 24 so filename + pad >= 6 */
 } __packed; /* level 10 Set */
+static_assert(offsetof(struct smb2_file_rename_info, FileName) == sizeof(struct smb2_file_rename_info_hdr),
+             "struct member likely outside of __struct_group()");
 
 struct smb2_file_link_info { /* encoding of request for level 11 */
-       __u8   ReplaceIfExists; /* 1 = replace existing link with new */
-                               /* 0 = fail if link already exists */
-       __u8   Reserved[7];
-       __u64  RootDirectory;  /* MBZ for network operations (why says spec?) */
-       __le32 FileNameLength;
+       /* New members MUST be added within the struct_group() macro below. */
+       __struct_group(smb2_file_link_info_hdr, __hdr, __packed,
+               __u8   ReplaceIfExists; /* 1 = replace existing link with new */
+                                       /* 0 = fail if link already exists */
+               __u8   Reserved[7];
+               __u64  RootDirectory;  /* MBZ for network operations (why says spec?) */
+               __le32 FileNameLength;
+       );
        char   FileName[];     /* Name to be assigned to new link */
 } __packed; /* level 11 Set */
+static_assert(offsetof(struct smb2_file_link_info, FileName) == sizeof(struct smb2_file_link_info_hdr),
+             "struct member likely outside of __struct_group()");
 
 /*
  * This level 18, although with struct with same name is different from cifs