diff options
| -rw-r--r-- | fs/cifs/smb2ops.c | 7 | ||||
| -rw-r--r-- | fs/cifs/smb2proto.h | 2 | ||||
| -rw-r--r-- | fs/cifs/smbdirect.c | 19 | ||||
| -rw-r--r-- | fs/cifs/transport.c | 19 |
4 files changed, 24 insertions, 23 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index badcfb2f3c22..0356b5559c71 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
| @@ -2485,7 +2485,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq, | |||
| 2485 | struct page **pages; | 2485 | struct page **pages; |
| 2486 | struct smb2_transform_hdr *tr_hdr; | 2486 | struct smb2_transform_hdr *tr_hdr; |
| 2487 | unsigned int npages = old_rq->rq_npages; | 2487 | unsigned int npages = old_rq->rq_npages; |
| 2488 | unsigned int orig_len = 0; | 2488 | unsigned int orig_len; |
| 2489 | int i; | 2489 | int i; |
| 2490 | int rc = -ENOMEM; | 2490 | int rc = -ENOMEM; |
| 2491 | 2491 | ||
| @@ -2499,9 +2499,6 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq, | |||
| 2499 | new_rq->rq_pagesz = old_rq->rq_pagesz; | 2499 | new_rq->rq_pagesz = old_rq->rq_pagesz; |
| 2500 | new_rq->rq_tailsz = old_rq->rq_tailsz; | 2500 | new_rq->rq_tailsz = old_rq->rq_tailsz; |
| 2501 | 2501 | ||
| 2502 | for (i = 0; i < old_rq->rq_nvec; i++) | ||
| 2503 | orig_len += old_rq->rq_iov[i].iov_len; | ||
| 2504 | |||
| 2505 | for (i = 0; i < npages; i++) { | 2502 | for (i = 0; i < npages; i++) { |
| 2506 | pages[i] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM); | 2503 | pages[i] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM); |
| 2507 | if (!pages[i]) | 2504 | if (!pages[i]) |
| @@ -2524,6 +2521,8 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq, | |||
| 2524 | if (!tr_hdr) | 2521 | if (!tr_hdr) |
| 2525 | goto err_free_iov; | 2522 | goto err_free_iov; |
| 2526 | 2523 | ||
| 2524 | orig_len = smb2_rqst_len(old_rq, false); | ||
| 2525 | |||
| 2527 | /* fill the 2nd iov with a transform header */ | 2526 | /* fill the 2nd iov with a transform header */ |
| 2528 | fill_transform_hdr(tr_hdr, orig_len, old_rq); | 2527 | fill_transform_hdr(tr_hdr, orig_len, old_rq); |
| 2529 | new_rq->rq_iov[0].iov_base = tr_hdr; | 2528 | new_rq->rq_iov[0].iov_base = tr_hdr; |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 78371c1a6503..3ae208ac2a77 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
| @@ -113,6 +113,8 @@ extern int smb2_unlock_range(struct cifsFileInfo *cfile, | |||
| 113 | extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile); | 113 | extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile); |
| 114 | extern void smb2_reconnect_server(struct work_struct *work); | 114 | extern void smb2_reconnect_server(struct work_struct *work); |
| 115 | extern int smb3_crypto_aead_allocate(struct TCP_Server_Info *server); | 115 | extern int smb3_crypto_aead_allocate(struct TCP_Server_Info *server); |
| 116 | extern unsigned long | ||
| 117 | smb2_rqst_len(struct smb_rqst *rqst, bool skip_rfc1002_marker); | ||
| 116 | 118 | ||
| 117 | /* | 119 | /* |
| 118 | * SMB2 Worker functions - most of protocol specific implementation details | 120 | * SMB2 Worker functions - most of protocol specific implementation details |
diff --git a/fs/cifs/smbdirect.c b/fs/cifs/smbdirect.c index e459c97151b3..6fd94d9ffac2 100644 --- a/fs/cifs/smbdirect.c +++ b/fs/cifs/smbdirect.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "smbdirect.h" | 18 | #include "smbdirect.h" |
| 19 | #include "cifs_debug.h" | 19 | #include "cifs_debug.h" |
| 20 | #include "cifsproto.h" | 20 | #include "cifsproto.h" |
| 21 | #include "smb2proto.h" | ||
| 21 | 22 | ||
| 22 | static struct smbd_response *get_empty_queue_buffer( | 23 | static struct smbd_response *get_empty_queue_buffer( |
| 23 | struct smbd_connection *info); | 24 | struct smbd_connection *info); |
| @@ -2087,7 +2088,7 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst) | |||
| 2087 | struct kvec vec; | 2088 | struct kvec vec; |
| 2088 | int nvecs; | 2089 | int nvecs; |
| 2089 | int size; | 2090 | int size; |
| 2090 | unsigned int buflen = 0, remaining_data_length; | 2091 | unsigned int buflen, remaining_data_length; |
| 2091 | int start, i, j; | 2092 | int start, i, j; |
| 2092 | int max_iov_size = | 2093 | int max_iov_size = |
| 2093 | info->max_send_size - sizeof(struct smbd_data_transfer); | 2094 | info->max_send_size - sizeof(struct smbd_data_transfer); |
| @@ -2111,25 +2112,13 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst) | |||
| 2111 | log_write(ERR, "expected the pdu length in 1st iov, but got %zu\n", rqst->rq_iov[0].iov_len); | 2112 | log_write(ERR, "expected the pdu length in 1st iov, but got %zu\n", rqst->rq_iov[0].iov_len); |
| 2112 | return -EINVAL; | 2113 | return -EINVAL; |
| 2113 | } | 2114 | } |
| 2114 | iov = &rqst->rq_iov[1]; | ||
| 2115 | |||
| 2116 | /* total up iov array first */ | ||
| 2117 | for (i = 0; i < rqst->rq_nvec-1; i++) { | ||
| 2118 | buflen += iov[i].iov_len; | ||
| 2119 | } | ||
| 2120 | 2115 | ||
| 2121 | /* | 2116 | /* |
| 2122 | * Add in the page array if there is one. The caller needs to set | 2117 | * Add in the page array if there is one. The caller needs to set |
| 2123 | * rq_tailsz to PAGE_SIZE when the buffer has multiple pages and | 2118 | * rq_tailsz to PAGE_SIZE when the buffer has multiple pages and |
| 2124 | * ends at page boundary | 2119 | * ends at page boundary |
| 2125 | */ | 2120 | */ |
| 2126 | if (rqst->rq_npages) { | 2121 | buflen = smb2_rqst_len(rqst, true); |
| 2127 | if (rqst->rq_npages == 1) | ||
| 2128 | buflen += rqst->rq_tailsz; | ||
| 2129 | else | ||
| 2130 | buflen += rqst->rq_pagesz * (rqst->rq_npages - 1) - | ||
| 2131 | rqst->rq_offset + rqst->rq_tailsz; | ||
| 2132 | } | ||
| 2133 | 2122 | ||
| 2134 | if (buflen + sizeof(struct smbd_data_transfer) > | 2123 | if (buflen + sizeof(struct smbd_data_transfer) > |
| 2135 | info->max_fragmented_send_size) { | 2124 | info->max_fragmented_send_size) { |
| @@ -2139,6 +2128,8 @@ int smbd_send(struct smbd_connection *info, struct smb_rqst *rqst) | |||
| 2139 | goto done; | 2128 | goto done; |
| 2140 | } | 2129 | } |
| 2141 | 2130 | ||
| 2131 | iov = &rqst->rq_iov[1]; | ||
| 2132 | |||
| 2142 | cifs_dbg(FYI, "Sending smb (RDMA): smb_len=%u\n", buflen); | 2133 | cifs_dbg(FYI, "Sending smb (RDMA): smb_len=%u\n", buflen); |
| 2143 | for (i = 0; i < rqst->rq_nvec-1; i++) | 2134 | for (i = 0; i < rqst->rq_nvec-1; i++) |
| 2144 | dump_smb(iov[i].iov_base, iov[i].iov_len); | 2135 | dump_smb(iov[i].iov_base, iov[i].iov_len); |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index a3ea42a4cb98..fb57dfbfb749 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
| @@ -201,15 +201,24 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg, | |||
| 201 | return 0; | 201 | return 0; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | static unsigned long | 204 | unsigned long |
| 205 | smb2_rqst_len(struct smb_rqst *rqst) | 205 | smb2_rqst_len(struct smb_rqst *rqst, bool skip_rfc1002_marker) |
| 206 | { | 206 | { |
| 207 | unsigned int i; | 207 | unsigned int i; |
| 208 | struct kvec *iov = rqst->rq_iov; | 208 | struct kvec *iov; |
| 209 | int nvec; | ||
| 209 | unsigned long buflen = 0; | 210 | unsigned long buflen = 0; |
| 210 | 211 | ||
| 212 | if (skip_rfc1002_marker && rqst->rq_iov[0].iov_len == 4) { | ||
| 213 | iov = &rqst->rq_iov[1]; | ||
| 214 | nvec = rqst->rq_nvec - 1; | ||
| 215 | } else { | ||
| 216 | iov = rqst->rq_iov; | ||
| 217 | nvec = rqst->rq_nvec; | ||
| 218 | } | ||
| 219 | |||
| 211 | /* total up iov array first */ | 220 | /* total up iov array first */ |
| 212 | for (i = 0; i < rqst->rq_nvec; i++) | 221 | for (i = 0; i < nvec; i++) |
| 213 | buflen += iov[i].iov_len; | 222 | buflen += iov[i].iov_len; |
| 214 | 223 | ||
| 215 | /* | 224 | /* |
| @@ -262,7 +271,7 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, | |||
| 262 | (char *)&val, sizeof(val)); | 271 | (char *)&val, sizeof(val)); |
| 263 | 272 | ||
| 264 | for (j = 0; j < num_rqst; j++) | 273 | for (j = 0; j < num_rqst; j++) |
| 265 | send_length += smb2_rqst_len(&rqst[j]); | 274 | send_length += smb2_rqst_len(&rqst[j], true); |
| 266 | rfc1002_marker = cpu_to_be32(send_length); | 275 | rfc1002_marker = cpu_to_be32(send_length); |
| 267 | 276 | ||
| 268 | /* Generate a rfc1002 marker for SMB2+ */ | 277 | /* Generate a rfc1002 marker for SMB2+ */ |
