Commit 7330195e authored by Gustavo A. R. Silva's avatar Gustavo A. R. Silva Committed by Steve French
Browse files

smb: client, common: Avoid multiple -Wflex-array-member-not-at-end warnings



-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: default avatarGustavo A. R. Silva <gustavoars@kernel.org>
Acked-by: default avatarPaulo Alcantara (Red Hat) <pc@manguebit.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 654292a0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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;
};

+20 −10
Original line number Diff line number Diff line
@@ -1707,23 +1707,33 @@ struct smb2_file_internal_info {
} __packed; /* level 6 Query */

struct smb2_file_rename_info { /* encoding of request for level 10 */
	/* 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 */
	/* 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