diff options
| author | Pavel Shilovsky <pshilov@microsoft.com> | 2016-10-24 19:59:57 -0400 |
|---|---|---|
| committer | Steve French <smfrench@gmail.com> | 2017-02-01 17:46:35 -0500 |
| commit | cb200bd6264a80c04e09e8635fa4f3901cabdaef (patch) | |
| tree | 40cab9532abad0920fb8ff05573ac0a1b4bac931 /fs | |
| parent | 738f9de5cdb9175c19d24cfdf90b4543fc3b47bf (diff) | |
CIFS: Separate SMB2 sync header processing
Do not process RFC1001 length in smb2_hdr_assemble() because
it is not a part of SMB2 header. This allows to cleanup the code
and adds a possibility combine several SMB2 packets into one
for compounding.
Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com>
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/cifs/smb2pdu.c | 50 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.h | 5 |
2 files changed, 35 insertions, 20 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 438c4b108c07..f6ba2c03f7cc 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
| @@ -79,25 +79,9 @@ static const int smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = { | |||
| 79 | 79 | ||
| 80 | 80 | ||
| 81 | static void | 81 | static void |
| 82 | smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ , | 82 | smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd, |
| 83 | const struct cifs_tcon *tcon) | 83 | const struct cifs_tcon *tcon) |
| 84 | { | 84 | { |
| 85 | struct smb2_pdu *pdu = (struct smb2_pdu *)hdr; | ||
| 86 | struct smb2_sync_hdr *shdr = get_sync_hdr(hdr); | ||
| 87 | char *temp = (char *)hdr; | ||
| 88 | /* lookup word count ie StructureSize from table */ | ||
| 89 | __u16 parmsize = smb2_req_struct_sizes[le16_to_cpu(smb2_cmd)]; | ||
| 90 | |||
| 91 | /* | ||
| 92 | * smaller than SMALL_BUFFER_SIZE but bigger than fixed area of | ||
| 93 | * largest operations (Create) | ||
| 94 | */ | ||
| 95 | memset(temp, 0, 256); | ||
| 96 | |||
| 97 | /* Note this is only network field converted to big endian */ | ||
| 98 | hdr->smb2_buf_length = | ||
| 99 | cpu_to_be32(parmsize + sizeof(struct smb2_sync_hdr)); | ||
| 100 | |||
| 101 | shdr->ProtocolId = SMB2_PROTO_NUMBER; | 85 | shdr->ProtocolId = SMB2_PROTO_NUMBER; |
| 102 | shdr->StructureSize = cpu_to_le16(64); | 86 | shdr->StructureSize = cpu_to_le16(64); |
| 103 | shdr->Command = smb2_cmd; | 87 | shdr->Command = smb2_cmd; |
| @@ -149,7 +133,6 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ , | |||
| 149 | if (tcon->ses && tcon->ses->server && tcon->ses->server->sign) | 133 | if (tcon->ses && tcon->ses->server && tcon->ses->server->sign) |
| 150 | shdr->Flags |= SMB2_FLAGS_SIGNED; | 134 | shdr->Flags |= SMB2_FLAGS_SIGNED; |
| 151 | out: | 135 | out: |
| 152 | pdu->StructureSize2 = cpu_to_le16(parmsize); | ||
| 153 | return; | 136 | return; |
| 154 | } | 137 | } |
| 155 | 138 | ||
| @@ -290,6 +273,26 @@ out: | |||
| 290 | return rc; | 273 | return rc; |
| 291 | } | 274 | } |
| 292 | 275 | ||
| 276 | static void | ||
| 277 | fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon, void *buf, | ||
| 278 | unsigned int *total_len) | ||
| 279 | { | ||
| 280 | struct smb2_sync_pdu *spdu = (struct smb2_sync_pdu *)buf; | ||
| 281 | /* lookup word count ie StructureSize from table */ | ||
| 282 | __u16 parmsize = smb2_req_struct_sizes[le16_to_cpu(smb2_command)]; | ||
| 283 | |||
| 284 | /* | ||
| 285 | * smaller than SMALL_BUFFER_SIZE but bigger than fixed area of | ||
| 286 | * largest operations (Create) | ||
| 287 | */ | ||
| 288 | memset(buf, 0, 256); | ||
| 289 | |||
| 290 | smb2_hdr_assemble(&spdu->sync_hdr, smb2_command, tcon); | ||
| 291 | spdu->StructureSize2 = cpu_to_le16(parmsize); | ||
| 292 | |||
| 293 | *total_len = parmsize + sizeof(struct smb2_sync_hdr); | ||
| 294 | } | ||
| 295 | |||
| 293 | /* | 296 | /* |
| 294 | * Allocate and return pointer to an SMB request hdr, and set basic | 297 | * Allocate and return pointer to an SMB request hdr, and set basic |
| 295 | * SMB information in the SMB header. If the return code is zero, this | 298 | * SMB information in the SMB header. If the return code is zero, this |
| @@ -299,7 +302,9 @@ static int | |||
| 299 | small_smb2_init(__le16 smb2_command, struct cifs_tcon *tcon, | 302 | small_smb2_init(__le16 smb2_command, struct cifs_tcon *tcon, |
| 300 | void **request_buf) | 303 | void **request_buf) |
| 301 | { | 304 | { |
| 302 | int rc = 0; | 305 | int rc; |
| 306 | unsigned int total_len; | ||
| 307 | struct smb2_pdu *pdu; | ||
| 303 | 308 | ||
| 304 | rc = smb2_reconnect(smb2_command, tcon); | 309 | rc = smb2_reconnect(smb2_command, tcon); |
| 305 | if (rc) | 310 | if (rc) |
| @@ -312,7 +317,12 @@ small_smb2_init(__le16 smb2_command, struct cifs_tcon *tcon, | |||
| 312 | return -ENOMEM; | 317 | return -ENOMEM; |
| 313 | } | 318 | } |
| 314 | 319 | ||
| 315 | smb2_hdr_assemble((struct smb2_hdr *) *request_buf, smb2_command, tcon); | 320 | pdu = (struct smb2_pdu *)(*request_buf); |
| 321 | |||
| 322 | fill_small_buf(smb2_command, tcon, get_sync_hdr(pdu), &total_len); | ||
| 323 | |||
| 324 | /* Note this is only network field converted to big endian */ | ||
| 325 | pdu->hdr.smb2_buf_length = cpu_to_be32(total_len); | ||
| 316 | 326 | ||
| 317 | if (tcon != NULL) { | 327 | if (tcon != NULL) { |
| 318 | #ifdef CONFIG_CIFS_STATS2 | 328 | #ifdef CONFIG_CIFS_STATS2 |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index 8dd24b73d974..052342da4844 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
| @@ -117,6 +117,11 @@ struct smb2_sync_hdr { | |||
| 117 | __u8 Signature[16]; | 117 | __u8 Signature[16]; |
| 118 | } __packed; | 118 | } __packed; |
| 119 | 119 | ||
| 120 | struct smb2_sync_pdu { | ||
| 121 | struct smb2_sync_hdr sync_hdr; | ||
| 122 | __le16 StructureSize2; /* size of wct area (varies, request specific) */ | ||
| 123 | } __packed; | ||
| 124 | |||
| 120 | struct smb2_hdr { | 125 | struct smb2_hdr { |
| 121 | __be32 smb2_buf_length; /* big endian on wire */ | 126 | __be32 smb2_buf_length; /* big endian on wire */ |
| 122 | /* length is only two or three bytes - with */ | 127 | /* length is only two or three bytes - with */ |
