On 08/30, Enzo Matsumiya wrote:
Since only SMB 3.0 and 3.0.2 uses it, and they use the same operations struct, remove the ->validate_negotiate server op and just check for server->dialect on the only caller (SMB2_tcon()). - rename smb3_validate_negotiate() to smb30_validate_negotiate() to be more explict - remove check for SMB311_PROT_ID since it's unreachable anyway - simplify dialect counting by using a counter Signed-off-by: Enzo Matsumiya <ematsumiya@xxxxxxx> --- fs/cifs/cifsglob.h | 1 - fs/cifs/smb2ops.c | 2 -- fs/cifs/smb2pdu.c | 62 ++++++++++++++++++++++----------------------- fs/cifs/smb2proto.h | 1 - 4 files changed, 30 insertions(+), 36 deletions(-) ... snip ... @@ -1143,35 +1145,30 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) else pneg_inbuf->SecurityMode = 0; - - if (strcmp(server->vals->version_string, - SMB3ANY_VERSION_STRING) == 0) { - pneg_inbuf->Dialects[0] = cpu_to_le16(SMB30_PROT_ID); - pneg_inbuf->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); - pneg_inbuf->Dialects[2] = cpu_to_le16(SMB311_PROT_ID); - pneg_inbuf->DialectCount = cpu_to_le16(3); - /* SMB 2.1 not included so subtract one dialect from len */ - inbuflen = sizeof(*pneg_inbuf) - - (sizeof(pneg_inbuf->Dialects[0])); - } else if (strcmp(server->vals->version_string, - SMBDEFAULT_VERSION_STRING) == 0) { - pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); - pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); - pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID); - pneg_inbuf->Dialects[3] = cpu_to_le16(SMB311_PROT_ID); - pneg_inbuf->DialectCount = cpu_to_le16(4); + i = 0; + if (!strcmp(server->vals->version_string, SMB3ANY_VERSION_STRING)) { + pneg_inbuf->Dialects[i++] = cpu_to_le16(SMB30_PROT_ID); + pneg_inbuf->Dialects[i++] = cpu_to_le16(SMB302_PROT_ID); + pneg_inbuf->Dialects[i++] = cpu_to_le16(SMB311_PROT_ID); + /* SMB 2.1 not included */ + } else if (!strcmp(server->vals->version_string, SMBDEFAULT_VERSION_STRING)) { + pneg_inbuf->Dialects[i++] = cpu_to_le16(SMB21_PROT_ID); + pneg_inbuf->Dialects[i++] = cpu_to_le16(SMB30_PROT_ID); + pneg_inbuf->Dialects[i++] = cpu_to_le16(SMB302_PROT_ID); + pneg_inbuf->Dialects[i++] = cpu_to_le16(SMB311_PROT_ID); /* structure is big enough for 4 dialects */ - inbuflen = sizeof(*pneg_inbuf); } else { /* otherwise specific dialect was requested */ - pneg_inbuf->Dialects[0] = - cpu_to_le16(server->vals->protocol_id); - pneg_inbuf->DialectCount = cpu_to_le16(1); - /* structure is big enough for 3 dialects, sending only 1 */ - inbuflen = sizeof(*pneg_inbuf) - - sizeof(pneg_inbuf->Dialects[0]) * 2; + pneg_inbuf->Dialects[i++] = cpu_to_le16(server->vals->protocol_id); } + pneg_inbuf->DialectCount = cpu_to_le16(i); + /* + * The structure holds 4 dialects at most, so subtract the number of dialects not added, + * if any. + */ + inbuflen = sizeof(*pneg_inbuf) - (sizeof(pneg_inbuf->Dialects[0]) * (4 - i)); + rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID, FSCTL_VALIDATE_NEGOTIATE_INFO, (char *)pneg_inbuf, inbuflen, CIFSMaxBufSize,
The hunk above will conflict with Zhang's patch "[PATCH v2 1/3] cifs: Fix the error length of VALIDATE_NEGOTIATE_INFO message", but this way is, IMHO, safer for future modifications because it doesn't use hardcoded values. It might actually make sense to even define a "SMB2_MAX_DIALECTS" to 4 here. Let me know what you think. Cheers, Enzo