hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/cifs/smb2pdu.c
....@@ -50,6 +50,9 @@
5050 #include "cifs_spnego.h"
5151 #include "smbdirect.h"
5252 #include "trace.h"
53
+#ifdef CONFIG_CIFS_DFS_UPCALL
54
+#include "dfs_cache.h"
55
+#endif
5356
5457 /*
5558 * The following table defines the expected "StructureSize" of SMB2 requests
....@@ -82,7 +85,7 @@
8285
8386 int smb3_encryption_required(const struct cifs_tcon *tcon)
8487 {
85
- if (!tcon)
88
+ if (!tcon || !tcon->ses)
8689 return 0;
8790 if ((tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) ||
8891 (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA))
....@@ -95,22 +98,21 @@
9598
9699 static void
97100 smb2_hdr_assemble(struct smb2_sync_hdr *shdr, __le16 smb2_cmd,
98
- const struct cifs_tcon *tcon)
101
+ const struct cifs_tcon *tcon,
102
+ struct TCP_Server_Info *server)
99103 {
100104 shdr->ProtocolId = SMB2_PROTO_NUMBER;
101105 shdr->StructureSize = cpu_to_le16(64);
102106 shdr->Command = smb2_cmd;
103
- if (tcon && tcon->ses && tcon->ses->server) {
104
- struct TCP_Server_Info *server = tcon->ses->server;
105
-
107
+ if (server) {
106108 spin_lock(&server->req_lock);
107
- /* Request up to 2 credits but don't go over the limit. */
109
+ /* Request up to 10 credits but don't go over the limit. */
108110 if (server->credits >= server->max_credits)
109111 shdr->CreditRequest = cpu_to_le16(0);
110112 else
111113 shdr->CreditRequest = cpu_to_le16(
112114 min_t(int, server->max_credits -
113
- server->credits, 2));
115
+ server->credits, 10));
114116 spin_unlock(&server->req_lock);
115117 } else {
116118 shdr->CreditRequest = cpu_to_le16(2);
....@@ -122,8 +124,7 @@
122124
123125 /* GLOBAL_CAP_LARGE_MTU will only be set if dialect > SMB2.02 */
124126 /* See sections 2.2.4 and 3.2.4.1.5 of MS-SMB2 */
125
- if ((tcon->ses) && (tcon->ses->server) &&
126
- (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
127
+ if (server && (server->capabilities & SMB2_GLOBAL_CAP_LARGE_MTU))
127128 shdr->CreditCharge = cpu_to_le16(1);
128129 /* else CreditCharge MBZ */
129130
....@@ -145,20 +146,20 @@
145146 /* if (tcon->share_flags & SHI1005_FLAGS_DFS)
146147 shdr->Flags |= SMB2_FLAGS_DFS_OPERATIONS; */
147148
148
- if (tcon->ses && tcon->ses->server && tcon->ses->server->sign &&
149
- !smb3_encryption_required(tcon))
149
+ if (server && server->sign && !smb3_encryption_required(tcon))
150150 shdr->Flags |= SMB2_FLAGS_SIGNED;
151151 out:
152152 return;
153153 }
154154
155155 static int
156
-smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon)
156
+smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon,
157
+ struct TCP_Server_Info *server)
157158 {
158159 int rc;
159160 struct nls_table *nls_codepage;
160161 struct cifs_ses *ses;
161
- struct TCP_Server_Info *server;
162
+ int retries;
162163
163164 /*
164165 * SMB2s NegProt, SessSetup, Logoff do not have tcon yet so
....@@ -186,15 +187,16 @@
186187 }
187188 }
188189 if ((!tcon->ses) || (tcon->ses->status == CifsExiting) ||
189
- (!tcon->ses->server))
190
+ (!tcon->ses->server) || !server)
190191 return -EIO;
191192
192193 ses = tcon->ses;
193
- server = ses->server;
194
+ retries = server->nr_targets;
194195
195196 /*
196
- * Give demultiplex thread up to 10 seconds to reconnect, should be
197
- * greater than cifs socket timeout which is 7 seconds
197
+ * Give demultiplex thread up to 10 seconds to each target available for
198
+ * reconnect -- should be greater than cifs socket timeout which is 7
199
+ * seconds.
198200 */
199201 while (server->tcpStatus == CifsNeedReconnect) {
200202 /*
....@@ -216,14 +218,17 @@
216218 (server->tcpStatus != CifsNeedReconnect),
217219 10 * HZ);
218220 if (rc < 0) {
219
- cifs_dbg(FYI, "%s: aborting reconnect due to a received"
220
- " signal by the process\n", __func__);
221
+ cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
222
+ __func__);
221223 return -ERESTARTSYS;
222224 }
223225
224226 /* are we still trying to reconnect? */
225227 if (server->tcpStatus != CifsNeedReconnect)
226228 break;
229
+
230
+ if (retries && --retries)
231
+ continue;
227232
228233 /*
229234 * on "soft" mounts we wait once. Hard mounts keep
....@@ -234,6 +239,7 @@
234239 cifs_dbg(FYI, "gave up waiting on reconnect in smb_init\n");
235240 return -EHOSTDOWN;
236241 }
242
+ retries = server->nr_targets;
237243 }
238244
239245 if (!tcon->ses->need_reconnect && !tcon->need_reconnect)
....@@ -258,15 +264,34 @@
258264 goto out;
259265 }
260266
267
+ /*
268
+ * If we are reconnecting an extra channel, bind
269
+ */
270
+ if (server->is_channel) {
271
+ ses->binding = true;
272
+ ses->binding_chan = cifs_ses_find_chan(ses, server);
273
+ }
274
+
261275 rc = cifs_negotiate_protocol(0, tcon->ses);
262276 if (!rc && tcon->ses->need_reconnect) {
263277 rc = cifs_setup_session(0, tcon->ses, nls_codepage);
264278 if ((rc == -EACCES) && !tcon->retry) {
265279 rc = -EHOSTDOWN;
280
+ ses->binding = false;
281
+ ses->binding_chan = NULL;
266282 mutex_unlock(&tcon->ses->session_mutex);
267283 goto failed;
284
+ } else if (rc) {
285
+ mutex_unlock(&ses->session_mutex);
286
+ goto out;
268287 }
269288 }
289
+ /*
290
+ * End of channel binding
291
+ */
292
+ ses->binding = false;
293
+ ses->binding_chan = NULL;
294
+
270295 if (rc || !tcon->need_reconnect) {
271296 mutex_unlock(&tcon->ses->session_mutex);
272297 goto out;
....@@ -276,18 +301,18 @@
276301 if (tcon->use_persistent)
277302 tcon->need_reopen_files = true;
278303
279
- rc = SMB2_tcon(0, tcon->ses, tcon->treeName, tcon, nls_codepage);
304
+ rc = cifs_tree_connect(0, tcon, nls_codepage);
280305 mutex_unlock(&tcon->ses->session_mutex);
281306
282307 cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
283308 if (rc) {
284309 /* If sess reconnected but tcon didn't, something strange ... */
285
- printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc);
310
+ pr_warn_once("reconnect tcon failed rc = %d\n", rc);
286311 goto out;
287312 }
288313
289314 if (smb2_command != SMB2_INTERNAL_CMD)
290
- queue_delayed_work(cifsiod_wq, &server->reconnect, 0);
315
+ mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
291316
292317 atomic_inc(&tconInfoReconnectCount);
293318 out:
....@@ -317,7 +342,9 @@
317342 }
318343
319344 static void
320
-fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon, void *buf,
345
+fill_small_buf(__le16 smb2_command, struct cifs_tcon *tcon,
346
+ struct TCP_Server_Info *server,
347
+ void *buf,
321348 unsigned int *total_len)
322349 {
323350 struct smb2_sync_pdu *spdu = (struct smb2_sync_pdu *)buf;
....@@ -330,7 +357,7 @@
330357 */
331358 memset(buf, 0, 256);
332359
333
- smb2_hdr_assemble(&spdu->sync_hdr, smb2_command, tcon);
360
+ smb2_hdr_assemble(&spdu->sync_hdr, smb2_command, tcon, server);
334361 spdu->StructureSize2 = cpu_to_le16(parmsize);
335362
336363 *total_len = parmsize + sizeof(struct smb2_sync_hdr);
....@@ -342,7 +369,8 @@
342369 * function must have filled in request_buf pointer.
343370 */
344371 static int __smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
345
- void **request_buf, unsigned int *total_len)
372
+ struct TCP_Server_Info *server,
373
+ void **request_buf, unsigned int *total_len)
346374 {
347375 /* BB eventually switch this to SMB2 specific small buf size */
348376 if (smb2_command == SMB2_SET_INFO)
....@@ -354,7 +382,7 @@
354382 return -ENOMEM;
355383 }
356384
357
- fill_small_buf(smb2_command, tcon,
385
+ fill_small_buf(smb2_command, tcon, server,
358386 (struct smb2_sync_hdr *)(*request_buf),
359387 total_len);
360388
....@@ -368,37 +396,33 @@
368396 }
369397
370398 static int smb2_plain_req_init(__le16 smb2_command, struct cifs_tcon *tcon,
399
+ struct TCP_Server_Info *server,
371400 void **request_buf, unsigned int *total_len)
372401 {
373402 int rc;
374403
375
- rc = smb2_reconnect(smb2_command, tcon);
404
+ rc = smb2_reconnect(smb2_command, tcon, server);
376405 if (rc)
377406 return rc;
378407
379
- return __smb2_plain_req_init(smb2_command, tcon, request_buf,
408
+ return __smb2_plain_req_init(smb2_command, tcon, server, request_buf,
380409 total_len);
381410 }
382411
383412 static int smb2_ioctl_req_init(u32 opcode, struct cifs_tcon *tcon,
413
+ struct TCP_Server_Info *server,
384414 void **request_buf, unsigned int *total_len)
385415 {
386416 /* Skip reconnect only for FSCTL_VALIDATE_NEGOTIATE_INFO IOCTLs */
387417 if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO) {
388
- return __smb2_plain_req_init(SMB2_IOCTL, tcon, request_buf,
389
- total_len);
418
+ return __smb2_plain_req_init(SMB2_IOCTL, tcon, server,
419
+ request_buf, total_len);
390420 }
391
- return smb2_plain_req_init(SMB2_IOCTL, tcon, request_buf, total_len);
421
+ return smb2_plain_req_init(SMB2_IOCTL, tcon, server,
422
+ request_buf, total_len);
392423 }
393424
394
-
395
-/* offset is sizeof smb2_negotiate_req but rounded up to 8 bytes */
396
-#define OFFSET_OF_NEG_CONTEXT 0x68 /* sizeof(struct smb2_negotiate_req) */
397
-
398
-
399
-#define SMB2_PREAUTH_INTEGRITY_CAPABILITIES cpu_to_le16(1)
400
-#define SMB2_ENCRYPTION_CAPABILITIES cpu_to_le16(2)
401
-#define SMB2_POSIX_EXTENSIONS_AVAILABLE cpu_to_le16(0x100)
425
+/* For explanation of negotiate contexts see MS-SMB2 section 2.2.3.1 */
402426
403427 static void
404428 build_preauth_ctxt(struct smb2_preauth_neg_context *pneg_ctxt)
....@@ -412,13 +436,52 @@
412436 }
413437
414438 static void
439
+build_compression_ctxt(struct smb2_compression_capabilities_context *pneg_ctxt)
440
+{
441
+ pneg_ctxt->ContextType = SMB2_COMPRESSION_CAPABILITIES;
442
+ pneg_ctxt->DataLength =
443
+ cpu_to_le16(sizeof(struct smb2_compression_capabilities_context)
444
+ - sizeof(struct smb2_neg_context));
445
+ pneg_ctxt->CompressionAlgorithmCount = cpu_to_le16(3);
446
+ pneg_ctxt->CompressionAlgorithms[0] = SMB3_COMPRESS_LZ77;
447
+ pneg_ctxt->CompressionAlgorithms[1] = SMB3_COMPRESS_LZ77_HUFF;
448
+ pneg_ctxt->CompressionAlgorithms[2] = SMB3_COMPRESS_LZNT1;
449
+}
450
+
451
+static void
415452 build_encrypt_ctxt(struct smb2_encryption_neg_context *pneg_ctxt)
416453 {
417454 pneg_ctxt->ContextType = SMB2_ENCRYPTION_CAPABILITIES;
418
- pneg_ctxt->DataLength = cpu_to_le16(4); /* Cipher Count + le16 cipher */
419
- pneg_ctxt->CipherCount = cpu_to_le16(1);
420
-/* pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;*/ /* not supported yet */
421
- pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_CCM;
455
+ if (require_gcm_256) {
456
+ pneg_ctxt->DataLength = cpu_to_le16(4); /* Cipher Count + 1 cipher */
457
+ pneg_ctxt->CipherCount = cpu_to_le16(1);
458
+ pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES256_GCM;
459
+ } else if (enable_gcm_256) {
460
+ pneg_ctxt->DataLength = cpu_to_le16(8); /* Cipher Count + 3 ciphers */
461
+ pneg_ctxt->CipherCount = cpu_to_le16(3);
462
+ pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;
463
+ pneg_ctxt->Ciphers[1] = SMB2_ENCRYPTION_AES256_GCM;
464
+ pneg_ctxt->Ciphers[2] = SMB2_ENCRYPTION_AES128_CCM;
465
+ } else {
466
+ pneg_ctxt->DataLength = cpu_to_le16(6); /* Cipher Count + 2 ciphers */
467
+ pneg_ctxt->CipherCount = cpu_to_le16(2);
468
+ pneg_ctxt->Ciphers[0] = SMB2_ENCRYPTION_AES128_GCM;
469
+ pneg_ctxt->Ciphers[1] = SMB2_ENCRYPTION_AES128_CCM;
470
+ }
471
+}
472
+
473
+static unsigned int
474
+build_netname_ctxt(struct smb2_netname_neg_context *pneg_ctxt, char *hostname)
475
+{
476
+ struct nls_table *cp = load_nls_default();
477
+
478
+ pneg_ctxt->ContextType = SMB2_NETNAME_NEGOTIATE_CONTEXT_ID;
479
+
480
+ /* copy up to max of first 100 bytes of server name to NetName field */
481
+ pneg_ctxt->DataLength = cpu_to_le16(2 * cifs_strtoUTF16(pneg_ctxt->NetName, hostname, 100, cp));
482
+ /* context size is DataLength + minimal smb2_neg_context */
483
+ return DIV_ROUND_UP(le16_to_cpu(pneg_ctxt->DataLength) +
484
+ sizeof(struct smb2_neg_context), 8) * 8;
422485 }
423486
424487 static void
....@@ -426,16 +489,47 @@
426489 {
427490 pneg_ctxt->ContextType = SMB2_POSIX_EXTENSIONS_AVAILABLE;
428491 pneg_ctxt->DataLength = cpu_to_le16(POSIX_CTXT_DATA_LEN);
492
+ /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
493
+ pneg_ctxt->Name[0] = 0x93;
494
+ pneg_ctxt->Name[1] = 0xAD;
495
+ pneg_ctxt->Name[2] = 0x25;
496
+ pneg_ctxt->Name[3] = 0x50;
497
+ pneg_ctxt->Name[4] = 0x9C;
498
+ pneg_ctxt->Name[5] = 0xB4;
499
+ pneg_ctxt->Name[6] = 0x11;
500
+ pneg_ctxt->Name[7] = 0xE7;
501
+ pneg_ctxt->Name[8] = 0xB4;
502
+ pneg_ctxt->Name[9] = 0x23;
503
+ pneg_ctxt->Name[10] = 0x83;
504
+ pneg_ctxt->Name[11] = 0xDE;
505
+ pneg_ctxt->Name[12] = 0x96;
506
+ pneg_ctxt->Name[13] = 0x8B;
507
+ pneg_ctxt->Name[14] = 0xCD;
508
+ pneg_ctxt->Name[15] = 0x7C;
429509 }
430510
431511 static void
432512 assemble_neg_contexts(struct smb2_negotiate_req *req,
433
- unsigned int *total_len)
513
+ struct TCP_Server_Info *server, unsigned int *total_len)
434514 {
435
- char *pneg_ctxt = (char *)req + OFFSET_OF_NEG_CONTEXT;
515
+ char *pneg_ctxt;
436516 unsigned int ctxt_len;
437517
438
- *total_len += 2; /* Add 2 due to round to 8 byte boundary for 1st ctxt */
518
+ if (*total_len > 200) {
519
+ /* In case length corrupted don't want to overrun smb buffer */
520
+ cifs_server_dbg(VFS, "Bad frame length assembling neg contexts\n");
521
+ return;
522
+ }
523
+
524
+ /*
525
+ * round up total_len of fixed part of SMB3 negotiate request to 8
526
+ * byte boundary before adding negotiate contexts
527
+ */
528
+ *total_len = roundup(*total_len, 8);
529
+
530
+ pneg_ctxt = (*total_len) + (char *)req;
531
+ req->NegotiateContextOffset = cpu_to_le32(*total_len);
532
+
439533 build_preauth_ctxt((struct smb2_preauth_neg_context *)pneg_ctxt);
440534 ctxt_len = DIV_ROUND_UP(sizeof(struct smb2_preauth_neg_context), 8) * 8;
441535 *total_len += ctxt_len;
....@@ -446,11 +540,25 @@
446540 *total_len += ctxt_len;
447541 pneg_ctxt += ctxt_len;
448542
543
+ if (server->compress_algorithm) {
544
+ build_compression_ctxt((struct smb2_compression_capabilities_context *)
545
+ pneg_ctxt);
546
+ ctxt_len = DIV_ROUND_UP(
547
+ sizeof(struct smb2_compression_capabilities_context),
548
+ 8) * 8;
549
+ *total_len += ctxt_len;
550
+ pneg_ctxt += ctxt_len;
551
+ req->NegotiateContextCount = cpu_to_le16(5);
552
+ } else
553
+ req->NegotiateContextCount = cpu_to_le16(4);
554
+
555
+ ctxt_len = build_netname_ctxt((struct smb2_netname_neg_context *)pneg_ctxt,
556
+ server->hostname);
557
+ *total_len += ctxt_len;
558
+ pneg_ctxt += ctxt_len;
559
+
449560 build_posix_ctxt((struct smb2_posix_neg_context *)pneg_ctxt);
450561 *total_len += sizeof(struct smb2_posix_neg_context);
451
-
452
- req->NegotiateContextOffset = cpu_to_le32(OFFSET_OF_NEG_CONTEXT);
453
- req->NegotiateContextCount = cpu_to_le16(3);
454562 }
455563
456564 static void decode_preauth_context(struct smb2_preauth_neg_context *ctxt)
....@@ -459,16 +567,37 @@
459567
460568 /* If invalid preauth context warn but use what we requested, SHA-512 */
461569 if (len < MIN_PREAUTH_CTXT_DATA_LEN) {
462
- printk_once(KERN_WARNING "server sent bad preauth context\n");
570
+ pr_warn_once("server sent bad preauth context\n");
463571 return;
464572 } else if (len < MIN_PREAUTH_CTXT_DATA_LEN + le16_to_cpu(ctxt->SaltLength)) {
465573 pr_warn_once("server sent invalid SaltLength\n");
466574 return;
467575 }
468576 if (le16_to_cpu(ctxt->HashAlgorithmCount) != 1)
469
- printk_once(KERN_WARNING "illegal SMB3 hash algorithm count\n");
577
+ pr_warn_once("Invalid SMB3 hash algorithm count\n");
470578 if (ctxt->HashAlgorithms != SMB2_PREAUTH_INTEGRITY_SHA512)
471
- printk_once(KERN_WARNING "unknown SMB3 hash algorithm\n");
579
+ pr_warn_once("unknown SMB3 hash algorithm\n");
580
+}
581
+
582
+static void decode_compress_ctx(struct TCP_Server_Info *server,
583
+ struct smb2_compression_capabilities_context *ctxt)
584
+{
585
+ unsigned int len = le16_to_cpu(ctxt->DataLength);
586
+
587
+ /* sizeof compress context is a one element compression capbility struct */
588
+ if (len < 10) {
589
+ pr_warn_once("server sent bad compression cntxt\n");
590
+ return;
591
+ }
592
+ if (le16_to_cpu(ctxt->CompressionAlgorithmCount) != 1) {
593
+ pr_warn_once("Invalid SMB3 compress algorithm count\n");
594
+ return;
595
+ }
596
+ if (le16_to_cpu(ctxt->CompressionAlgorithms[0]) > 3) {
597
+ pr_warn_once("unknown compression algorithm\n");
598
+ return;
599
+ }
600
+ server->compress_algorithm = ctxt->CompressionAlgorithms[0];
472601 }
473602
474603 static int decode_encrypt_ctx(struct TCP_Server_Info *server,
....@@ -478,18 +607,39 @@
478607
479608 cifs_dbg(FYI, "decode SMB3.11 encryption neg context of len %d\n", len);
480609 if (len < MIN_ENCRYPT_CTXT_DATA_LEN) {
481
- printk_once(KERN_WARNING "server sent bad crypto ctxt len\n");
610
+ pr_warn_once("server sent bad crypto ctxt len\n");
482611 return -EINVAL;
483612 }
484613
485614 if (le16_to_cpu(ctxt->CipherCount) != 1) {
486
- printk_once(KERN_WARNING "illegal SMB3.11 cipher count\n");
615
+ pr_warn_once("Invalid SMB3.11 cipher count\n");
487616 return -EINVAL;
488617 }
489618 cifs_dbg(FYI, "SMB311 cipher type:%d\n", le16_to_cpu(ctxt->Ciphers[0]));
490
- if ((ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES128_CCM) &&
491
- (ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES128_GCM)) {
492
- printk_once(KERN_WARNING "invalid SMB3.11 cipher returned\n");
619
+ if (require_gcm_256) {
620
+ if (ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES256_GCM) {
621
+ cifs_dbg(VFS, "Server does not support requested encryption type (AES256 GCM)\n");
622
+ return -EOPNOTSUPP;
623
+ }
624
+ } else if (ctxt->Ciphers[0] == 0) {
625
+ /*
626
+ * e.g. if server only supported AES256_CCM (very unlikely)
627
+ * or server supported no encryption types or had all disabled.
628
+ * Since GLOBAL_CAP_ENCRYPTION will be not set, in the case
629
+ * in which mount requested encryption ("seal") checks later
630
+ * on during tree connection will return proper rc, but if
631
+ * seal not requested by client, since server is allowed to
632
+ * return 0 to indicate no supported cipher, we can't fail here
633
+ */
634
+ server->cipher_type = 0;
635
+ server->capabilities &= ~SMB2_GLOBAL_CAP_ENCRYPTION;
636
+ pr_warn_once("Server does not support requested encryption types\n");
637
+ return 0;
638
+ } else if ((ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES128_CCM) &&
639
+ (ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES128_GCM) &&
640
+ (ctxt->Ciphers[0] != SMB2_ENCRYPTION_AES256_GCM)) {
641
+ /* server returned a cipher we didn't ask for */
642
+ pr_warn_once("Invalid SMB3.11 cipher returned\n");
493643 return -EINVAL;
494644 }
495645 server->cipher_type = ctxt->Ciphers[0];
....@@ -509,7 +659,7 @@
509659
510660 cifs_dbg(FYI, "decoding %d negotiate contexts\n", ctxt_cnt);
511661 if (len_of_smb <= offset) {
512
- cifs_dbg(VFS, "Invalid response: negotiate context offset\n");
662
+ cifs_server_dbg(VFS, "Invalid response: negotiate context offset\n");
513663 return -EINVAL;
514664 }
515665
....@@ -535,10 +685,13 @@
535685 else if (pctx->ContextType == SMB2_ENCRYPTION_CAPABILITIES)
536686 rc = decode_encrypt_ctx(server,
537687 (struct smb2_encryption_neg_context *)pctx);
688
+ else if (pctx->ContextType == SMB2_COMPRESSION_CAPABILITIES)
689
+ decode_compress_ctx(server,
690
+ (struct smb2_compression_capabilities_context *)pctx);
538691 else if (pctx->ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE)
539692 server->posix_ext_supported = true;
540693 else
541
- cifs_dbg(VFS, "unknown negcontext of type %d ignored\n",
694
+ cifs_server_dbg(VFS, "unknown negcontext of type %d ignored\n",
542695 le16_to_cpu(pctx->ContextType));
543696
544697 if (rc)
....@@ -586,7 +739,7 @@
586739 buf->Name[14] = 0xCD;
587740 buf->Name[15] = 0x7C;
588741 buf->Mode = cpu_to_le32(mode);
589
- cifs_dbg(FYI, "mode on posix create 0%o", mode);
742
+ cifs_dbg(FYI, "mode on posix create 0%o\n", mode);
590743 return buf;
591744 }
592745
....@@ -597,6 +750,8 @@
597750 unsigned int num = *num_iovec;
598751
599752 iov[num].iov_base = create_posix_buf(mode);
753
+ if (mode == ACL_NO_MODE)
754
+ cifs_dbg(FYI, "Invalid mode\n");
600755 if (iov[num].iov_base == NULL)
601756 return -ENOMEM;
602757 iov[num].iov_len = sizeof(struct create_posix);
....@@ -635,7 +790,7 @@
635790 struct kvec rsp_iov;
636791 int rc = 0;
637792 int resp_buftype;
638
- struct TCP_Server_Info *server = ses->server;
793
+ struct TCP_Server_Info *server = cifs_ses_server(ses);
639794 int blob_offset, blob_length;
640795 char *security_blob;
641796 int flags = CIFS_NEG_OP;
....@@ -648,7 +803,8 @@
648803 return -EIO;
649804 }
650805
651
- rc = smb2_plain_req_init(SMB2_NEGOTIATE, NULL, (void **) &req, &total_len);
806
+ rc = smb2_plain_req_init(SMB2_NEGOTIATE, NULL, server,
807
+ (void **) &req, &total_len);
652808 if (rc)
653809 return rc;
654810
....@@ -657,22 +813,23 @@
657813 memset(server->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE);
658814 memset(ses->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE);
659815
660
- if (strcmp(ses->server->vals->version_string,
816
+ if (strcmp(server->vals->version_string,
661817 SMB3ANY_VERSION_STRING) == 0) {
662818 req->Dialects[0] = cpu_to_le16(SMB30_PROT_ID);
663819 req->Dialects[1] = cpu_to_le16(SMB302_PROT_ID);
664820 req->DialectCount = cpu_to_le16(2);
665821 total_len += 4;
666
- } else if (strcmp(ses->server->vals->version_string,
822
+ } else if (strcmp(server->vals->version_string,
667823 SMBDEFAULT_VERSION_STRING) == 0) {
668824 req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
669825 req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
670826 req->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
671
- req->DialectCount = cpu_to_le16(3);
672
- total_len += 6;
827
+ req->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
828
+ req->DialectCount = cpu_to_le16(4);
829
+ total_len += 8;
673830 } else {
674831 /* otherwise send specific dialect */
675
- req->Dialects[0] = cpu_to_le16(ses->server->vals->protocol_id);
832
+ req->Dialects[0] = cpu_to_le16(server->vals->protocol_id);
676833 req->DialectCount = cpu_to_le16(1);
677834 total_len += 2;
678835 }
....@@ -685,16 +842,20 @@
685842 else
686843 req->SecurityMode = 0;
687844
688
- req->Capabilities = cpu_to_le32(ses->server->vals->req_capabilities);
845
+ req->Capabilities = cpu_to_le32(server->vals->req_capabilities);
846
+ if (ses->chan_max > 1)
847
+ req->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL);
689848
690849 /* ClientGUID must be zero for SMB2.02 dialect */
691
- if (ses->server->vals->protocol_id == SMB20_PROT_ID)
850
+ if (server->vals->protocol_id == SMB20_PROT_ID)
692851 memset(req->ClientGUID, 0, SMB2_CLIENT_GUID_SIZE);
693852 else {
694853 memcpy(req->ClientGUID, server->client_guid,
695854 SMB2_CLIENT_GUID_SIZE);
696
- if (ses->server->vals->protocol_id == SMB311_PROT_ID)
697
- assemble_neg_contexts(req, &total_len);
855
+ if ((server->vals->protocol_id == SMB311_PROT_ID) ||
856
+ (strcmp(server->vals->version_string,
857
+ SMBDEFAULT_VERSION_STRING) == 0))
858
+ assemble_neg_contexts(req, server, &total_len);
698859 }
699860 iov[0].iov_base = (char *)req;
700861 iov[0].iov_len = total_len;
....@@ -703,7 +864,8 @@
703864 rqst.rq_iov = iov;
704865 rqst.rq_nvec = 1;
705866
706
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
867
+ rc = cifs_send_recv(xid, ses, server,
868
+ &rqst, &resp_buftype, flags, &rsp_iov);
707869 cifs_small_buf_release(req);
708870 rsp = (struct smb2_negotiate_rsp *)rsp_iov.iov_base;
709871 /*
....@@ -711,40 +873,41 @@
711873 * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]);
712874 */
713875 if (rc == -EOPNOTSUPP) {
714
- cifs_dbg(VFS, "Dialect not supported by server. Consider "
715
- "specifying vers=1.0 or vers=2.0 on mount for accessing"
716
- " older servers\n");
876
+ cifs_server_dbg(VFS, "Dialect not supported by server. Consider specifying vers=1.0 or vers=2.0 on mount for accessing older servers\n");
717877 goto neg_exit;
718878 } else if (rc != 0)
719879 goto neg_exit;
720880
721
- if (strcmp(ses->server->vals->version_string,
881
+ if (strcmp(server->vals->version_string,
722882 SMB3ANY_VERSION_STRING) == 0) {
723883 if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
724
- cifs_dbg(VFS,
884
+ cifs_server_dbg(VFS,
725885 "SMB2 dialect returned but not requested\n");
726886 return -EIO;
727887 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
728
- cifs_dbg(VFS,
888
+ cifs_server_dbg(VFS,
729889 "SMB2.1 dialect returned but not requested\n");
730890 return -EIO;
731891 }
732
- } else if (strcmp(ses->server->vals->version_string,
892
+ } else if (strcmp(server->vals->version_string,
733893 SMBDEFAULT_VERSION_STRING) == 0) {
734894 if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) {
735
- cifs_dbg(VFS,
895
+ cifs_server_dbg(VFS,
736896 "SMB2 dialect returned but not requested\n");
737897 return -EIO;
738898 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) {
739899 /* ops set to 3.0 by default for default so update */
740
- ses->server->ops = &smb21_operations;
741
- ses->server->vals = &smb21_values;
900
+ server->ops = &smb21_operations;
901
+ server->vals = &smb21_values;
902
+ } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) {
903
+ server->ops = &smb311_operations;
904
+ server->vals = &smb311_values;
742905 }
743906 } else if (le16_to_cpu(rsp->DialectRevision) !=
744
- ses->server->vals->protocol_id) {
907
+ server->vals->protocol_id) {
745908 /* if requested single dialect ensure returned dialect matched */
746
- cifs_dbg(VFS, "Illegal 0x%x dialect returned: not requested\n",
747
- le16_to_cpu(rsp->DialectRevision));
909
+ cifs_server_dbg(VFS, "Invalid 0x%x dialect returned: not requested\n",
910
+ le16_to_cpu(rsp->DialectRevision));
748911 return -EIO;
749912 }
750913
....@@ -761,8 +924,8 @@
761924 else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID))
762925 cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n");
763926 else {
764
- cifs_dbg(VFS, "Illegal dialect returned by server 0x%x\n",
765
- le16_to_cpu(rsp->DialectRevision));
927
+ cifs_server_dbg(VFS, "Invalid dialect returned by server 0x%x\n",
928
+ le16_to_cpu(rsp->DialectRevision));
766929 rc = -EIO;
767930 goto neg_exit;
768931 }
....@@ -828,7 +991,7 @@
828991 rc = smb311_decode_neg_context(rsp, server,
829992 rsp_iov.iov_len);
830993 else
831
- cifs_dbg(VFS, "Missing expected negotiate contexts\n");
994
+ cifs_server_dbg(VFS, "Missing expected negotiate contexts\n");
832995 }
833996 neg_exit:
834997 free_rsp_buf(resp_buftype, rsp);
....@@ -842,11 +1005,12 @@
8421005 struct validate_negotiate_info_rsp *pneg_rsp = NULL;
8431006 u32 rsplen;
8441007 u32 inbuflen; /* max of 4 dialects */
1008
+ struct TCP_Server_Info *server = tcon->ses->server;
8451009
8461010 cifs_dbg(FYI, "validate negotiate\n");
8471011
8481012 /* In SMB3.11 preauth integrity supersedes validate negotiate */
849
- if (tcon->ses->server->dialect == SMB311_PROT_ID)
1013
+ if (server->dialect == SMB311_PROT_ID)
8501014 return 0;
8511015
8521016 /*
....@@ -865,15 +1029,18 @@
8651029 }
8661030
8671031 if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL)
868
- cifs_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n");
1032
+ cifs_tcon_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n");
8691033
8701034 pneg_inbuf = kmalloc(sizeof(*pneg_inbuf), GFP_NOFS);
8711035 if (!pneg_inbuf)
8721036 return -ENOMEM;
8731037
8741038 pneg_inbuf->Capabilities =
875
- cpu_to_le32(tcon->ses->server->vals->req_capabilities);
876
- memcpy(pneg_inbuf->Guid, tcon->ses->server->client_guid,
1039
+ cpu_to_le32(server->vals->req_capabilities);
1040
+ if (tcon->ses->chan_max > 1)
1041
+ pneg_inbuf->Capabilities |= cpu_to_le32(SMB2_GLOBAL_CAP_MULTI_CHANNEL);
1042
+
1043
+ memcpy(pneg_inbuf->Guid, server->client_guid,
8771044 SMB2_CLIENT_GUID_SIZE);
8781045
8791046 if (tcon->ses->sign)
....@@ -886,53 +1053,56 @@
8861053 pneg_inbuf->SecurityMode = 0;
8871054
8881055
889
- if (strcmp(tcon->ses->server->vals->version_string,
1056
+ if (strcmp(server->vals->version_string,
8901057 SMB3ANY_VERSION_STRING) == 0) {
8911058 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB30_PROT_ID);
8921059 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB302_PROT_ID);
8931060 pneg_inbuf->DialectCount = cpu_to_le16(2);
8941061 /* structure is big enough for 3 dialects, sending only 2 */
8951062 inbuflen = sizeof(*pneg_inbuf) -
896
- sizeof(pneg_inbuf->Dialects[0]);
897
- } else if (strcmp(tcon->ses->server->vals->version_string,
1063
+ (2 * sizeof(pneg_inbuf->Dialects[0]));
1064
+ } else if (strcmp(server->vals->version_string,
8981065 SMBDEFAULT_VERSION_STRING) == 0) {
8991066 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID);
9001067 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID);
9011068 pneg_inbuf->Dialects[2] = cpu_to_le16(SMB302_PROT_ID);
902
- pneg_inbuf->DialectCount = cpu_to_le16(3);
1069
+ pneg_inbuf->Dialects[3] = cpu_to_le16(SMB311_PROT_ID);
1070
+ pneg_inbuf->DialectCount = cpu_to_le16(4);
9031071 /* structure is big enough for 3 dialects */
9041072 inbuflen = sizeof(*pneg_inbuf);
9051073 } else {
9061074 /* otherwise specific dialect was requested */
9071075 pneg_inbuf->Dialects[0] =
908
- cpu_to_le16(tcon->ses->server->vals->protocol_id);
1076
+ cpu_to_le16(server->vals->protocol_id);
9091077 pneg_inbuf->DialectCount = cpu_to_le16(1);
910
- /* structure is big enough for 3 dialects, sending only 1 */
1078
+ /* structure is big enough for 4 dialects, sending only 1 */
9111079 inbuflen = sizeof(*pneg_inbuf) -
912
- sizeof(pneg_inbuf->Dialects[0]) * 2;
1080
+ sizeof(pneg_inbuf->Dialects[0]) * 3;
9131081 }
9141082
9151083 rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
916
- FSCTL_VALIDATE_NEGOTIATE_INFO, true /* is_fsctl */,
917
- (char *)pneg_inbuf, inbuflen, (char **)&pneg_rsp, &rsplen);
1084
+ FSCTL_VALIDATE_NEGOTIATE_INFO,
1085
+ (char *)pneg_inbuf, inbuflen, CIFSMaxBufSize,
1086
+ (char **)&pneg_rsp, &rsplen);
9181087 if (rc == -EOPNOTSUPP) {
9191088 /*
9201089 * Old Windows versions or Netapp SMB server can return
9211090 * not supported error. Client should accept it.
9221091 */
923
- cifs_dbg(VFS, "Server does not support validate negotiate\n");
1092
+ cifs_tcon_dbg(VFS, "Server does not support validate negotiate\n");
9241093 rc = 0;
9251094 goto out_free_inbuf;
9261095 } else if (rc != 0) {
927
- cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc);
1096
+ cifs_tcon_dbg(VFS, "validate protocol negotiate failed: %d\n",
1097
+ rc);
9281098 rc = -EIO;
9291099 goto out_free_inbuf;
9301100 }
9311101
9321102 rc = -EIO;
9331103 if (rsplen != sizeof(*pneg_rsp)) {
934
- cifs_dbg(VFS, "invalid protocol negotiate response size: %d\n",
935
- rsplen);
1104
+ cifs_tcon_dbg(VFS, "Invalid protocol negotiate response size: %d\n",
1105
+ rsplen);
9361106
9371107 /* relax check since Mac returns max bufsize allowed on ioctl */
9381108 if (rsplen > CIFSMaxBufSize || rsplen < sizeof(*pneg_rsp))
....@@ -940,16 +1110,16 @@
9401110 }
9411111
9421112 /* check validate negotiate info response matches what we got earlier */
943
- if (pneg_rsp->Dialect != cpu_to_le16(tcon->ses->server->dialect))
1113
+ if (pneg_rsp->Dialect != cpu_to_le16(server->dialect))
9441114 goto vneg_out;
9451115
946
- if (pneg_rsp->SecurityMode != cpu_to_le16(tcon->ses->server->sec_mode))
1116
+ if (pneg_rsp->SecurityMode != cpu_to_le16(server->sec_mode))
9471117 goto vneg_out;
9481118
9491119 /* do not validate server guid because not saved at negprot time yet */
9501120
9511121 if ((le32_to_cpu(pneg_rsp->Capabilities) | SMB2_NT_FIND |
952
- SMB2_LARGE_FILES) != tcon->ses->server->capabilities)
1122
+ SMB2_LARGE_FILES) != server->capabilities)
9531123 goto vneg_out;
9541124
9551125 /* validate negotiate successful */
....@@ -958,7 +1128,7 @@
9581128 goto out_free_rsp;
9591129
9601130 vneg_out:
961
- cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n");
1131
+ cifs_tcon_dbg(VFS, "protocol revalidation - security settings mismatch\n");
9621132 out_free_rsp:
9631133 kfree(pneg_rsp);
9641134 out_free_inbuf:
....@@ -982,7 +1152,7 @@
9821152 if ((server->sec_kerberos || server->sec_mskerberos) &&
9831153 (global_secflags & CIFSSEC_MAY_KRB5))
9841154 return Kerberos;
985
- /* Fallthrough */
1155
+ fallthrough;
9861156 default:
9871157 return Unspecified;
9881158 }
....@@ -1013,21 +1183,30 @@
10131183 int rc;
10141184 struct cifs_ses *ses = sess_data->ses;
10151185 struct smb2_sess_setup_req *req;
1016
- struct TCP_Server_Info *server = ses->server;
1186
+ struct TCP_Server_Info *server = cifs_ses_server(ses);
10171187 unsigned int total_len;
10181188
1019
- rc = smb2_plain_req_init(SMB2_SESSION_SETUP, NULL, (void **) &req,
1020
- &total_len);
1189
+ rc = smb2_plain_req_init(SMB2_SESSION_SETUP, NULL, server,
1190
+ (void **) &req,
1191
+ &total_len);
10211192 if (rc)
10221193 return rc;
10231194
1024
- /* First session, not a reauthenticate */
1025
- req->sync_hdr.SessionId = 0;
1026
-
1027
- /* if reconnect, we need to send previous sess id, otherwise it is 0 */
1028
- req->PreviousSessionId = sess_data->previous_session;
1029
-
1030
- req->Flags = 0; /* MBZ */
1195
+ if (sess_data->ses->binding) {
1196
+ req->sync_hdr.SessionId = sess_data->ses->Suid;
1197
+ req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
1198
+ req->PreviousSessionId = 0;
1199
+ req->Flags = SMB2_SESSION_REQ_FLAG_BINDING;
1200
+ } else {
1201
+ /* First session, not a reauthenticate */
1202
+ req->sync_hdr.SessionId = 0;
1203
+ /*
1204
+ * if reconnect, we need to send previous sess id
1205
+ * otherwise it is 0
1206
+ */
1207
+ req->PreviousSessionId = sess_data->previous_session;
1208
+ req->Flags = 0; /* MBZ */
1209
+ }
10311210
10321211 /* enough to enable echos and oplocks and one max size write */
10331212 req->sync_hdr.CreditRequest = cpu_to_le16(130);
....@@ -1086,6 +1265,7 @@
10861265
10871266 /* BB add code to build os and lm fields */
10881267 rc = cifs_send_recv(sess_data->xid, sess_data->ses,
1268
+ cifs_ses_server(sess_data->ses),
10891269 &rqst,
10901270 &sess_data->buf0_type,
10911271 CIFS_LOG_ERROR | CIFS_NEG_OP, &rsp_iov);
....@@ -1100,28 +1280,33 @@
11001280 {
11011281 int rc = 0;
11021282 struct cifs_ses *ses = sess_data->ses;
1283
+ struct TCP_Server_Info *server = cifs_ses_server(ses);
11031284
1104
- mutex_lock(&ses->server->srv_mutex);
1105
- if (ses->server->ops->generate_signingkey) {
1106
- rc = ses->server->ops->generate_signingkey(ses);
1285
+ mutex_lock(&server->srv_mutex);
1286
+ if (server->ops->generate_signingkey) {
1287
+ rc = server->ops->generate_signingkey(ses);
11071288 if (rc) {
11081289 cifs_dbg(FYI,
11091290 "SMB3 session key generation failed\n");
1110
- mutex_unlock(&ses->server->srv_mutex);
1291
+ mutex_unlock(&server->srv_mutex);
11111292 return rc;
11121293 }
11131294 }
1114
- if (!ses->server->session_estab) {
1115
- ses->server->sequence_number = 0x2;
1116
- ses->server->session_estab = true;
1295
+ if (!server->session_estab) {
1296
+ server->sequence_number = 0x2;
1297
+ server->session_estab = true;
11171298 }
1118
- mutex_unlock(&ses->server->srv_mutex);
1299
+ mutex_unlock(&server->srv_mutex);
11191300
11201301 cifs_dbg(FYI, "SMB2/3 session established successfully\n");
1121
- spin_lock(&GlobalMid_Lock);
1122
- ses->status = CifsGood;
1123
- ses->need_reconnect = false;
1124
- spin_unlock(&GlobalMid_Lock);
1302
+ /* keep existing ses state if binding */
1303
+ if (!ses->binding) {
1304
+ spin_lock(&GlobalMid_Lock);
1305
+ ses->status = CifsGood;
1306
+ ses->need_reconnect = false;
1307
+ spin_unlock(&GlobalMid_Lock);
1308
+ }
1309
+
11251310 return rc;
11261311 }
11271312
....@@ -1154,23 +1339,24 @@
11541339 * sending us a response in an expected form
11551340 */
11561341 if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
1157
- cifs_dbg(VFS,
1158
- "bad cifs.upcall version. Expected %d got %d",
1159
- CIFS_SPNEGO_UPCALL_VERSION, msg->version);
1342
+ cifs_dbg(VFS, "bad cifs.upcall version. Expected %d got %d\n",
1343
+ CIFS_SPNEGO_UPCALL_VERSION, msg->version);
11601344 rc = -EKEYREJECTED;
11611345 goto out_put_spnego_key;
11621346 }
11631347
1164
- ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
1165
- GFP_KERNEL);
1166
- if (!ses->auth_key.response) {
1167
- cifs_dbg(VFS,
1168
- "Kerberos can't allocate (%u bytes) memory",
1169
- msg->sesskey_len);
1170
- rc = -ENOMEM;
1171
- goto out_put_spnego_key;
1348
+ /* keep session key if binding */
1349
+ if (!ses->binding) {
1350
+ ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
1351
+ GFP_KERNEL);
1352
+ if (!ses->auth_key.response) {
1353
+ cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n",
1354
+ msg->sesskey_len);
1355
+ rc = -ENOMEM;
1356
+ goto out_put_spnego_key;
1357
+ }
1358
+ ses->auth_key.len = msg->sesskey_len;
11721359 }
1173
- ses->auth_key.len = msg->sesskey_len;
11741360
11751361 sess_data->iov[1].iov_base = msg->data + msg->sesskey_len;
11761362 sess_data->iov[1].iov_len = msg->secblob_len;
....@@ -1180,9 +1366,11 @@
11801366 goto out_put_spnego_key;
11811367
11821368 rsp = (struct smb2_sess_setup_rsp *)sess_data->iov[0].iov_base;
1183
- ses->Suid = rsp->sync_hdr.SessionId;
1184
-
1185
- ses->session_flags = le16_to_cpu(rsp->SessionFlags);
1369
+ /* keep session id and flags if binding */
1370
+ if (!ses->binding) {
1371
+ ses->Suid = rsp->sync_hdr.SessionId;
1372
+ ses->session_flags = le16_to_cpu(rsp->SessionFlags);
1373
+ }
11861374
11871375 rc = SMB2_sess_establish_session(sess_data);
11881376 out_put_spnego_key:
....@@ -1276,9 +1464,11 @@
12761464
12771465 cifs_dbg(FYI, "rawntlmssp session setup challenge phase\n");
12781466
1279
-
1280
- ses->Suid = rsp->sync_hdr.SessionId;
1281
- ses->session_flags = le16_to_cpu(rsp->SessionFlags);
1467
+ /* keep existing ses id and flags if binding */
1468
+ if (!ses->binding) {
1469
+ ses->Suid = rsp->sync_hdr.SessionId;
1470
+ ses->session_flags = le16_to_cpu(rsp->SessionFlags);
1471
+ }
12821472
12831473 out:
12841474 kfree(ntlmssp_blob);
....@@ -1335,10 +1525,28 @@
13351525
13361526 rsp = (struct smb2_sess_setup_rsp *)sess_data->iov[0].iov_base;
13371527
1338
- ses->Suid = rsp->sync_hdr.SessionId;
1339
- ses->session_flags = le16_to_cpu(rsp->SessionFlags);
1528
+ /* keep existing ses id and flags if binding */
1529
+ if (!ses->binding) {
1530
+ ses->Suid = rsp->sync_hdr.SessionId;
1531
+ ses->session_flags = le16_to_cpu(rsp->SessionFlags);
1532
+ }
13401533
13411534 rc = SMB2_sess_establish_session(sess_data);
1535
+#ifdef CONFIG_CIFS_DEBUG_DUMP_KEYS
1536
+ if (ses->server->dialect < SMB30_PROT_ID) {
1537
+ cifs_dbg(VFS, "%s: dumping generated SMB2 session keys\n", __func__);
1538
+ /*
1539
+ * The session id is opaque in terms of endianness, so we can't
1540
+ * print it as a long long. we dump it as we got it on the wire
1541
+ */
1542
+ cifs_dbg(VFS, "Session Id %*ph\n", (int)sizeof(ses->Suid),
1543
+ &ses->Suid);
1544
+ cifs_dbg(VFS, "Session Key %*ph\n",
1545
+ SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
1546
+ cifs_dbg(VFS, "Signing Key %*ph\n",
1547
+ SMB3_SIGN_KEY_SIZE, ses->auth_key.response);
1548
+ }
1549
+#endif
13421550 out:
13431551 kfree(ntlmssp_blob);
13441552 SMB2_sess_free_buffer(sess_data);
....@@ -1353,11 +1561,10 @@
13531561 {
13541562 int type;
13551563
1356
- type = smb2_select_sectype(ses->server, ses->sectype);
1564
+ type = smb2_select_sectype(cifs_ses_server(ses), ses->sectype);
13571565 cifs_dbg(FYI, "sess setup type %d\n", type);
13581566 if (type == Unspecified) {
1359
- cifs_dbg(VFS,
1360
- "Unable to select appropriate authentication method!");
1567
+ cifs_dbg(VFS, "Unable to select appropriate authentication method!\n");
13611568 return -EINVAL;
13621569 }
13631570
....@@ -1381,7 +1588,7 @@
13811588 const struct nls_table *nls_cp)
13821589 {
13831590 int rc = 0;
1384
- struct TCP_Server_Info *server = ses->server;
1591
+ struct TCP_Server_Info *server = cifs_ses_server(ses);
13851592 struct SMB2_sess_data *sess_data;
13861593
13871594 cifs_dbg(FYI, "Session Setup\n");
....@@ -1407,14 +1614,14 @@
14071614 /*
14081615 * Initialize the session hash with the server one.
14091616 */
1410
- memcpy(ses->preauth_sha_hash, ses->server->preauth_sha_hash,
1617
+ memcpy(ses->preauth_sha_hash, server->preauth_sha_hash,
14111618 SMB2_PREAUTH_HASH_SIZE);
14121619
14131620 while (sess_data->func)
14141621 sess_data->func(sess_data);
14151622
14161623 if ((ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST) && (ses->sign))
1417
- cifs_dbg(VFS, "signing requested but authenticated as guest\n");
1624
+ cifs_server_dbg(VFS, "signing requested but authenticated as guest\n");
14181625 rc = sess_data->result;
14191626 out:
14201627 kfree(sess_data);
....@@ -1445,7 +1652,8 @@
14451652 if (ses->need_reconnect)
14461653 goto smb2_session_already_dead;
14471654
1448
- rc = smb2_plain_req_init(SMB2_LOGOFF, NULL, (void **) &req, &total_len);
1655
+ rc = smb2_plain_req_init(SMB2_LOGOFF, NULL, ses->server,
1656
+ (void **) &req, &total_len);
14491657 if (rc)
14501658 return rc;
14511659
....@@ -1457,7 +1665,7 @@
14571665 else if (server->sign)
14581666 req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
14591667
1460
- flags |= CIFS_NO_RESP;
1668
+ flags |= CIFS_NO_RSP_BUF;
14611669
14621670 iov[0].iov_base = (char *)req;
14631671 iov[0].iov_len = total_len;
....@@ -1466,7 +1674,8 @@
14661674 rqst.rq_iov = iov;
14671675 rqst.rq_nvec = 1;
14681676
1469
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
1677
+ rc = cifs_send_recv(xid, ses, ses->server,
1678
+ &rqst, &resp_buf_type, flags, &rsp_iov);
14701679 cifs_small_buf_release(req);
14711680 /*
14721681 * No tcon so can't do
....@@ -1507,10 +1716,14 @@
15071716 __le16 *unc_path = NULL;
15081717 int flags = 0;
15091718 unsigned int total_len;
1719
+ struct TCP_Server_Info *server;
1720
+
1721
+ /* always use master channel */
1722
+ server = ses->server;
15101723
15111724 cifs_dbg(FYI, "TCON\n");
15121725
1513
- if (!(ses->server) || !tree)
1726
+ if (!server || !tree)
15141727 return -EIO;
15151728
15161729 unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL);
....@@ -1526,9 +1739,9 @@
15261739
15271740 /* SMB2 TREE_CONNECT request must be called with TreeId == 0 */
15281741 tcon->tid = 0;
1529
-
1530
- rc = smb2_plain_req_init(SMB2_TREE_CONNECT, tcon, (void **) &req,
1531
- &total_len);
1742
+ atomic_set(&tcon->num_remote_opens, 0);
1743
+ rc = smb2_plain_req_init(SMB2_TREE_CONNECT, tcon, server,
1744
+ (void **) &req, &total_len);
15321745 if (rc) {
15331746 kfree(unc_path);
15341747 return rc;
....@@ -1553,7 +1766,7 @@
15531766 * unless it is guest or anonymous user. See MS-SMB2 3.2.5.3.1
15541767 * (Samba servers don't always set the flag so also check if null user)
15551768 */
1556
- if ((ses->server->dialect == SMB311_PROT_ID) &&
1769
+ if ((server->dialect == SMB311_PROT_ID) &&
15571770 !smb3_encryption_required(tcon) &&
15581771 !(ses->session_flags &
15591772 (SMB2_SESSION_FLAG_IS_GUEST|SMB2_SESSION_FLAG_IS_NULL)) &&
....@@ -1564,10 +1777,14 @@
15641777 rqst.rq_iov = iov;
15651778 rqst.rq_nvec = 2;
15661779
1567
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
1780
+ /* Need 64 for max size write so ask for more in case not there yet */
1781
+ req->sync_hdr.CreditRequest = cpu_to_le16(64);
1782
+
1783
+ rc = cifs_send_recv(xid, ses, server,
1784
+ &rqst, &resp_buftype, flags, &rsp_iov);
15681785 cifs_small_buf_release(req);
15691786 rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base;
1570
-
1787
+ trace_smb3_tcon(xid, tcon->tid, ses->Suid, tree, rc);
15711788 if (rc != 0) {
15721789 if (tcon) {
15731790 cifs_stats_fail_inc(tcon, SMB2_TREE_CONNECT_HE);
....@@ -1589,7 +1806,7 @@
15891806 cifs_dbg(FYI, "connection to printer\n");
15901807 break;
15911808 default:
1592
- cifs_dbg(VFS, "unknown share type %d\n", rsp->ShareType);
1809
+ cifs_server_dbg(VFS, "unknown share type %d\n", rsp->ShareType);
15931810 rc = -EOPNOTSUPP;
15941811 goto tcon_error_exit;
15951812 }
....@@ -1604,23 +1821,24 @@
16041821
16051822 if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) &&
16061823 ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
1607
- cifs_dbg(VFS, "DFS capability contradicts DFS flag\n");
1824
+ cifs_tcon_dbg(VFS, "DFS capability contradicts DFS flag\n");
16081825
16091826 if (tcon->seal &&
1610
- !(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
1611
- cifs_dbg(VFS, "Encryption is requested but not supported\n");
1827
+ !(server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION))
1828
+ cifs_tcon_dbg(VFS, "Encryption is requested but not supported\n");
16121829
16131830 init_copy_chunk_defaults(tcon);
1614
- if (tcon->ses->server->ops->validate_negotiate)
1615
- rc = tcon->ses->server->ops->validate_negotiate(xid, tcon);
1831
+ if (server->ops->validate_negotiate)
1832
+ rc = server->ops->validate_negotiate(xid, tcon);
16161833 tcon_exit:
1834
+
16171835 free_rsp_buf(resp_buftype, rsp);
16181836 kfree(unc_path);
16191837 return rc;
16201838
16211839 tcon_error_exit:
16221840 if (rsp && rsp->sync_hdr.Status == STATUS_BAD_NETWORK_NAME) {
1623
- cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
1841
+ cifs_tcon_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
16241842 }
16251843 goto tcon_exit;
16261844 }
....@@ -1646,15 +1864,18 @@
16461864 if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
16471865 return 0;
16481866
1649
- rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, (void **) &req,
1650
- &total_len);
1867
+ close_shroot_lease(&tcon->crfid);
1868
+
1869
+ rc = smb2_plain_req_init(SMB2_TREE_DISCONNECT, tcon, ses->server,
1870
+ (void **) &req,
1871
+ &total_len);
16511872 if (rc)
16521873 return rc;
16531874
16541875 if (smb3_encryption_required(tcon))
16551876 flags |= CIFS_TRANSFORM_REQ;
16561877
1657
- flags |= CIFS_NO_RESP;
1878
+ flags |= CIFS_NO_RSP_BUF;
16581879
16591880 iov[0].iov_base = (char *)req;
16601881 iov[0].iov_len = total_len;
....@@ -1663,7 +1884,8 @@
16631884 rqst.rq_iov = iov;
16641885 rqst.rq_nvec = 1;
16651886
1666
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
1887
+ rc = cifs_send_recv(xid, ses, ses->server,
1888
+ &rqst, &resp_buf_type, flags, &rsp_iov);
16671889 cifs_small_buf_release(req);
16681890 if (rc)
16691891 cifs_stats_fail_inc(tcon, SMB2_TREE_DISCONNECT_HE);
....@@ -1720,25 +1942,97 @@
17201942 return buf;
17211943 }
17221944
1723
-static __u8
1724
-parse_lease_state(struct TCP_Server_Info *server, struct smb2_create_rsp *rsp,
1725
- unsigned int *epoch, char *lease_key)
1945
+static void
1946
+parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
1947
+{
1948
+ struct create_on_disk_id *pdisk_id = (struct create_on_disk_id *)cc;
1949
+
1950
+ cifs_dbg(FYI, "parse query id context 0x%llx 0x%llx\n",
1951
+ pdisk_id->DiskFileId, pdisk_id->VolumeId);
1952
+ buf->IndexNumber = pdisk_id->DiskFileId;
1953
+}
1954
+
1955
+static void
1956
+parse_posix_ctxt(struct create_context *cc, struct smb2_file_all_info *info,
1957
+ struct create_posix_rsp *posix)
1958
+{
1959
+ int sid_len;
1960
+ u8 *beg = (u8 *)cc + le16_to_cpu(cc->DataOffset);
1961
+ u8 *end = beg + le32_to_cpu(cc->DataLength);
1962
+ u8 *sid;
1963
+
1964
+ memset(posix, 0, sizeof(*posix));
1965
+
1966
+ posix->nlink = le32_to_cpu(*(__le32 *)(beg + 0));
1967
+ posix->reparse_tag = le32_to_cpu(*(__le32 *)(beg + 4));
1968
+ posix->mode = le32_to_cpu(*(__le32 *)(beg + 8));
1969
+
1970
+ sid = beg + 12;
1971
+ sid_len = posix_info_sid_size(sid, end);
1972
+ if (sid_len < 0) {
1973
+ cifs_dbg(VFS, "bad owner sid in posix create response\n");
1974
+ return;
1975
+ }
1976
+ memcpy(&posix->owner, sid, sid_len);
1977
+
1978
+ sid = sid + sid_len;
1979
+ sid_len = posix_info_sid_size(sid, end);
1980
+ if (sid_len < 0) {
1981
+ cifs_dbg(VFS, "bad group sid in posix create response\n");
1982
+ return;
1983
+ }
1984
+ memcpy(&posix->group, sid, sid_len);
1985
+
1986
+ cifs_dbg(FYI, "nlink=%d mode=%o reparse_tag=%x\n",
1987
+ posix->nlink, posix->mode, posix->reparse_tag);
1988
+}
1989
+
1990
+void
1991
+smb2_parse_contexts(struct TCP_Server_Info *server,
1992
+ struct smb2_create_rsp *rsp,
1993
+ unsigned int *epoch, char *lease_key, __u8 *oplock,
1994
+ struct smb2_file_all_info *buf,
1995
+ struct create_posix_rsp *posix)
17261996 {
17271997 char *data_offset;
17281998 struct create_context *cc;
17291999 unsigned int next;
17302000 unsigned int remaining;
17312001 char *name;
2002
+ static const char smb3_create_tag_posix[] = {
2003
+ 0x93, 0xAD, 0x25, 0x50, 0x9C,
2004
+ 0xB4, 0x11, 0xE7, 0xB4, 0x23, 0x83,
2005
+ 0xDE, 0x96, 0x8B, 0xCD, 0x7C
2006
+ };
17322007
2008
+ *oplock = 0;
17332009 data_offset = (char *)rsp + le32_to_cpu(rsp->CreateContextsOffset);
17342010 remaining = le32_to_cpu(rsp->CreateContextsLength);
17352011 cc = (struct create_context *)data_offset;
2012
+
2013
+ /* Initialize inode number to 0 in case no valid data in qfid context */
2014
+ if (buf)
2015
+ buf->IndexNumber = 0;
2016
+
17362017 while (remaining >= sizeof(struct create_context)) {
17372018 name = le16_to_cpu(cc->NameOffset) + (char *)cc;
17382019 if (le16_to_cpu(cc->NameLength) == 4 &&
1739
- strncmp(name, "RqLs", 4) == 0)
1740
- return server->ops->parse_lease_buf(cc, epoch,
1741
- lease_key);
2020
+ strncmp(name, SMB2_CREATE_REQUEST_LEASE, 4) == 0)
2021
+ *oplock = server->ops->parse_lease_buf(cc, epoch,
2022
+ lease_key);
2023
+ else if (buf && (le16_to_cpu(cc->NameLength) == 4) &&
2024
+ strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4) == 0)
2025
+ parse_query_id_ctxt(cc, buf);
2026
+ else if ((le16_to_cpu(cc->NameLength) == 16)) {
2027
+ if (posix &&
2028
+ memcmp(name, smb3_create_tag_posix, 16) == 0)
2029
+ parse_posix_ctxt(cc, buf, posix);
2030
+ }
2031
+ /* else {
2032
+ cifs_dbg(FYI, "Context not matched with len %d\n",
2033
+ le16_to_cpu(cc->NameLength));
2034
+ cifs_dump_mem("Cctxt name: ", name, 4);
2035
+ } */
17422036
17432037 next = le32_to_cpu(cc->Next);
17442038 if (!next)
....@@ -1747,7 +2041,10 @@
17472041 cc = (struct create_context *)((char *)cc + next);
17482042 }
17492043
1750
- return 0;
2044
+ if (rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
2045
+ *oplock = rsp->OplockLevel;
2046
+
2047
+ return;
17512048 }
17522049
17532050 static int
....@@ -1773,8 +2070,9 @@
17732070 }
17742071
17752072 static struct create_durable_v2 *
1776
-create_durable_v2_buf(struct cifs_fid *pfid)
2073
+create_durable_v2_buf(struct cifs_open_parms *oparms)
17772074 {
2075
+ struct cifs_fid *pfid = oparms->fid;
17782076 struct create_durable_v2 *buf;
17792077
17802078 buf = kzalloc(sizeof(struct create_durable_v2), GFP_KERNEL);
....@@ -1788,7 +2086,14 @@
17882086 (struct create_durable_v2, Name));
17892087 buf->ccontext.NameLength = cpu_to_le16(4);
17902088
1791
- buf->dcontext.Timeout = 0; /* Should this be configurable by workload */
2089
+ /*
2090
+ * NB: Handle timeout defaults to 0, which allows server to choose
2091
+ * (most servers default to 120 seconds) and most clients default to 0.
2092
+ * This can be overridden at mount ("handletimeout=") if the user wants
2093
+ * a different persistent (or resilient) handle timeout for all opens
2094
+ * opens on a particular SMB3 mount.
2095
+ */
2096
+ buf->dcontext.Timeout = cpu_to_le32(oparms->tcon->handle_timeout);
17922097 buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
17932098 generate_random_uuid(buf->dcontext.CreateGuid);
17942099 memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16);
....@@ -1841,7 +2146,7 @@
18412146 struct smb2_create_req *req = iov[0].iov_base;
18422147 unsigned int num = *num_iovec;
18432148
1844
- iov[num].iov_base = create_durable_v2_buf(oparms->fid);
2149
+ iov[num].iov_base = create_durable_v2_buf(oparms);
18452150 if (iov[num].iov_base == NULL)
18462151 return -ENOMEM;
18472152 iov[num].iov_len = sizeof(struct create_durable_v2);
....@@ -1956,6 +2261,183 @@
19562261 return 0;
19572262 }
19582263
2264
+/* See See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx */
2265
+static void setup_owner_group_sids(char *buf)
2266
+{
2267
+ struct owner_group_sids *sids = (struct owner_group_sids *)buf;
2268
+
2269
+ /* Populate the user ownership fields S-1-5-88-1 */
2270
+ sids->owner.Revision = 1;
2271
+ sids->owner.NumAuth = 3;
2272
+ sids->owner.Authority[5] = 5;
2273
+ sids->owner.SubAuthorities[0] = cpu_to_le32(88);
2274
+ sids->owner.SubAuthorities[1] = cpu_to_le32(1);
2275
+ sids->owner.SubAuthorities[2] = cpu_to_le32(current_fsuid().val);
2276
+
2277
+ /* Populate the group ownership fields S-1-5-88-2 */
2278
+ sids->group.Revision = 1;
2279
+ sids->group.NumAuth = 3;
2280
+ sids->group.Authority[5] = 5;
2281
+ sids->group.SubAuthorities[0] = cpu_to_le32(88);
2282
+ sids->group.SubAuthorities[1] = cpu_to_le32(2);
2283
+ sids->group.SubAuthorities[2] = cpu_to_le32(current_fsgid().val);
2284
+
2285
+ cifs_dbg(FYI, "owner S-1-5-88-1-%d, group S-1-5-88-2-%d\n", current_fsuid().val, current_fsgid().val);
2286
+}
2287
+
2288
+/* See MS-SMB2 2.2.13.2.2 and MS-DTYP 2.4.6 */
2289
+static struct crt_sd_ctxt *
2290
+create_sd_buf(umode_t mode, bool set_owner, unsigned int *len)
2291
+{
2292
+ struct crt_sd_ctxt *buf;
2293
+ __u8 *ptr, *aclptr;
2294
+ unsigned int acelen, acl_size, ace_count;
2295
+ unsigned int owner_offset = 0;
2296
+ unsigned int group_offset = 0;
2297
+ struct smb3_acl acl = {};
2298
+
2299
+ *len = roundup(sizeof(struct crt_sd_ctxt) + (sizeof(struct cifs_ace) * 4), 8);
2300
+
2301
+ if (set_owner) {
2302
+ /* sizeof(struct owner_group_sids) is already multiple of 8 so no need to round */
2303
+ *len += sizeof(struct owner_group_sids);
2304
+ }
2305
+
2306
+ buf = kzalloc(*len, GFP_KERNEL);
2307
+ if (buf == NULL)
2308
+ return buf;
2309
+
2310
+ ptr = (__u8 *)&buf[1];
2311
+ if (set_owner) {
2312
+ /* offset fields are from beginning of security descriptor not of create context */
2313
+ owner_offset = ptr - (__u8 *)&buf->sd;
2314
+ buf->sd.OffsetOwner = cpu_to_le32(owner_offset);
2315
+ group_offset = owner_offset + offsetof(struct owner_group_sids, group);
2316
+ buf->sd.OffsetGroup = cpu_to_le32(group_offset);
2317
+
2318
+ setup_owner_group_sids(ptr);
2319
+ ptr += sizeof(struct owner_group_sids);
2320
+ } else {
2321
+ buf->sd.OffsetOwner = 0;
2322
+ buf->sd.OffsetGroup = 0;
2323
+ }
2324
+
2325
+ buf->ccontext.DataOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, sd));
2326
+ buf->ccontext.NameOffset = cpu_to_le16(offsetof(struct crt_sd_ctxt, Name));
2327
+ buf->ccontext.NameLength = cpu_to_le16(4);
2328
+ /* SMB2_CREATE_SD_BUFFER_TOKEN is "SecD" */
2329
+ buf->Name[0] = 'S';
2330
+ buf->Name[1] = 'e';
2331
+ buf->Name[2] = 'c';
2332
+ buf->Name[3] = 'D';
2333
+ buf->sd.Revision = 1; /* Must be one see MS-DTYP 2.4.6 */
2334
+
2335
+ /*
2336
+ * ACL is "self relative" ie ACL is stored in contiguous block of memory
2337
+ * and "DP" ie the DACL is present
2338
+ */
2339
+ buf->sd.Control = cpu_to_le16(ACL_CONTROL_SR | ACL_CONTROL_DP);
2340
+
2341
+ /* offset owner, group and Sbz1 and SACL are all zero */
2342
+ buf->sd.OffsetDacl = cpu_to_le32(ptr - (__u8 *)&buf->sd);
2343
+ /* Ship the ACL for now. we will copy it into buf later. */
2344
+ aclptr = ptr;
2345
+ ptr += sizeof(struct smb3_acl);
2346
+
2347
+ /* create one ACE to hold the mode embedded in reserved special SID */
2348
+ acelen = setup_special_mode_ACE((struct cifs_ace *)ptr, (__u64)mode);
2349
+ ptr += acelen;
2350
+ acl_size = acelen + sizeof(struct smb3_acl);
2351
+ ace_count = 1;
2352
+
2353
+ if (set_owner) {
2354
+ /* we do not need to reallocate buffer to add the two more ACEs. plenty of space */
2355
+ acelen = setup_special_user_owner_ACE((struct cifs_ace *)ptr);
2356
+ ptr += acelen;
2357
+ acl_size += acelen;
2358
+ ace_count += 1;
2359
+ }
2360
+
2361
+ /* and one more ACE to allow access for authenticated users */
2362
+ acelen = setup_authusers_ACE((struct cifs_ace *)ptr);
2363
+ ptr += acelen;
2364
+ acl_size += acelen;
2365
+ ace_count += 1;
2366
+
2367
+ acl.AclRevision = ACL_REVISION; /* See 2.4.4.1 of MS-DTYP */
2368
+ acl.AclSize = cpu_to_le16(acl_size);
2369
+ acl.AceCount = cpu_to_le16(ace_count);
2370
+ /* acl.Sbz1 and Sbz2 MBZ so are not set here, but initialized above */
2371
+ memcpy(aclptr, &acl, sizeof(struct smb3_acl));
2372
+
2373
+ buf->ccontext.DataLength = cpu_to_le32(ptr - (__u8 *)&buf->sd);
2374
+ *len = roundup(ptr - (__u8 *)buf, 8);
2375
+
2376
+ return buf;
2377
+}
2378
+
2379
+static int
2380
+add_sd_context(struct kvec *iov, unsigned int *num_iovec, umode_t mode, bool set_owner)
2381
+{
2382
+ struct smb2_create_req *req = iov[0].iov_base;
2383
+ unsigned int num = *num_iovec;
2384
+ unsigned int len = 0;
2385
+
2386
+ iov[num].iov_base = create_sd_buf(mode, set_owner, &len);
2387
+ if (iov[num].iov_base == NULL)
2388
+ return -ENOMEM;
2389
+ iov[num].iov_len = len;
2390
+ if (!req->CreateContextsOffset)
2391
+ req->CreateContextsOffset = cpu_to_le32(
2392
+ sizeof(struct smb2_create_req) +
2393
+ iov[num - 1].iov_len);
2394
+ le32_add_cpu(&req->CreateContextsLength, len);
2395
+ *num_iovec = num + 1;
2396
+ return 0;
2397
+}
2398
+
2399
+static struct crt_query_id_ctxt *
2400
+create_query_id_buf(void)
2401
+{
2402
+ struct crt_query_id_ctxt *buf;
2403
+
2404
+ buf = kzalloc(sizeof(struct crt_query_id_ctxt), GFP_KERNEL);
2405
+ if (!buf)
2406
+ return NULL;
2407
+
2408
+ buf->ccontext.DataOffset = cpu_to_le16(0);
2409
+ buf->ccontext.DataLength = cpu_to_le32(0);
2410
+ buf->ccontext.NameOffset = cpu_to_le16(offsetof
2411
+ (struct crt_query_id_ctxt, Name));
2412
+ buf->ccontext.NameLength = cpu_to_le16(4);
2413
+ /* SMB2_CREATE_QUERY_ON_DISK_ID is "QFid" */
2414
+ buf->Name[0] = 'Q';
2415
+ buf->Name[1] = 'F';
2416
+ buf->Name[2] = 'i';
2417
+ buf->Name[3] = 'd';
2418
+ return buf;
2419
+}
2420
+
2421
+/* See MS-SMB2 2.2.13.2.9 */
2422
+static int
2423
+add_query_id_context(struct kvec *iov, unsigned int *num_iovec)
2424
+{
2425
+ struct smb2_create_req *req = iov[0].iov_base;
2426
+ unsigned int num = *num_iovec;
2427
+
2428
+ iov[num].iov_base = create_query_id_buf();
2429
+ if (iov[num].iov_base == NULL)
2430
+ return -ENOMEM;
2431
+ iov[num].iov_len = sizeof(struct crt_query_id_ctxt);
2432
+ if (!req->CreateContextsOffset)
2433
+ req->CreateContextsOffset = cpu_to_le32(
2434
+ sizeof(struct smb2_create_req) +
2435
+ iov[num - 1].iov_len);
2436
+ le32_add_cpu(&req->CreateContextsLength, sizeof(struct crt_query_id_ctxt));
2437
+ *num_iovec = num + 1;
2438
+ return 0;
2439
+}
2440
+
19592441 static int
19602442 alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len,
19612443 const char *treename, const __le16 *path)
....@@ -2009,7 +2491,6 @@
20092491 struct smb_rqst rqst;
20102492 struct smb2_create_req *req;
20112493 struct smb2_create_rsp *rsp = NULL;
2012
- struct TCP_Server_Info *server;
20132494 struct cifs_ses *ses = tcon->ses;
20142495 struct kvec iov[3]; /* make sure at least one for each open context */
20152496 struct kvec rsp_iov = {NULL, 0};
....@@ -2024,6 +2505,7 @@
20242505 int flags = 0;
20252506 unsigned int total_len;
20262507 __le16 *utf16_path = NULL;
2508
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
20272509
20282510 cifs_dbg(FYI, "mkdir\n");
20292511
....@@ -2032,15 +2514,14 @@
20322514 if (!utf16_path)
20332515 return -ENOMEM;
20342516
2035
- if (ses && (ses->server))
2036
- server = ses->server;
2037
- else {
2517
+ if (!ses || !server) {
20382518 rc = -EIO;
20392519 goto err_free_path;
20402520 }
20412521
20422522 /* resource #2: request */
2043
- rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len);
2523
+ rc = smb2_plain_req_init(SMB2_CREATE, tcon, server,
2524
+ (void **) &req, &total_len);
20442525 if (rc)
20452526 goto err_free_path;
20462527
....@@ -2122,8 +2603,12 @@
21222603 rqst.rq_iov = iov;
21232604 rqst.rq_nvec = n_iov;
21242605
2606
+ /* no need to inc num_remote_opens because we close it just below */
2607
+ trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, CREATE_NOT_FILE,
2608
+ FILE_WRITE_ATTRIBUTES);
21252609 /* resource #4: response buffer */
2126
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
2610
+ rc = cifs_send_recv(xid, ses, server,
2611
+ &rqst, &resp_buftype, flags, &rsp_iov);
21272612 if (rc) {
21282613 cifs_stats_fail_inc(tcon, SMB2_CREATE_HE);
21292614 trace_smb3_posix_mkdir_err(xid, tcon->tid, ses->Suid,
....@@ -2152,10 +2637,10 @@
21522637 }
21532638
21542639 int
2155
-SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock,
2640
+SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
2641
+ struct smb_rqst *rqst, __u8 *oplock,
21562642 struct cifs_open_parms *oparms, __le16 *path)
21572643 {
2158
- struct TCP_Server_Info *server = tcon->ses->server;
21592644 struct smb2_create_req *req;
21602645 unsigned int n_iov = 2;
21612646 __u32 file_attributes = 0;
....@@ -2166,7 +2651,8 @@
21662651 __le16 *copy_path;
21672652 int rc;
21682653
2169
- rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len);
2654
+ rc = smb2_plain_req_init(SMB2_CREATE, tcon, server,
2655
+ (void **) &req, &total_len);
21702656 if (rc)
21712657 return rc;
21722658
....@@ -2184,6 +2670,7 @@
21842670 /* File attributes ignored on open (used in create though) */
21852671 req->FileAttributes = cpu_to_le32(file_attributes);
21862672 req->ShareAccess = FILE_SHARE_ALL_LE;
2673
+
21872674 req->CreateDisposition = cpu_to_le32(oparms->disposition);
21882675 req->CreateOptions = cpu_to_le32(oparms->create_options & CREATE_OPTIONS_MASK);
21892676 req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req));
....@@ -2285,6 +2772,43 @@
22852772 return rc;
22862773 }
22872774
2775
+ if ((oparms->disposition != FILE_OPEN) && (oparms->cifs_sb)) {
2776
+ bool set_mode;
2777
+ bool set_owner;
2778
+
2779
+ if ((oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) &&
2780
+ (oparms->mode != ACL_NO_MODE))
2781
+ set_mode = true;
2782
+ else {
2783
+ set_mode = false;
2784
+ oparms->mode = ACL_NO_MODE;
2785
+ }
2786
+
2787
+ if (oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL)
2788
+ set_owner = true;
2789
+ else
2790
+ set_owner = false;
2791
+
2792
+ if (set_owner | set_mode) {
2793
+ if (n_iov > 2) {
2794
+ struct create_context *ccontext =
2795
+ (struct create_context *)iov[n_iov-1].iov_base;
2796
+ ccontext->Next = cpu_to_le32(iov[n_iov-1].iov_len);
2797
+ }
2798
+
2799
+ cifs_dbg(FYI, "add sd with mode 0x%x\n", oparms->mode);
2800
+ rc = add_sd_context(iov, &n_iov, oparms->mode, set_owner);
2801
+ if (rc)
2802
+ return rc;
2803
+ }
2804
+ }
2805
+
2806
+ if (n_iov > 2) {
2807
+ struct create_context *ccontext =
2808
+ (struct create_context *)iov[n_iov-1].iov_base;
2809
+ ccontext->Next = cpu_to_le32(iov[n_iov-1].iov_len);
2810
+ }
2811
+ add_query_id_context(iov, &n_iov);
22882812
22892813 rqst->rq_nvec = n_iov;
22902814 return 0;
....@@ -2309,13 +2833,14 @@
23092833 int
23102834 SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
23112835 __u8 *oplock, struct smb2_file_all_info *buf,
2836
+ struct create_posix_rsp *posix,
23122837 struct kvec *err_iov, int *buftype)
23132838 {
23142839 struct smb_rqst rqst;
23152840 struct smb2_create_rsp *rsp = NULL;
2316
- struct TCP_Server_Info *server;
23172841 struct cifs_tcon *tcon = oparms->tcon;
23182842 struct cifs_ses *ses = tcon->ses;
2843
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
23192844 struct kvec iov[SMB2_CREATE_IOV_SIZE];
23202845 struct kvec rsp_iov = {NULL, 0};
23212846 int resp_buftype = CIFS_NO_BUFFER;
....@@ -2323,9 +2848,7 @@
23232848 int flags = 0;
23242849
23252850 cifs_dbg(FYI, "create/open\n");
2326
- if (ses && (ses->server))
2327
- server = ses->server;
2328
- else
2851
+ if (!ses || !server)
23292852 return -EIO;
23302853
23312854 if (smb3_encryption_required(tcon))
....@@ -2336,11 +2859,16 @@
23362859 rqst.rq_iov = iov;
23372860 rqst.rq_nvec = SMB2_CREATE_IOV_SIZE;
23382861
2339
- rc = SMB2_open_init(tcon, &rqst, oplock, oparms, path);
2862
+ rc = SMB2_open_init(tcon, server,
2863
+ &rqst, oplock, oparms, path);
23402864 if (rc)
23412865 goto creat_exit;
23422866
2343
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
2867
+ trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid,
2868
+ oparms->create_options, oparms->desired_access);
2869
+
2870
+ rc = cifs_send_recv(xid, ses, server,
2871
+ &rqst, &resp_buftype, flags,
23442872 &rsp_iov);
23452873 rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
23462874
....@@ -2354,14 +2882,24 @@
23542882 }
23552883 trace_smb3_open_err(xid, tcon->tid, ses->Suid,
23562884 oparms->create_options, oparms->desired_access, rc);
2885
+ if (rc == -EREMCHG) {
2886
+ pr_warn_once("server share %s deleted\n",
2887
+ tcon->treeName);
2888
+ tcon->need_reconnect = true;
2889
+ }
23572890 goto creat_exit;
23582891 } else
23592892 trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid,
23602893 ses->Suid, oparms->create_options,
23612894 oparms->desired_access);
23622895
2896
+ atomic_inc(&tcon->num_remote_opens);
23632897 oparms->fid->persistent_fid = rsp->PersistentFileId;
23642898 oparms->fid->volatile_fid = rsp->VolatileFileId;
2899
+ oparms->fid->access = oparms->desired_access;
2900
+#ifdef CONFIG_CIFS_DEBUG2
2901
+ oparms->fid->mid = le64_to_cpu(rsp->sync_hdr.MessageId);
2902
+#endif /* CIFS_DEBUG2 */
23652903
23662904 if (buf) {
23672905 memcpy(buf, &rsp->CreationTime, 32);
....@@ -2372,37 +2910,135 @@
23722910 buf->DeletePending = 0;
23732911 }
23742912
2375
- if (rsp->OplockLevel == SMB2_OPLOCK_LEVEL_LEASE)
2376
- *oplock = parse_lease_state(server, rsp, &oparms->fid->epoch,
2377
- oparms->fid->lease_key);
2378
- else
2379
- *oplock = rsp->OplockLevel;
2913
+
2914
+ smb2_parse_contexts(server, rsp, &oparms->fid->epoch,
2915
+ oparms->fid->lease_key, oplock, buf, posix);
23802916 creat_exit:
23812917 SMB2_open_free(&rqst);
23822918 free_rsp_buf(resp_buftype, rsp);
23832919 return rc;
23842920 }
23852921
2922
+int
2923
+SMB2_ioctl_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
2924
+ struct smb_rqst *rqst,
2925
+ u64 persistent_fid, u64 volatile_fid, u32 opcode,
2926
+ char *in_data, u32 indatalen,
2927
+ __u32 max_response_size)
2928
+{
2929
+ struct smb2_ioctl_req *req;
2930
+ struct kvec *iov = rqst->rq_iov;
2931
+ unsigned int total_len;
2932
+ int rc;
2933
+ char *in_data_buf;
2934
+
2935
+ rc = smb2_ioctl_req_init(opcode, tcon, server,
2936
+ (void **) &req, &total_len);
2937
+ if (rc)
2938
+ return rc;
2939
+
2940
+ if (indatalen) {
2941
+ /*
2942
+ * indatalen is usually small at a couple of bytes max, so
2943
+ * just allocate through generic pool
2944
+ */
2945
+ in_data_buf = kmemdup(in_data, indatalen, GFP_NOFS);
2946
+ if (!in_data_buf) {
2947
+ cifs_small_buf_release(req);
2948
+ return -ENOMEM;
2949
+ }
2950
+ }
2951
+
2952
+ req->CtlCode = cpu_to_le32(opcode);
2953
+ req->PersistentFileId = persistent_fid;
2954
+ req->VolatileFileId = volatile_fid;
2955
+
2956
+ iov[0].iov_base = (char *)req;
2957
+ /*
2958
+ * If no input data, the size of ioctl struct in
2959
+ * protocol spec still includes a 1 byte data buffer,
2960
+ * but if input data passed to ioctl, we do not
2961
+ * want to double count this, so we do not send
2962
+ * the dummy one byte of data in iovec[0] if sending
2963
+ * input data (in iovec[1]).
2964
+ */
2965
+ if (indatalen) {
2966
+ req->InputCount = cpu_to_le32(indatalen);
2967
+ /* do not set InputOffset if no input data */
2968
+ req->InputOffset =
2969
+ cpu_to_le32(offsetof(struct smb2_ioctl_req, Buffer));
2970
+ rqst->rq_nvec = 2;
2971
+ iov[0].iov_len = total_len - 1;
2972
+ iov[1].iov_base = in_data_buf;
2973
+ iov[1].iov_len = indatalen;
2974
+ } else {
2975
+ rqst->rq_nvec = 1;
2976
+ iov[0].iov_len = total_len;
2977
+ }
2978
+
2979
+ req->OutputOffset = 0;
2980
+ req->OutputCount = 0; /* MBZ */
2981
+
2982
+ /*
2983
+ * In most cases max_response_size is set to 16K (CIFSMaxBufSize)
2984
+ * We Could increase default MaxOutputResponse, but that could require
2985
+ * more credits. Windows typically sets this smaller, but for some
2986
+ * ioctls it may be useful to allow server to send more. No point
2987
+ * limiting what the server can send as long as fits in one credit
2988
+ * We can not handle more than CIFS_MAX_BUF_SIZE yet but may want
2989
+ * to increase this limit up in the future.
2990
+ * Note that for snapshot queries that servers like Azure expect that
2991
+ * the first query be minimal size (and just used to get the number/size
2992
+ * of previous versions) so response size must be specified as EXACTLY
2993
+ * sizeof(struct snapshot_array) which is 16 when rounded up to multiple
2994
+ * of eight bytes. Currently that is the only case where we set max
2995
+ * response size smaller.
2996
+ */
2997
+ req->MaxOutputResponse = cpu_to_le32(max_response_size);
2998
+ req->sync_hdr.CreditCharge =
2999
+ cpu_to_le16(DIV_ROUND_UP(max(indatalen, max_response_size),
3000
+ SMB2_MAX_BUFFER_SIZE));
3001
+ /* always an FSCTL (for now) */
3002
+ req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL);
3003
+
3004
+ /* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
3005
+ if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
3006
+ req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
3007
+
3008
+ return 0;
3009
+}
3010
+
3011
+void
3012
+SMB2_ioctl_free(struct smb_rqst *rqst)
3013
+{
3014
+ int i;
3015
+ if (rqst && rqst->rq_iov) {
3016
+ cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
3017
+ for (i = 1; i < rqst->rq_nvec; i++)
3018
+ if (rqst->rq_iov[i].iov_base != smb2_padding)
3019
+ kfree(rqst->rq_iov[i].iov_base);
3020
+ }
3021
+}
3022
+
3023
+
23863024 /*
23873025 * SMB2 IOCTL is used for both IOCTLs and FSCTLs
23883026 */
23893027 int
23903028 SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
2391
- u64 volatile_fid, u32 opcode, bool is_fsctl,
2392
- char *in_data, u32 indatalen,
2393
- char **out_data, u32 *plen /* returned data len */)
3029
+ u64 volatile_fid, u32 opcode, char *in_data, u32 indatalen,
3030
+ u32 max_out_data_len, char **out_data,
3031
+ u32 *plen /* returned data len */)
23943032 {
23953033 struct smb_rqst rqst;
2396
- struct smb2_ioctl_req *req;
2397
- struct smb2_ioctl_rsp *rsp;
3034
+ struct smb2_ioctl_rsp *rsp = NULL;
23983035 struct cifs_ses *ses;
2399
- struct kvec iov[2];
2400
- struct kvec rsp_iov;
2401
- int resp_buftype;
2402
- int n_iov;
3036
+ struct TCP_Server_Info *server;
3037
+ struct kvec iov[SMB2_IOCTL_IOV_SIZE];
3038
+ struct kvec rsp_iov = {NULL, 0};
3039
+ int resp_buftype = CIFS_NO_BUFFER;
24033040 int rc = 0;
24043041 int flags = 0;
2405
- unsigned int total_len;
24063042
24073043 cifs_dbg(FYI, "SMB2 IOCTL\n");
24083044
....@@ -2413,95 +3049,51 @@
24133049 if (plen)
24143050 *plen = 0;
24153051
2416
- if (tcon)
2417
- ses = tcon->ses;
2418
- else
3052
+ if (!tcon)
24193053 return -EIO;
24203054
2421
- if (!ses || !(ses->server))
3055
+ ses = tcon->ses;
3056
+ if (!ses)
24223057 return -EIO;
24233058
2424
- rc = smb2_ioctl_req_init(opcode, tcon, (void **) &req, &total_len);
2425
- if (rc)
2426
- return rc;
3059
+ server = cifs_pick_channel(ses);
3060
+ if (!server)
3061
+ return -EIO;
24273062
24283063 if (smb3_encryption_required(tcon))
24293064 flags |= CIFS_TRANSFORM_REQ;
24303065
2431
- req->CtlCode = cpu_to_le32(opcode);
2432
- req->PersistentFileId = persistent_fid;
2433
- req->VolatileFileId = volatile_fid;
2434
-
2435
- if (indatalen) {
2436
- req->InputCount = cpu_to_le32(indatalen);
2437
- /* do not set InputOffset if no input data */
2438
- req->InputOffset =
2439
- cpu_to_le32(offsetof(struct smb2_ioctl_req, Buffer));
2440
- iov[1].iov_base = in_data;
2441
- iov[1].iov_len = indatalen;
2442
- n_iov = 2;
2443
- } else
2444
- n_iov = 1;
2445
-
2446
- req->OutputOffset = 0;
2447
- req->OutputCount = 0; /* MBZ */
2448
-
2449
- /*
2450
- * Could increase MaxOutputResponse, but that would require more
2451
- * than one credit. Windows typically sets this smaller, but for some
2452
- * ioctls it may be useful to allow server to send more. No point
2453
- * limiting what the server can send as long as fits in one credit
2454
- * Unfortunately - we can not handle more than CIFS_MAX_MSG_SIZE
2455
- * (by default, note that it can be overridden to make max larger)
2456
- * in responses (except for read responses which can be bigger.
2457
- * We may want to bump this limit up
2458
- */
2459
- req->MaxOutputResponse = cpu_to_le32(CIFSMaxBufSize);
2460
-
2461
- if (is_fsctl)
2462
- req->Flags = cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL);
2463
- else
2464
- req->Flags = 0;
2465
-
2466
- iov[0].iov_base = (char *)req;
2467
-
2468
- /*
2469
- * If no input data, the size of ioctl struct in
2470
- * protocol spec still includes a 1 byte data buffer,
2471
- * but if input data passed to ioctl, we do not
2472
- * want to double count this, so we do not send
2473
- * the dummy one byte of data in iovec[0] if sending
2474
- * input data (in iovec[1]).
2475
- */
2476
-
2477
- if (indatalen) {
2478
- iov[0].iov_len = total_len - 1;
2479
- } else
2480
- iov[0].iov_len = total_len;
2481
-
2482
- /* validate negotiate request must be signed - see MS-SMB2 3.2.5.5 */
2483
- if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
2484
- req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
2485
-
24863066 memset(&rqst, 0, sizeof(struct smb_rqst));
3067
+ memset(&iov, 0, sizeof(iov));
24873068 rqst.rq_iov = iov;
2488
- rqst.rq_nvec = n_iov;
3069
+ rqst.rq_nvec = SMB2_IOCTL_IOV_SIZE;
24893070
2490
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
3071
+ rc = SMB2_ioctl_init(tcon, server,
3072
+ &rqst, persistent_fid, volatile_fid, opcode,
3073
+ in_data, indatalen, max_out_data_len);
3074
+ if (rc)
3075
+ goto ioctl_exit;
3076
+
3077
+ rc = cifs_send_recv(xid, ses, server,
3078
+ &rqst, &resp_buftype, flags,
24913079 &rsp_iov);
2492
- cifs_small_buf_release(req);
24933080 rsp = (struct smb2_ioctl_rsp *)rsp_iov.iov_base;
24943081
24953082 if (rc != 0)
24963083 trace_smb3_fsctl_err(xid, persistent_fid, tcon->tid,
24973084 ses->Suid, 0, opcode, rc);
24983085
2499
- if ((rc != 0) && (rc != -EINVAL)) {
3086
+ if ((rc != 0) && (rc != -EINVAL) && (rc != -E2BIG)) {
25003087 cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
25013088 goto ioctl_exit;
25023089 } else if (rc == -EINVAL) {
25033090 if ((opcode != FSCTL_SRV_COPYCHUNK_WRITE) &&
25043091 (opcode != FSCTL_SRV_COPYCHUNK)) {
3092
+ cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
3093
+ goto ioctl_exit;
3094
+ }
3095
+ } else if (rc == -E2BIG) {
3096
+ if (opcode != FSCTL_QUERY_ALLOCATED_RANGES) {
25053097 cifs_stats_fail_inc(tcon, SMB2_IOCTL_HE);
25063098 goto ioctl_exit;
25073099 }
....@@ -2517,28 +3109,29 @@
25173109 if (*plen == 0)
25183110 goto ioctl_exit; /* server returned no data */
25193111 else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) {
2520
- cifs_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen);
3112
+ cifs_tcon_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen);
25213113 *plen = 0;
25223114 rc = -EIO;
25233115 goto ioctl_exit;
25243116 }
25253117
25263118 if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) {
2527
- cifs_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen,
3119
+ cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen,
25283120 le32_to_cpu(rsp->OutputOffset));
25293121 *plen = 0;
25303122 rc = -EIO;
25313123 goto ioctl_exit;
25323124 }
25333125
2534
- *out_data = kmalloc(*plen, GFP_KERNEL);
3126
+ *out_data = kmemdup((char *)rsp + le32_to_cpu(rsp->OutputOffset),
3127
+ *plen, GFP_KERNEL);
25353128 if (*out_data == NULL) {
25363129 rc = -ENOMEM;
25373130 goto ioctl_exit;
25383131 }
25393132
2540
- memcpy(*out_data, (char *)rsp + le32_to_cpu(rsp->OutputOffset), *plen);
25413133 ioctl_exit:
3134
+ SMB2_ioctl_free(&rqst);
25423135 free_rsp_buf(resp_buftype, rsp);
25433136 return rc;
25443137 }
....@@ -2559,9 +3152,10 @@
25593152 cpu_to_le16(COMPRESSION_FORMAT_DEFAULT);
25603153
25613154 rc = SMB2_ioctl(xid, tcon, persistent_fid, volatile_fid,
2562
- FSCTL_SET_COMPRESSION, true /* is_fsctl */,
3155
+ FSCTL_SET_COMPRESSION,
25633156 (char *)&fsctl_input /* data input */,
2564
- 2 /* in data len */, &ret_data /* out data */, NULL);
3157
+ 2 /* in data len */, CIFSMaxBufSize /* max out data */,
3158
+ &ret_data /* out data */, NULL);
25653159
25663160 cifs_dbg(FYI, "set compression rc %d\n", rc);
25673161
....@@ -2569,20 +3163,26 @@
25693163 }
25703164
25713165 int
2572
-SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
2573
- u64 persistent_fid, u64 volatile_fid)
3166
+SMB2_close_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
3167
+ struct smb_rqst *rqst,
3168
+ u64 persistent_fid, u64 volatile_fid, bool query_attrs)
25743169 {
25753170 struct smb2_close_req *req;
25763171 struct kvec *iov = rqst->rq_iov;
25773172 unsigned int total_len;
25783173 int rc;
25793174
2580
- rc = smb2_plain_req_init(SMB2_CLOSE, tcon, (void **) &req, &total_len);
3175
+ rc = smb2_plain_req_init(SMB2_CLOSE, tcon, server,
3176
+ (void **) &req, &total_len);
25813177 if (rc)
25823178 return rc;
25833179
25843180 req->PersistentFileId = persistent_fid;
25853181 req->VolatileFileId = volatile_fid;
3182
+ if (query_attrs)
3183
+ req->Flags = SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB;
3184
+ else
3185
+ req->Flags = 0;
25863186 iov[0].iov_base = (char *)req;
25873187 iov[0].iov_len = total_len;
25883188
....@@ -2597,20 +3197,24 @@
25973197 }
25983198
25993199 int
2600
-SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon,
2601
- u64 persistent_fid, u64 volatile_fid, int flags)
3200
+__SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
3201
+ u64 persistent_fid, u64 volatile_fid,
3202
+ struct smb2_file_network_open_info *pbuf)
26023203 {
26033204 struct smb_rqst rqst;
26043205 struct smb2_close_rsp *rsp = NULL;
26053206 struct cifs_ses *ses = tcon->ses;
3207
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
26063208 struct kvec iov[1];
26073209 struct kvec rsp_iov;
26083210 int resp_buftype = CIFS_NO_BUFFER;
26093211 int rc = 0;
3212
+ int flags = 0;
3213
+ bool query_attrs = false;
26103214
26113215 cifs_dbg(FYI, "Close\n");
26123216
2613
- if (!ses || !(ses->server))
3217
+ if (!ses || !server)
26143218 return -EIO;
26153219
26163220 if (smb3_encryption_required(tcon))
....@@ -2621,11 +3225,19 @@
26213225 rqst.rq_iov = iov;
26223226 rqst.rq_nvec = 1;
26233227
2624
- rc = SMB2_close_init(tcon, &rqst, persistent_fid, volatile_fid);
3228
+ /* check if need to ask server to return timestamps in close response */
3229
+ if (pbuf)
3230
+ query_attrs = true;
3231
+
3232
+ trace_smb3_close_enter(xid, persistent_fid, tcon->tid, ses->Suid);
3233
+ rc = SMB2_close_init(tcon, server,
3234
+ &rqst, persistent_fid, volatile_fid,
3235
+ query_attrs);
26253236 if (rc)
26263237 goto close_exit;
26273238
2628
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
3239
+ rc = cifs_send_recv(xid, ses, server,
3240
+ &rqst, &resp_buftype, flags, &rsp_iov);
26293241 rsp = (struct smb2_close_rsp *)rsp_iov.iov_base;
26303242
26313243 if (rc != 0) {
....@@ -2633,35 +3245,40 @@
26333245 trace_smb3_close_err(xid, persistent_fid, tcon->tid, ses->Suid,
26343246 rc);
26353247 goto close_exit;
3248
+ } else {
3249
+ trace_smb3_close_done(xid, persistent_fid, tcon->tid,
3250
+ ses->Suid);
3251
+ /*
3252
+ * Note that have to subtract 4 since struct network_open_info
3253
+ * has a final 4 byte pad that close response does not have
3254
+ */
3255
+ if (pbuf)
3256
+ memcpy(pbuf, (char *)&rsp->CreationTime, sizeof(*pbuf) - 4);
26363257 }
26373258
2638
- /* BB FIXME - decode close response, update inode for caching */
2639
-
3259
+ atomic_dec(&tcon->num_remote_opens);
26403260 close_exit:
26413261 SMB2_close_free(&rqst);
26423262 free_rsp_buf(resp_buftype, rsp);
2643
- return rc;
2644
-}
2645
-
2646
-int
2647
-SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
2648
- u64 persistent_fid, u64 volatile_fid)
2649
-{
2650
- int rc;
2651
- int tmp_rc;
2652
-
2653
- rc = SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0);
26543263
26553264 /* retry close in a worker thread if this one is interrupted */
2656
- if (rc == -EINTR) {
3265
+ if (is_interrupt_error(rc)) {
3266
+ int tmp_rc;
3267
+
26573268 tmp_rc = smb2_handle_cancelled_close(tcon, persistent_fid,
26583269 volatile_fid);
26593270 if (tmp_rc)
26603271 cifs_dbg(VFS, "handle cancelled close fid 0x%llx returned error %d\n",
26613272 persistent_fid, tmp_rc);
26623273 }
2663
-
26643274 return rc;
3275
+}
3276
+
3277
+int
3278
+SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
3279
+ u64 persistent_fid, u64 volatile_fid)
3280
+{
3281
+ return __SMB2_close(xid, tcon, persistent_fid, volatile_fid, NULL);
26653282 }
26663283
26673284 int
....@@ -2688,7 +3305,7 @@
26883305 }
26893306
26903307 if ((begin_of_buf > end_of_smb) || (end_of_buf > end_of_smb)) {
2691
- cifs_dbg(VFS, "illegal server response, bad offset to data\n");
3308
+ cifs_dbg(VFS, "Invalid server response, bad offset to data\n");
26923309 return -EINVAL;
26933310 }
26943311
....@@ -2699,10 +3316,10 @@
26993316 * If SMB buffer fields are valid, copy into temporary buffer to hold result.
27003317 * Caller must free buffer.
27013318 */
2702
-static int
2703
-validate_and_copy_iov(unsigned int offset, unsigned int buffer_length,
2704
- struct kvec *iov, unsigned int minbufsize,
2705
- char *data)
3319
+int
3320
+smb2_validate_and_copy_iov(unsigned int offset, unsigned int buffer_length,
3321
+ struct kvec *iov, unsigned int minbufsize,
3322
+ char *data)
27063323 {
27073324 char *begin_of_buf = offset + (char *)iov->iov_base;
27083325 int rc;
....@@ -2720,18 +3337,19 @@
27203337 }
27213338
27223339 int
2723
-SMB2_query_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
3340
+SMB2_query_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
3341
+ struct smb_rqst *rqst,
27243342 u64 persistent_fid, u64 volatile_fid,
27253343 u8 info_class, u8 info_type, u32 additional_info,
2726
- size_t output_len)
3344
+ size_t output_len, size_t input_len, void *input)
27273345 {
27283346 struct smb2_query_info_req *req;
27293347 struct kvec *iov = rqst->rq_iov;
27303348 unsigned int total_len;
27313349 int rc;
27323350
2733
- rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, (void **) &req,
2734
- &total_len);
3351
+ rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server,
3352
+ (void **) &req, &total_len);
27353353 if (rc)
27363354 return rc;
27373355
....@@ -2741,16 +3359,17 @@
27413359 req->VolatileFileId = volatile_fid;
27423360 req->AdditionalInformation = cpu_to_le32(additional_info);
27433361
2744
- /*
2745
- * We do not use the input buffer (do not send extra byte)
2746
- */
2747
- req->InputBufferOffset = 0;
2748
-
27493362 req->OutputBufferLength = cpu_to_le32(output_len);
3363
+ if (input_len) {
3364
+ req->InputBufferLength = cpu_to_le32(input_len);
3365
+ /* total_len for smb query request never close to le16 max */
3366
+ req->InputBufferOffset = cpu_to_le16(total_len - 1);
3367
+ memcpy(req->Buffer, input, input_len);
3368
+ }
27503369
27513370 iov[0].iov_base = (char *)req;
27523371 /* 1 for Buffer */
2753
- iov[0].iov_len = total_len - 1;
3372
+ iov[0].iov_len = total_len - 1 + input_len;
27543373 return 0;
27553374 }
27563375
....@@ -2774,11 +3393,16 @@
27743393 int rc = 0;
27753394 int resp_buftype = CIFS_NO_BUFFER;
27763395 struct cifs_ses *ses = tcon->ses;
3396
+ struct TCP_Server_Info *server;
27773397 int flags = 0;
3398
+ bool allocated = false;
27783399
27793400 cifs_dbg(FYI, "Query Info\n");
27803401
2781
- if (!ses || !(ses->server))
3402
+ if (!ses)
3403
+ return -EIO;
3404
+ server = cifs_pick_channel(ses);
3405
+ if (!server)
27823406 return -EIO;
27833407
27843408 if (smb3_encryption_required(tcon))
....@@ -2789,13 +3413,18 @@
27893413 rqst.rq_iov = iov;
27903414 rqst.rq_nvec = 1;
27913415
2792
- rc = SMB2_query_info_init(tcon, &rqst, persistent_fid, volatile_fid,
3416
+ rc = SMB2_query_info_init(tcon, server,
3417
+ &rqst, persistent_fid, volatile_fid,
27933418 info_class, info_type, additional_info,
2794
- output_len);
3419
+ output_len, 0, NULL);
27953420 if (rc)
27963421 goto qinf_exit;
27973422
2798
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
3423
+ trace_smb3_query_info_enter(xid, persistent_fid, tcon->tid,
3424
+ ses->Suid, info_class, (__u32)info_type);
3425
+
3426
+ rc = cifs_send_recv(xid, ses, server,
3427
+ &rqst, &resp_buftype, flags, &rsp_iov);
27993428 rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
28003429
28013430 if (rc) {
....@@ -2805,40 +3434,38 @@
28053434 goto qinf_exit;
28063435 }
28073436
3437
+ trace_smb3_query_info_done(xid, persistent_fid, tcon->tid,
3438
+ ses->Suid, info_class, (__u32)info_type);
3439
+
28083440 if (dlen) {
28093441 *dlen = le32_to_cpu(rsp->OutputBufferLength);
28103442 if (!*data) {
28113443 *data = kmalloc(*dlen, GFP_KERNEL);
28123444 if (!*data) {
2813
- cifs_dbg(VFS,
3445
+ cifs_tcon_dbg(VFS,
28143446 "Error %d allocating memory for acl\n",
28153447 rc);
28163448 *dlen = 0;
3449
+ rc = -ENOMEM;
28173450 goto qinf_exit;
28183451 }
3452
+ allocated = true;
28193453 }
28203454 }
28213455
2822
- rc = validate_and_copy_iov(le16_to_cpu(rsp->OutputBufferOffset),
2823
- le32_to_cpu(rsp->OutputBufferLength),
2824
- &rsp_iov, min_len, *data);
3456
+ rc = smb2_validate_and_copy_iov(le16_to_cpu(rsp->OutputBufferOffset),
3457
+ le32_to_cpu(rsp->OutputBufferLength),
3458
+ &rsp_iov, min_len, *data);
3459
+ if (rc && allocated) {
3460
+ kfree(*data);
3461
+ *data = NULL;
3462
+ *dlen = 0;
3463
+ }
28253464
28263465 qinf_exit:
28273466 SMB2_query_info_free(&rqst);
28283467 free_rsp_buf(resp_buftype, rsp);
28293468 return rc;
2830
-}
2831
-
2832
-int SMB2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
2833
- u64 persistent_fid, u64 volatile_fid,
2834
- int ea_buf_size, struct smb2_file_full_ea_info *data)
2835
-{
2836
- return query_info(xid, tcon, persistent_fid, volatile_fid,
2837
- FILE_FULL_EA_INFORMATION, SMB2_O_INFO_FILE, 0,
2838
- ea_buf_size,
2839
- sizeof(struct smb2_file_full_ea_info),
2840
- (void **)&data,
2841
- NULL);
28423469 }
28433470
28443471 int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
....@@ -2849,6 +3476,19 @@
28493476 sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
28503477 sizeof(struct smb2_file_all_info), (void **)&data,
28513478 NULL);
3479
+}
3480
+
3481
+int
3482
+SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon,
3483
+ u64 persistent_fid, u64 volatile_fid, struct smb311_posix_qinfo *data, u32 *plen)
3484
+{
3485
+ size_t output_len = sizeof(struct smb311_posix_qinfo *) +
3486
+ (sizeof(struct cifs_sid) * 2) + (PATH_MAX * 2);
3487
+ *plen = 0;
3488
+
3489
+ return query_info(xid, tcon, persistent_fid, volatile_fid,
3490
+ SMB_FIND_FILE_POSIX_INFO, SMB2_O_INFO_FILE, 0,
3491
+ output_len, sizeof(struct smb311_posix_qinfo), (void **)&data, plen);
28523492 }
28533493
28543494 int
....@@ -2876,6 +3516,98 @@
28763516 }
28773517
28783518 /*
3519
+ * CHANGE_NOTIFY Request is sent to get notifications on changes to a directory
3520
+ * See MS-SMB2 2.2.35 and 2.2.36
3521
+ */
3522
+
3523
+static int
3524
+SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst,
3525
+ struct cifs_tcon *tcon, struct TCP_Server_Info *server,
3526
+ u64 persistent_fid, u64 volatile_fid,
3527
+ u32 completion_filter, bool watch_tree)
3528
+{
3529
+ struct smb2_change_notify_req *req;
3530
+ struct kvec *iov = rqst->rq_iov;
3531
+ unsigned int total_len;
3532
+ int rc;
3533
+
3534
+ rc = smb2_plain_req_init(SMB2_CHANGE_NOTIFY, tcon, server,
3535
+ (void **) &req, &total_len);
3536
+ if (rc)
3537
+ return rc;
3538
+
3539
+ req->PersistentFileId = persistent_fid;
3540
+ req->VolatileFileId = volatile_fid;
3541
+ /* See note 354 of MS-SMB2, 64K max */
3542
+ req->OutputBufferLength =
3543
+ cpu_to_le32(SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE);
3544
+ req->CompletionFilter = cpu_to_le32(completion_filter);
3545
+ if (watch_tree)
3546
+ req->Flags = cpu_to_le16(SMB2_WATCH_TREE);
3547
+ else
3548
+ req->Flags = 0;
3549
+
3550
+ iov[0].iov_base = (char *)req;
3551
+ iov[0].iov_len = total_len;
3552
+
3553
+ return 0;
3554
+}
3555
+
3556
+int
3557
+SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon,
3558
+ u64 persistent_fid, u64 volatile_fid, bool watch_tree,
3559
+ u32 completion_filter)
3560
+{
3561
+ struct cifs_ses *ses = tcon->ses;
3562
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
3563
+ struct smb_rqst rqst;
3564
+ struct kvec iov[1];
3565
+ struct kvec rsp_iov = {NULL, 0};
3566
+ int resp_buftype = CIFS_NO_BUFFER;
3567
+ int flags = 0;
3568
+ int rc = 0;
3569
+
3570
+ cifs_dbg(FYI, "change notify\n");
3571
+ if (!ses || !server)
3572
+ return -EIO;
3573
+
3574
+ if (smb3_encryption_required(tcon))
3575
+ flags |= CIFS_TRANSFORM_REQ;
3576
+
3577
+ memset(&rqst, 0, sizeof(struct smb_rqst));
3578
+ memset(&iov, 0, sizeof(iov));
3579
+ rqst.rq_iov = iov;
3580
+ rqst.rq_nvec = 1;
3581
+
3582
+ rc = SMB2_notify_init(xid, &rqst, tcon, server,
3583
+ persistent_fid, volatile_fid,
3584
+ completion_filter, watch_tree);
3585
+ if (rc)
3586
+ goto cnotify_exit;
3587
+
3588
+ trace_smb3_notify_enter(xid, persistent_fid, tcon->tid, ses->Suid,
3589
+ (u8)watch_tree, completion_filter);
3590
+ rc = cifs_send_recv(xid, ses, server,
3591
+ &rqst, &resp_buftype, flags, &rsp_iov);
3592
+
3593
+ if (rc != 0) {
3594
+ cifs_stats_fail_inc(tcon, SMB2_CHANGE_NOTIFY_HE);
3595
+ trace_smb3_notify_err(xid, persistent_fid, tcon->tid, ses->Suid,
3596
+ (u8)watch_tree, completion_filter, rc);
3597
+ } else
3598
+ trace_smb3_notify_done(xid, persistent_fid, tcon->tid,
3599
+ ses->Suid, (u8)watch_tree, completion_filter);
3600
+
3601
+ cnotify_exit:
3602
+ if (rqst.rq_iov)
3603
+ cifs_small_buf_release(rqst.rq_iov[0].iov_base); /* request */
3604
+ free_rsp_buf(resp_buftype, rsp_iov.iov_base);
3605
+ return rc;
3606
+}
3607
+
3608
+
3609
+
3610
+/*
28793611 * This is a no-op for now. We're not really interested in the reply, but
28803612 * rather in the fact that the server sent one and that server->lstrp
28813613 * gets updated.
....@@ -2887,14 +3619,16 @@
28873619 {
28883620 struct TCP_Server_Info *server = mid->callback_data;
28893621 struct smb2_echo_rsp *rsp = (struct smb2_echo_rsp *)mid->resp_buf;
2890
- unsigned int credits_received = 0;
3622
+ struct cifs_credits credits = { .value = 0, .instance = 0 };
28913623
28923624 if (mid->mid_state == MID_RESPONSE_RECEIVED
2893
- || mid->mid_state == MID_RESPONSE_MALFORMED)
2894
- credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest);
3625
+ || mid->mid_state == MID_RESPONSE_MALFORMED) {
3626
+ credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
3627
+ credits.instance = server->reconnect_instance;
3628
+ }
28953629
28963630 DeleteMidQEntry(mid);
2897
- add_credits(server, credits_received, CIFS_ECHO_OP);
3631
+ add_credits(server, &credits, CIFS_ECHO_OP);
28983632 }
28993633
29003634 void smb2_reconnect_server(struct work_struct *work)
....@@ -2924,9 +3658,14 @@
29243658 tcon_exist = true;
29253659 }
29263660 }
3661
+ /*
3662
+ * IPC has the same lifetime as its session and uses its
3663
+ * refcount.
3664
+ */
29273665 if (ses->tcon_ipc && ses->tcon_ipc->need_reconnect) {
29283666 list_add_tail(&ses->tcon_ipc->rlist, &tmp_list);
29293667 tcon_exist = true;
3668
+ ses->ses_count++;
29303669 }
29313670 }
29323671 /*
....@@ -2939,13 +3678,16 @@
29393678 spin_unlock(&cifs_tcp_ses_lock);
29403679
29413680 list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
2942
- rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon);
3681
+ rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon, server);
29433682 if (!rc)
29443683 cifs_reopen_persistent_handles(tcon);
29453684 else
29463685 resched = true;
29473686 list_del_init(&tcon->rlist);
2948
- cifs_put_tcon(tcon);
3687
+ if (tcon->ipc)
3688
+ cifs_put_smb_ses(tcon->ses);
3689
+ else
3690
+ cifs_put_tcon(tcon);
29493691 }
29503692
29513693 cifs_dbg(FYI, "Reconnecting tcons finished\n");
....@@ -2972,11 +3714,12 @@
29723714
29733715 if (server->tcpStatus == CifsNeedNegotiate) {
29743716 /* No need to send echo on newly established connections */
2975
- queue_delayed_work(cifsiod_wq, &server->reconnect, 0);
3717
+ mod_delayed_work(cifsiod_wq, &server->reconnect, 0);
29763718 return rc;
29773719 }
29783720
2979
- rc = smb2_plain_req_init(SMB2_ECHO, NULL, (void **)&req, &total_len);
3721
+ rc = smb2_plain_req_init(SMB2_ECHO, NULL, server,
3722
+ (void **)&req, &total_len);
29803723 if (rc)
29813724 return rc;
29823725
....@@ -2986,7 +3729,7 @@
29863729 iov[0].iov_base = (char *)req;
29873730
29883731 rc = cifs_call_async(server, &rqst, NULL, smb2_echo_callback, NULL,
2989
- server, CIFS_ECHO_OP);
3732
+ server, CIFS_ECHO_OP, NULL);
29903733 if (rc)
29913734 cifs_dbg(FYI, "Echo request failed: %d\n", rc);
29923735
....@@ -2994,31 +3737,27 @@
29943737 return rc;
29953738 }
29963739
2997
-int
2998
-SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
2999
- u64 volatile_fid)
3740
+void
3741
+SMB2_flush_free(struct smb_rqst *rqst)
30003742 {
3001
- struct smb_rqst rqst;
3743
+ if (rqst && rqst->rq_iov)
3744
+ cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
3745
+}
3746
+
3747
+int
3748
+SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst,
3749
+ struct cifs_tcon *tcon, struct TCP_Server_Info *server,
3750
+ u64 persistent_fid, u64 volatile_fid)
3751
+{
30023752 struct smb2_flush_req *req;
3003
- struct cifs_ses *ses = tcon->ses;
3004
- struct kvec iov[1];
3005
- struct kvec rsp_iov;
3006
- int resp_buftype;
3007
- int rc = 0;
3008
- int flags = 0;
3753
+ struct kvec *iov = rqst->rq_iov;
30093754 unsigned int total_len;
3755
+ int rc;
30103756
3011
- cifs_dbg(FYI, "Flush\n");
3012
-
3013
- if (!ses || !(ses->server))
3014
- return -EIO;
3015
-
3016
- rc = smb2_plain_req_init(SMB2_FLUSH, tcon, (void **) &req, &total_len);
3757
+ rc = smb2_plain_req_init(SMB2_FLUSH, tcon, server,
3758
+ (void **) &req, &total_len);
30173759 if (rc)
30183760 return rc;
3019
-
3020
- if (smb3_encryption_required(tcon))
3021
- flags |= CIFS_TRANSFORM_REQ;
30223761
30233762 req->PersistentFileId = persistent_fid;
30243763 req->VolatileFileId = volatile_fid;
....@@ -3026,19 +3765,53 @@
30263765 iov[0].iov_base = (char *)req;
30273766 iov[0].iov_len = total_len;
30283767
3768
+ return 0;
3769
+}
3770
+
3771
+int
3772
+SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
3773
+ u64 volatile_fid)
3774
+{
3775
+ struct cifs_ses *ses = tcon->ses;
3776
+ struct smb_rqst rqst;
3777
+ struct kvec iov[1];
3778
+ struct kvec rsp_iov = {NULL, 0};
3779
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
3780
+ int resp_buftype = CIFS_NO_BUFFER;
3781
+ int flags = 0;
3782
+ int rc = 0;
3783
+
3784
+ cifs_dbg(FYI, "flush\n");
3785
+ if (!ses || !(ses->server))
3786
+ return -EIO;
3787
+
3788
+ if (smb3_encryption_required(tcon))
3789
+ flags |= CIFS_TRANSFORM_REQ;
3790
+
30293791 memset(&rqst, 0, sizeof(struct smb_rqst));
3792
+ memset(&iov, 0, sizeof(iov));
30303793 rqst.rq_iov = iov;
30313794 rqst.rq_nvec = 1;
30323795
3033
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
3034
- cifs_small_buf_release(req);
3796
+ rc = SMB2_flush_init(xid, &rqst, tcon, server,
3797
+ persistent_fid, volatile_fid);
3798
+ if (rc)
3799
+ goto flush_exit;
3800
+
3801
+ trace_smb3_flush_enter(xid, persistent_fid, tcon->tid, ses->Suid);
3802
+ rc = cifs_send_recv(xid, ses, server,
3803
+ &rqst, &resp_buftype, flags, &rsp_iov);
30353804
30363805 if (rc != 0) {
30373806 cifs_stats_fail_inc(tcon, SMB2_FLUSH_HE);
30383807 trace_smb3_flush_err(xid, persistent_fid, tcon->tid, ses->Suid,
30393808 rc);
3040
- }
3809
+ } else
3810
+ trace_smb3_flush_done(xid, persistent_fid, tcon->tid,
3811
+ ses->Suid);
30413812
3813
+ flush_exit:
3814
+ SMB2_flush_free(&rqst);
30423815 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
30433816 return rc;
30443817 }
....@@ -3055,14 +3828,13 @@
30553828 int rc = -EACCES;
30563829 struct smb2_read_plain_req *req = NULL;
30573830 struct smb2_sync_hdr *shdr;
3058
- struct TCP_Server_Info *server;
3831
+ struct TCP_Server_Info *server = io_parms->server;
30593832
3060
- rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, (void **) &req,
3061
- total_len);
3833
+ rc = smb2_plain_req_init(SMB2_READ, io_parms->tcon, server,
3834
+ (void **) &req, total_len);
30623835 if (rc)
30633836 return rc;
30643837
3065
- server = io_parms->tcon->ses->server;
30663838 if (server == NULL)
30673839 return -ECONNABORTED;
30683840
....@@ -3077,6 +3849,11 @@
30773849 req->MinimumCount = 0;
30783850 req->Length = cpu_to_le32(io_parms->length);
30793851 req->Offset = cpu_to_le64(io_parms->offset);
3852
+
3853
+ trace_smb3_read_enter(0 /* xid */,
3854
+ io_parms->persistent_fid,
3855
+ io_parms->tcon->tid, io_parms->tcon->ses->Suid,
3856
+ io_parms->offset, io_parms->length);
30803857 #ifdef CONFIG_CIFS_SMB_DIRECT
30813858 /*
30823859 * If we want to do a RDMA write, fill in and append
....@@ -3086,15 +3863,14 @@
30863863 rdata->bytes >= server->smbd_conn->rdma_readwrite_threshold) {
30873864
30883865 struct smbd_buffer_descriptor_v1 *v1;
3089
- bool need_invalidate =
3090
- io_parms->tcon->ses->server->dialect == SMB30_PROT_ID;
3866
+ bool need_invalidate = server->dialect == SMB30_PROT_ID;
30913867
30923868 rdata->mr = smbd_register_mr(
30933869 server->smbd_conn, rdata->pages,
30943870 rdata->nr_pages, rdata->page_offset,
30953871 rdata->tailsz, true, need_invalidate);
30963872 if (!rdata->mr)
3097
- return -ENOBUFS;
3873
+ return -EAGAIN;
30983874
30993875 req->Channel = SMB2_CHANNEL_RDMA_V1_INVALIDATE;
31003876 if (need_invalidate)
....@@ -3144,17 +3920,24 @@
31443920 {
31453921 struct cifs_readdata *rdata = mid->callback_data;
31463922 struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
3147
- struct TCP_Server_Info *server = tcon->ses->server;
3923
+ struct TCP_Server_Info *server = rdata->server;
31483924 struct smb2_sync_hdr *shdr =
31493925 (struct smb2_sync_hdr *)rdata->iov[0].iov_base;
3150
- unsigned int credits_received = 0;
3926
+ struct cifs_credits credits = { .value = 0, .instance = 0 };
31513927 struct smb_rqst rqst = { .rq_iov = &rdata->iov[1],
3152
- .rq_nvec = 1,
3153
- .rq_pages = rdata->pages,
3154
- .rq_offset = rdata->page_offset,
3155
- .rq_npages = rdata->nr_pages,
3156
- .rq_pagesz = rdata->pagesz,
3157
- .rq_tailsz = rdata->tailsz };
3928
+ .rq_nvec = 1, };
3929
+
3930
+ if (rdata->got_bytes) {
3931
+ rqst.rq_pages = rdata->pages;
3932
+ rqst.rq_offset = rdata->page_offset;
3933
+ rqst.rq_npages = rdata->nr_pages;
3934
+ rqst.rq_pagesz = rdata->pagesz;
3935
+ rqst.rq_tailsz = rdata->tailsz;
3936
+ }
3937
+
3938
+ WARN_ONCE(rdata->server != mid->server,
3939
+ "rdata server %p != mid server %p",
3940
+ rdata->server, mid->server);
31583941
31593942 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
31603943 __func__, mid->mid, mid->mid_state, rdata->result,
....@@ -3162,14 +3945,15 @@
31623945
31633946 switch (mid->mid_state) {
31643947 case MID_RESPONSE_RECEIVED:
3165
- credits_received = le16_to_cpu(shdr->CreditRequest);
3948
+ credits.value = le16_to_cpu(shdr->CreditRequest);
3949
+ credits.instance = server->reconnect_instance;
31663950 /* result already set, check signature */
31673951 if (server->sign && !mid->decrypted) {
31683952 int rc;
31693953
31703954 rc = smb2_verify_signature(&rqst, server);
31713955 if (rc)
3172
- cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
3956
+ cifs_tcon_dbg(VFS, "SMB signature verification returned error = %d\n",
31733957 rc);
31743958 }
31753959 /* FIXME: should this be counted toward the initiating task? */
....@@ -3187,11 +3971,11 @@
31873971 cifs_stats_bytes_read(tcon, rdata->got_bytes);
31883972 break;
31893973 case MID_RESPONSE_MALFORMED:
3190
- credits_received = le16_to_cpu(shdr->CreditRequest);
3191
- /* fall through */
3974
+ credits.value = le16_to_cpu(shdr->CreditRequest);
3975
+ credits.instance = server->reconnect_instance;
3976
+ fallthrough;
31923977 default:
3193
- if (rdata->result != -ENODATA)
3194
- rdata->result = -EIO;
3978
+ rdata->result = -EIO;
31953979 }
31963980 #ifdef CONFIG_CIFS_SMB_DIRECT
31973981 /*
....@@ -3218,7 +4002,7 @@
32184002
32194003 queue_work(cifsiod_wq, &rdata->work);
32204004 DeleteMidQEntry(mid);
3221
- add_credits(server, credits_received, 0);
4005
+ add_credits(server, &credits, 0);
32224006 }
32234007
32244008 /* smb2_async_readv - send an async read, and set up mid to handle result */
....@@ -3232,33 +4016,27 @@
32324016 struct smb_rqst rqst = { .rq_iov = rdata->iov,
32334017 .rq_nvec = 1 };
32344018 struct TCP_Server_Info *server;
4019
+ struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
32354020 unsigned int total_len;
32364021
32374022 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
32384023 __func__, rdata->offset, rdata->bytes);
32394024
4025
+ if (!rdata->server)
4026
+ rdata->server = cifs_pick_channel(tcon->ses);
4027
+
32404028 io_parms.tcon = tlink_tcon(rdata->cfile->tlink);
4029
+ io_parms.server = server = rdata->server;
32414030 io_parms.offset = rdata->offset;
32424031 io_parms.length = rdata->bytes;
32434032 io_parms.persistent_fid = rdata->cfile->fid.persistent_fid;
32444033 io_parms.volatile_fid = rdata->cfile->fid.volatile_fid;
32454034 io_parms.pid = rdata->pid;
32464035
3247
- server = io_parms.tcon->ses->server;
3248
-
32494036 rc = smb2_new_read_req(
32504037 (void **) &buf, &total_len, &io_parms, rdata, 0, 0);
3251
- if (rc) {
3252
- if (rc == -EAGAIN && rdata->credits) {
3253
- /* credits was reset by reconnect */
3254
- rdata->credits = 0;
3255
- /* reduce in_flight value since we won't send the req */
3256
- spin_lock(&server->req_lock);
3257
- server->in_flight--;
3258
- spin_unlock(&server->req_lock);
3259
- }
4038
+ if (rc)
32604039 return rc;
3261
- }
32624040
32634041 if (smb3_encryption_required(io_parms.tcon))
32644042 flags |= CIFS_TRANSFORM_REQ;
....@@ -3268,24 +4046,23 @@
32684046
32694047 shdr = (struct smb2_sync_hdr *)buf;
32704048
3271
- if (rdata->credits) {
4049
+ if (rdata->credits.value > 0) {
32724050 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
32734051 SMB2_MAX_BUFFER_SIZE));
3274
- shdr->CreditRequest =
3275
- cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1);
3276
- spin_lock(&server->req_lock);
3277
- server->credits += rdata->credits -
3278
- le16_to_cpu(shdr->CreditCharge);
3279
- spin_unlock(&server->req_lock);
3280
- wake_up(&server->request_q);
3281
- rdata->credits = le16_to_cpu(shdr->CreditCharge);
4052
+ shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
4053
+
4054
+ rc = adjust_credits(server, &rdata->credits, rdata->bytes);
4055
+ if (rc)
4056
+ goto async_readv_out;
4057
+
32824058 flags |= CIFS_HAS_CREDITS;
32834059 }
32844060
32854061 kref_get(&rdata->refcount);
3286
- rc = cifs_call_async(io_parms.tcon->ses->server, &rqst,
4062
+ rc = cifs_call_async(server, &rqst,
32874063 cifs_readv_receive, smb2_readv_callback,
3288
- smb3_handle_read_data, rdata, flags);
4064
+ smb3_handle_read_data, rdata, flags,
4065
+ &rdata->credits);
32894066 if (rc) {
32904067 kref_put(&rdata->refcount, cifs_readdata_release);
32914068 cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
....@@ -3295,6 +4072,7 @@
32954072 io_parms.offset, io_parms.length, rc);
32964073 }
32974074
4075
+async_readv_out:
32984076 cifs_small_buf_release(buf);
32994077 return rc;
33004078 }
....@@ -3304,7 +4082,7 @@
33044082 unsigned int *nbytes, char **buf, int *buf_type)
33054083 {
33064084 struct smb_rqst rqst;
3307
- int resp_buftype, rc = -EACCES;
4085
+ int resp_buftype, rc;
33084086 struct smb2_read_plain_req *req = NULL;
33094087 struct smb2_read_rsp *rsp = NULL;
33104088 struct kvec iov[1];
....@@ -3312,6 +4090,9 @@
33124090 unsigned int total_len;
33134091 int flags = CIFS_LOG_ERROR;
33144092 struct cifs_ses *ses = io_parms->tcon->ses;
4093
+
4094
+ if (!io_parms->server)
4095
+ io_parms->server = cifs_pick_channel(io_parms->tcon->ses);
33154096
33164097 *nbytes = 0;
33174098 rc = smb2_new_read_req((void **)&req, &total_len, io_parms, NULL, 0, 0);
....@@ -3328,7 +4109,8 @@
33284109 rqst.rq_iov = iov;
33294110 rqst.rq_nvec = 1;
33304111
3331
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
4112
+ rc = cifs_send_recv(xid, ses, io_parms->server,
4113
+ &rqst, &resp_buftype, flags, &rsp_iov);
33324114 rsp = (struct smb2_read_rsp *)rsp_iov.iov_base;
33334115
33344116 if (rc) {
....@@ -3339,7 +4121,10 @@
33394121 io_parms->tcon->tid, ses->Suid,
33404122 io_parms->offset, io_parms->length,
33414123 rc);
3342
- }
4124
+ } else
4125
+ trace_smb3_read_done(xid, req->PersistentFileId,
4126
+ io_parms->tcon->tid, ses->Suid,
4127
+ io_parms->offset, 0);
33434128 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
33444129 cifs_small_buf_release(req);
33454130 return rc == -ENODATA ? 0 : rc;
....@@ -3381,14 +4166,20 @@
33814166 {
33824167 struct cifs_writedata *wdata = mid->callback_data;
33834168 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
4169
+ struct TCP_Server_Info *server = wdata->server;
33844170 unsigned int written;
33854171 struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
3386
- unsigned int credits_received = 0;
4172
+ struct cifs_credits credits = { .value = 0, .instance = 0 };
4173
+
4174
+ WARN_ONCE(wdata->server != mid->server,
4175
+ "wdata server %p != mid server %p",
4176
+ wdata->server, mid->server);
33874177
33884178 switch (mid->mid_state) {
33894179 case MID_RESPONSE_RECEIVED:
3390
- credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest);
3391
- wdata->result = smb2_check_receive(mid, tcon->ses->server, 0);
4180
+ credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
4181
+ credits.instance = server->reconnect_instance;
4182
+ wdata->result = smb2_check_receive(mid, server, 0);
33924183 if (wdata->result != 0)
33934184 break;
33944185
....@@ -3412,8 +4203,9 @@
34124203 wdata->result = -EAGAIN;
34134204 break;
34144205 case MID_RESPONSE_MALFORMED:
3415
- credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest);
3416
- /* fall through */
4206
+ credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
4207
+ credits.instance = server->reconnect_instance;
4208
+ fallthrough;
34174209 default:
34184210 wdata->result = -EIO;
34194211 break;
....@@ -3438,8 +4230,8 @@
34384230 tcon->tid, tcon->ses->Suid, wdata->offset,
34394231 wdata->bytes, wdata->result);
34404232 if (wdata->result == -ENOSPC)
3441
- printk_once(KERN_WARNING "Out of space writing to %s\n",
3442
- tcon->treeName);
4233
+ pr_warn_once("Out of space writing to %s\n",
4234
+ tcon->treeName);
34434235 } else
34444236 trace_smb3_write_done(0 /* no xid */,
34454237 wdata->cfile->fid.persistent_fid,
....@@ -3448,7 +4240,7 @@
34484240
34494241 queue_work(cifsiod_wq, &wdata->work);
34504242 DeleteMidQEntry(mid);
3451
- add_credits(tcon->ses->server, credits_received, 0);
4243
+ add_credits(server, &credits, 0);
34524244 }
34534245
34544246 /* smb2_async_writev - send an async write, and set up mid to handle result */
....@@ -3460,23 +4252,18 @@
34604252 struct smb2_write_req *req = NULL;
34614253 struct smb2_sync_hdr *shdr;
34624254 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
3463
- struct TCP_Server_Info *server = tcon->ses->server;
4255
+ struct TCP_Server_Info *server = wdata->server;
34644256 struct kvec iov[1];
34654257 struct smb_rqst rqst = { };
34664258 unsigned int total_len;
34674259
3468
- rc = smb2_plain_req_init(SMB2_WRITE, tcon, (void **) &req, &total_len);
3469
- if (rc) {
3470
- if (rc == -EAGAIN && wdata->credits) {
3471
- /* credits was reset by reconnect */
3472
- wdata->credits = 0;
3473
- /* reduce in_flight value since we won't send the req */
3474
- spin_lock(&server->req_lock);
3475
- server->in_flight--;
3476
- spin_unlock(&server->req_lock);
3477
- }
3478
- goto async_writev_out;
3479
- }
4260
+ if (!wdata->server)
4261
+ server = wdata->server = cifs_pick_channel(tcon->ses);
4262
+
4263
+ rc = smb2_plain_req_init(SMB2_WRITE, tcon, server,
4264
+ (void **) &req, &total_len);
4265
+ if (rc)
4266
+ return rc;
34804267
34814268 if (smb3_encryption_required(tcon))
34824269 flags |= CIFS_TRANSFORM_REQ;
....@@ -3493,6 +4280,9 @@
34934280 req->DataOffset = cpu_to_le16(
34944281 offsetof(struct smb2_write_req, Buffer));
34954282 req->RemainingBytes = 0;
4283
+
4284
+ trace_smb3_write_enter(0 /* xid */, wdata->cfile->fid.persistent_fid,
4285
+ tcon->tid, tcon->ses->Suid, wdata->offset, wdata->bytes);
34964286 #ifdef CONFIG_CIFS_SMB_DIRECT
34974287 /*
34984288 * If we want to do a server RDMA read, fill in and append
....@@ -3509,7 +4299,7 @@
35094299 wdata->nr_pages, wdata->page_offset,
35104300 wdata->tailsz, false, need_invalidate);
35114301 if (!wdata->mr) {
3512
- rc = -ENOBUFS;
4302
+ rc = -EAGAIN;
35134303 goto async_writev_out;
35144304 }
35154305 req->Length = 0;
....@@ -3562,23 +4352,21 @@
35624352 req->Length = cpu_to_le32(wdata->bytes);
35634353 #endif
35644354
3565
- if (wdata->credits) {
4355
+ if (wdata->credits.value > 0) {
35664356 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
35674357 SMB2_MAX_BUFFER_SIZE));
3568
- shdr->CreditRequest =
3569
- cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 1);
3570
- spin_lock(&server->req_lock);
3571
- server->credits += wdata->credits -
3572
- le16_to_cpu(shdr->CreditCharge);
3573
- spin_unlock(&server->req_lock);
3574
- wake_up(&server->request_q);
3575
- wdata->credits = le16_to_cpu(shdr->CreditCharge);
4358
+ shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
4359
+
4360
+ rc = adjust_credits(server, &wdata->credits, wdata->bytes);
4361
+ if (rc)
4362
+ goto async_writev_out;
4363
+
35764364 flags |= CIFS_HAS_CREDITS;
35774365 }
35784366
35794367 kref_get(&wdata->refcount);
35804368 rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL,
3581
- wdata, flags);
4369
+ wdata, flags, &wdata->credits);
35824370
35834371 if (rc) {
35844372 trace_smb3_write_err(0 /* no xid */, req->PersistentFileId,
....@@ -3611,19 +4399,23 @@
36114399 struct kvec rsp_iov;
36124400 int flags = 0;
36134401 unsigned int total_len;
4402
+ struct TCP_Server_Info *server;
36144403
36154404 *nbytes = 0;
36164405
36174406 if (n_vec < 1)
36184407 return rc;
36194408
3620
- rc = smb2_plain_req_init(SMB2_WRITE, io_parms->tcon, (void **) &req,
3621
- &total_len);
4409
+ if (!io_parms->server)
4410
+ io_parms->server = cifs_pick_channel(io_parms->tcon->ses);
4411
+ server = io_parms->server;
4412
+ if (server == NULL)
4413
+ return -ECONNABORTED;
4414
+
4415
+ rc = smb2_plain_req_init(SMB2_WRITE, io_parms->tcon, server,
4416
+ (void **) &req, &total_len);
36224417 if (rc)
36234418 return rc;
3624
-
3625
- if (io_parms->tcon->ses->server == NULL)
3626
- return -ECONNABORTED;
36274419
36284420 if (smb3_encryption_required(io_parms->tcon))
36294421 flags |= CIFS_TRANSFORM_REQ;
....@@ -3641,6 +4433,10 @@
36414433 offsetof(struct smb2_write_req, Buffer));
36424434 req->RemainingBytes = 0;
36434435
4436
+ trace_smb3_write_enter(xid, io_parms->persistent_fid,
4437
+ io_parms->tcon->tid, io_parms->tcon->ses->Suid,
4438
+ io_parms->offset, io_parms->length);
4439
+
36444440 iov[0].iov_base = (char *)req;
36454441 /* 1 for Buffer */
36464442 iov[0].iov_len = total_len - 1;
....@@ -3649,7 +4445,8 @@
36494445 rqst.rq_iov = iov;
36504446 rqst.rq_nvec = n_vec + 1;
36514447
3652
- rc = cifs_send_recv(xid, io_parms->tcon->ses, &rqst,
4448
+ rc = cifs_send_recv(xid, io_parms->tcon->ses, server,
4449
+ &rqst,
36534450 &resp_buftype, flags, &rsp_iov);
36544451 rsp = (struct smb2_write_rsp *)rsp_iov.iov_base;
36554452
....@@ -3673,8 +4470,104 @@
36734470 return rc;
36744471 }
36754472
4473
+int posix_info_sid_size(const void *beg, const void *end)
4474
+{
4475
+ size_t subauth;
4476
+ int total;
4477
+
4478
+ if (beg + 1 > end)
4479
+ return -1;
4480
+
4481
+ subauth = *(u8 *)(beg+1);
4482
+ if (subauth < 1 || subauth > 15)
4483
+ return -1;
4484
+
4485
+ total = 1 + 1 + 6 + 4*subauth;
4486
+ if (beg + total > end)
4487
+ return -1;
4488
+
4489
+ return total;
4490
+}
4491
+
4492
+int posix_info_parse(const void *beg, const void *end,
4493
+ struct smb2_posix_info_parsed *out)
4494
+
4495
+{
4496
+ int total_len = 0;
4497
+ int sid_len;
4498
+ int name_len;
4499
+ const void *owner_sid;
4500
+ const void *group_sid;
4501
+ const void *name;
4502
+
4503
+ /* if no end bound given, assume payload to be correct */
4504
+ if (!end) {
4505
+ const struct smb2_posix_info *p = beg;
4506
+
4507
+ end = beg + le32_to_cpu(p->NextEntryOffset);
4508
+ /* last element will have a 0 offset, pick a sensible bound */
4509
+ if (end == beg)
4510
+ end += 0xFFFF;
4511
+ }
4512
+
4513
+ /* check base buf */
4514
+ if (beg + sizeof(struct smb2_posix_info) > end)
4515
+ return -1;
4516
+ total_len = sizeof(struct smb2_posix_info);
4517
+
4518
+ /* check owner sid */
4519
+ owner_sid = beg + total_len;
4520
+ sid_len = posix_info_sid_size(owner_sid, end);
4521
+ if (sid_len < 0)
4522
+ return -1;
4523
+ total_len += sid_len;
4524
+
4525
+ /* check group sid */
4526
+ group_sid = beg + total_len;
4527
+ sid_len = posix_info_sid_size(group_sid, end);
4528
+ if (sid_len < 0)
4529
+ return -1;
4530
+ total_len += sid_len;
4531
+
4532
+ /* check name len */
4533
+ if (beg + total_len + 4 > end)
4534
+ return -1;
4535
+ name_len = le32_to_cpu(*(__le32 *)(beg + total_len));
4536
+ if (name_len < 1 || name_len > 0xFFFF)
4537
+ return -1;
4538
+ total_len += 4;
4539
+
4540
+ /* check name */
4541
+ name = beg + total_len;
4542
+ if (name + name_len > end)
4543
+ return -1;
4544
+ total_len += name_len;
4545
+
4546
+ if (out) {
4547
+ out->base = beg;
4548
+ out->size = total_len;
4549
+ out->name_len = name_len;
4550
+ out->name = name;
4551
+ memcpy(&out->owner, owner_sid,
4552
+ posix_info_sid_size(owner_sid, end));
4553
+ memcpy(&out->group, group_sid,
4554
+ posix_info_sid_size(group_sid, end));
4555
+ }
4556
+ return total_len;
4557
+}
4558
+
4559
+static int posix_info_extra_size(const void *beg, const void *end)
4560
+{
4561
+ int len = posix_info_parse(beg, end, NULL);
4562
+
4563
+ if (len < 0)
4564
+ return -1;
4565
+ return len - sizeof(struct smb2_posix_info);
4566
+}
4567
+
36764568 static unsigned int
3677
-num_entries(char *bufstart, char *end_of_buf, char **lastentry, size_t size)
4569
+num_entries(int infotype, char *bufstart, char *end_of_buf, char **lastentry,
4570
+ size_t size)
36784571 {
36794572 int len;
36804573 unsigned int entrycount = 0;
....@@ -3698,8 +4591,13 @@
36984591 entryptr = entryptr + next_offset;
36994592 dir_info = (FILE_DIRECTORY_INFO *)entryptr;
37004593
3701
- len = le32_to_cpu(dir_info->FileNameLength);
3702
- if (entryptr + len < entryptr ||
4594
+ if (infotype == SMB_FIND_FILE_POSIX_INFO)
4595
+ len = posix_info_extra_size(entryptr, end_of_buf);
4596
+ else
4597
+ len = le32_to_cpu(dir_info->FileNameLength);
4598
+
4599
+ if (len < 0 ||
4600
+ entryptr + len < entryptr ||
37034601 entryptr + len > end_of_buf ||
37044602 entryptr + len + size > end_of_buf) {
37054603 cifs_dbg(VFS, "directory entry name would overflow frame end of buf %p\n",
....@@ -3721,56 +4619,42 @@
37214619 /*
37224620 * Readdir/FindFirst
37234621 */
3724
-int
3725
-SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
3726
- u64 persistent_fid, u64 volatile_fid, int index,
3727
- struct cifs_search_info *srch_inf)
4622
+int SMB2_query_directory_init(const unsigned int xid,
4623
+ struct cifs_tcon *tcon,
4624
+ struct TCP_Server_Info *server,
4625
+ struct smb_rqst *rqst,
4626
+ u64 persistent_fid, u64 volatile_fid,
4627
+ int index, int info_level)
37284628 {
3729
- struct smb_rqst rqst;
37304629 struct smb2_query_directory_req *req;
3731
- struct smb2_query_directory_rsp *rsp = NULL;
3732
- struct kvec iov[2];
3733
- struct kvec rsp_iov;
3734
- int rc = 0;
3735
- int len;
3736
- int resp_buftype = CIFS_NO_BUFFER;
37374630 unsigned char *bufptr;
3738
- struct TCP_Server_Info *server;
3739
- struct cifs_ses *ses = tcon->ses;
37404631 __le16 asteriks = cpu_to_le16('*');
3741
- char *end_of_smb;
3742
- unsigned int output_size = CIFSMaxBufSize;
3743
- size_t info_buf_size;
3744
- int flags = 0;
4632
+ unsigned int output_size = CIFSMaxBufSize -
4633
+ MAX_SMB2_CREATE_RESPONSE_SIZE -
4634
+ MAX_SMB2_CLOSE_RESPONSE_SIZE;
37454635 unsigned int total_len;
4636
+ struct kvec *iov = rqst->rq_iov;
4637
+ int len, rc;
37464638
3747
- if (ses && (ses->server))
3748
- server = ses->server;
3749
- else
3750
- return -EIO;
3751
-
3752
- rc = smb2_plain_req_init(SMB2_QUERY_DIRECTORY, tcon, (void **) &req,
3753
- &total_len);
4639
+ rc = smb2_plain_req_init(SMB2_QUERY_DIRECTORY, tcon, server,
4640
+ (void **) &req, &total_len);
37544641 if (rc)
37554642 return rc;
37564643
3757
- if (smb3_encryption_required(tcon))
3758
- flags |= CIFS_TRANSFORM_REQ;
3759
-
3760
- switch (srch_inf->info_level) {
4644
+ switch (info_level) {
37614645 case SMB_FIND_FILE_DIRECTORY_INFO:
37624646 req->FileInformationClass = FILE_DIRECTORY_INFORMATION;
3763
- info_buf_size = sizeof(FILE_DIRECTORY_INFO) - 1;
37644647 break;
37654648 case SMB_FIND_FILE_ID_FULL_DIR_INFO:
37664649 req->FileInformationClass = FILEID_FULL_DIRECTORY_INFORMATION;
3767
- info_buf_size = sizeof(SEARCH_ID_FULL_DIR_INFO) - 1;
4650
+ break;
4651
+ case SMB_FIND_FILE_POSIX_INFO:
4652
+ req->FileInformationClass = SMB_FIND_FILE_POSIX_INFO;
37684653 break;
37694654 default:
3770
- cifs_dbg(VFS, "info level %u isn't supported\n",
3771
- srch_inf->info_level);
3772
- rc = -EINVAL;
3773
- goto qdir_exit;
4655
+ cifs_tcon_dbg(VFS, "info level %u isn't supported\n",
4656
+ info_level);
4657
+ return -EINVAL;
37744658 }
37754659
37764660 req->FileIndex = cpu_to_le32(index);
....@@ -3799,29 +4683,56 @@
37994683 iov[1].iov_base = (char *)(req->Buffer);
38004684 iov[1].iov_len = len;
38014685
3802
- memset(&rqst, 0, sizeof(struct smb_rqst));
3803
- rqst.rq_iov = iov;
3804
- rqst.rq_nvec = 2;
4686
+ trace_smb3_query_dir_enter(xid, persistent_fid, tcon->tid,
4687
+ tcon->ses->Suid, index, output_size);
38054688
3806
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
3807
- cifs_small_buf_release(req);
3808
- rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base;
4689
+ return 0;
4690
+}
38094691
3810
- if (rc) {
3811
- if (rc == -ENODATA &&
3812
- rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
3813
- srch_inf->endOfSearch = true;
3814
- rc = 0;
3815
- } else
3816
- cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE);
3817
- goto qdir_exit;
4692
+void SMB2_query_directory_free(struct smb_rqst *rqst)
4693
+{
4694
+ if (rqst && rqst->rq_iov) {
4695
+ cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
4696
+ }
4697
+}
4698
+
4699
+int
4700
+smb2_parse_query_directory(struct cifs_tcon *tcon,
4701
+ struct kvec *rsp_iov,
4702
+ int resp_buftype,
4703
+ struct cifs_search_info *srch_inf)
4704
+{
4705
+ struct smb2_query_directory_rsp *rsp;
4706
+ size_t info_buf_size;
4707
+ char *end_of_smb;
4708
+ int rc;
4709
+
4710
+ rsp = (struct smb2_query_directory_rsp *)rsp_iov->iov_base;
4711
+
4712
+ switch (srch_inf->info_level) {
4713
+ case SMB_FIND_FILE_DIRECTORY_INFO:
4714
+ info_buf_size = sizeof(FILE_DIRECTORY_INFO) - 1;
4715
+ break;
4716
+ case SMB_FIND_FILE_ID_FULL_DIR_INFO:
4717
+ info_buf_size = sizeof(SEARCH_ID_FULL_DIR_INFO) - 1;
4718
+ break;
4719
+ case SMB_FIND_FILE_POSIX_INFO:
4720
+ /* note that posix payload are variable size */
4721
+ info_buf_size = sizeof(struct smb2_posix_info);
4722
+ break;
4723
+ default:
4724
+ cifs_tcon_dbg(VFS, "info level %u isn't supported\n",
4725
+ srch_inf->info_level);
4726
+ return -EINVAL;
38184727 }
38194728
38204729 rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset),
3821
- le32_to_cpu(rsp->OutputBufferLength), &rsp_iov,
4730
+ le32_to_cpu(rsp->OutputBufferLength), rsp_iov,
38224731 info_buf_size);
3823
- if (rc)
3824
- goto qdir_exit;
4732
+ if (rc) {
4733
+ cifs_tcon_dbg(VFS, "bad info payload");
4734
+ return rc;
4735
+ }
38254736
38264737 srch_inf->unicode = true;
38274738
....@@ -3834,10 +4745,15 @@
38344745 srch_inf->ntwrk_buf_start = (char *)rsp;
38354746 srch_inf->srch_entries_start = srch_inf->last_entry =
38364747 (char *)rsp + le16_to_cpu(rsp->OutputBufferOffset);
3837
- end_of_smb = rsp_iov.iov_len + (char *)rsp;
3838
- srch_inf->entries_in_buffer =
3839
- num_entries(srch_inf->srch_entries_start, end_of_smb,
3840
- &srch_inf->last_entry, info_buf_size);
4748
+ end_of_smb = rsp_iov->iov_len + (char *)rsp;
4749
+
4750
+ srch_inf->entries_in_buffer = num_entries(
4751
+ srch_inf->info_level,
4752
+ srch_inf->srch_entries_start,
4753
+ end_of_smb,
4754
+ &srch_inf->last_entry,
4755
+ info_buf_size);
4756
+
38414757 srch_inf->index_of_last_entry += srch_inf->entries_in_buffer;
38424758 cifs_dbg(FYI, "num entries %d last_index %lld srch start %p srch end %p\n",
38434759 srch_inf->entries_in_buffer, srch_inf->index_of_last_entry,
....@@ -3847,54 +4763,99 @@
38474763 else if (resp_buftype == CIFS_SMALL_BUFFER)
38484764 srch_inf->smallBuf = true;
38494765 else
3850
- cifs_dbg(VFS, "illegal search buffer type\n");
4766
+ cifs_tcon_dbg(VFS, "Invalid search buffer type\n");
38514767
3852
- return rc;
3853
-
3854
-qdir_exit:
3855
- free_rsp_buf(resp_buftype, rsp);
3856
- return rc;
4768
+ return 0;
38574769 }
38584770
3859
-static int
3860
-send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
3861
- u64 persistent_fid, u64 volatile_fid, u32 pid, u8 info_class,
3862
- u8 info_type, u32 additional_info, unsigned int num,
3863
- void **data, unsigned int *size)
4771
+int
4772
+SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
4773
+ u64 persistent_fid, u64 volatile_fid, int index,
4774
+ struct cifs_search_info *srch_inf)
38644775 {
38654776 struct smb_rqst rqst;
3866
- struct smb2_set_info_req *req;
3867
- struct smb2_set_info_rsp *rsp = NULL;
3868
- struct kvec *iov;
4777
+ struct kvec iov[SMB2_QUERY_DIRECTORY_IOV_SIZE];
4778
+ struct smb2_query_directory_rsp *rsp = NULL;
4779
+ int resp_buftype = CIFS_NO_BUFFER;
38694780 struct kvec rsp_iov;
38704781 int rc = 0;
3871
- int resp_buftype;
3872
- unsigned int i;
38734782 struct cifs_ses *ses = tcon->ses;
4783
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
38744784 int flags = 0;
3875
- unsigned int total_len;
38764785
38774786 if (!ses || !(ses->server))
38784787 return -EIO;
38794788
3880
- if (!num)
3881
- return -EINVAL;
3882
-
3883
- iov = kmalloc_array(num, sizeof(struct kvec), GFP_KERNEL);
3884
- if (!iov)
3885
- return -ENOMEM;
3886
-
3887
- rc = smb2_plain_req_init(SMB2_SET_INFO, tcon, (void **) &req, &total_len);
3888
- if (rc) {
3889
- kfree(iov);
3890
- return rc;
3891
- }
3892
-
38934789 if (smb3_encryption_required(tcon))
38944790 flags |= CIFS_TRANSFORM_REQ;
38954791
3896
- req->sync_hdr.ProcessId = cpu_to_le32(pid);
4792
+ memset(&rqst, 0, sizeof(struct smb_rqst));
4793
+ memset(&iov, 0, sizeof(iov));
4794
+ rqst.rq_iov = iov;
4795
+ rqst.rq_nvec = SMB2_QUERY_DIRECTORY_IOV_SIZE;
38974796
4797
+ rc = SMB2_query_directory_init(xid, tcon, server,
4798
+ &rqst, persistent_fid,
4799
+ volatile_fid, index,
4800
+ srch_inf->info_level);
4801
+ if (rc)
4802
+ goto qdir_exit;
4803
+
4804
+ rc = cifs_send_recv(xid, ses, server,
4805
+ &rqst, &resp_buftype, flags, &rsp_iov);
4806
+ rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base;
4807
+
4808
+ if (rc) {
4809
+ if (rc == -ENODATA &&
4810
+ rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
4811
+ trace_smb3_query_dir_done(xid, persistent_fid,
4812
+ tcon->tid, tcon->ses->Suid, index, 0);
4813
+ srch_inf->endOfSearch = true;
4814
+ rc = 0;
4815
+ } else {
4816
+ trace_smb3_query_dir_err(xid, persistent_fid, tcon->tid,
4817
+ tcon->ses->Suid, index, 0, rc);
4818
+ cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE);
4819
+ }
4820
+ goto qdir_exit;
4821
+ }
4822
+
4823
+ rc = smb2_parse_query_directory(tcon, &rsp_iov, resp_buftype,
4824
+ srch_inf);
4825
+ if (rc) {
4826
+ trace_smb3_query_dir_err(xid, persistent_fid, tcon->tid,
4827
+ tcon->ses->Suid, index, 0, rc);
4828
+ goto qdir_exit;
4829
+ }
4830
+ resp_buftype = CIFS_NO_BUFFER;
4831
+
4832
+ trace_smb3_query_dir_done(xid, persistent_fid, tcon->tid,
4833
+ tcon->ses->Suid, index, srch_inf->entries_in_buffer);
4834
+
4835
+qdir_exit:
4836
+ SMB2_query_directory_free(&rqst);
4837
+ free_rsp_buf(resp_buftype, rsp);
4838
+ return rc;
4839
+}
4840
+
4841
+int
4842
+SMB2_set_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
4843
+ struct smb_rqst *rqst,
4844
+ u64 persistent_fid, u64 volatile_fid, u32 pid,
4845
+ u8 info_class, u8 info_type, u32 additional_info,
4846
+ void **data, unsigned int *size)
4847
+{
4848
+ struct smb2_set_info_req *req;
4849
+ struct kvec *iov = rqst->rq_iov;
4850
+ unsigned int i, total_len;
4851
+ int rc;
4852
+
4853
+ rc = smb2_plain_req_init(SMB2_SET_INFO, tcon, server,
4854
+ (void **) &req, &total_len);
4855
+ if (rc)
4856
+ return rc;
4857
+
4858
+ req->sync_hdr.ProcessId = cpu_to_le32(pid);
38984859 req->InfoType = info_type;
38994860 req->FileInfoClass = info_class;
39004861 req->PersistentFileId = persistent_fid;
....@@ -3912,19 +4873,69 @@
39124873 /* 1 for Buffer */
39134874 iov[0].iov_len = total_len - 1;
39144875
3915
- for (i = 1; i < num; i++) {
4876
+ for (i = 1; i < rqst->rq_nvec; i++) {
39164877 le32_add_cpu(&req->BufferLength, size[i]);
39174878 iov[i].iov_base = (char *)data[i];
39184879 iov[i].iov_len = size[i];
39194880 }
39204881
4882
+ return 0;
4883
+}
4884
+
4885
+void
4886
+SMB2_set_info_free(struct smb_rqst *rqst)
4887
+{
4888
+ if (rqst && rqst->rq_iov)
4889
+ cifs_buf_release(rqst->rq_iov[0].iov_base); /* request */
4890
+}
4891
+
4892
+static int
4893
+send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
4894
+ u64 persistent_fid, u64 volatile_fid, u32 pid, u8 info_class,
4895
+ u8 info_type, u32 additional_info, unsigned int num,
4896
+ void **data, unsigned int *size)
4897
+{
4898
+ struct smb_rqst rqst;
4899
+ struct smb2_set_info_rsp *rsp = NULL;
4900
+ struct kvec *iov;
4901
+ struct kvec rsp_iov;
4902
+ int rc = 0;
4903
+ int resp_buftype;
4904
+ struct cifs_ses *ses = tcon->ses;
4905
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
4906
+ int flags = 0;
4907
+
4908
+ if (!ses || !server)
4909
+ return -EIO;
4910
+
4911
+ if (!num)
4912
+ return -EINVAL;
4913
+
4914
+ if (smb3_encryption_required(tcon))
4915
+ flags |= CIFS_TRANSFORM_REQ;
4916
+
4917
+ iov = kmalloc_array(num, sizeof(struct kvec), GFP_KERNEL);
4918
+ if (!iov)
4919
+ return -ENOMEM;
4920
+
39214921 memset(&rqst, 0, sizeof(struct smb_rqst));
39224922 rqst.rq_iov = iov;
39234923 rqst.rq_nvec = num;
39244924
3925
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
4925
+ rc = SMB2_set_info_init(tcon, server,
4926
+ &rqst, persistent_fid, volatile_fid, pid,
4927
+ info_class, info_type, additional_info,
4928
+ data, size);
4929
+ if (rc) {
4930
+ kfree(iov);
4931
+ return rc;
4932
+ }
4933
+
4934
+
4935
+ rc = cifs_send_recv(xid, ses, server,
4936
+ &rqst, &resp_buftype, flags,
39264937 &rsp_iov);
3927
- cifs_buf_release(req);
4938
+ SMB2_set_info_free(&rqst);
39284939 rsp = (struct smb2_set_info_rsp *)rsp_iov.iov_base;
39294940
39304941 if (rc != 0) {
....@@ -3939,88 +4950,8 @@
39394950 }
39404951
39414952 int
3942
-SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon,
3943
- u64 persistent_fid, u64 volatile_fid, __le16 *target_file)
3944
-{
3945
- struct smb2_file_rename_info info;
3946
- void **data;
3947
- unsigned int size[2];
3948
- int rc;
3949
- int len = (2 * UniStrnlen((wchar_t *)target_file, PATH_MAX));
3950
-
3951
- data = kmalloc_array(2, sizeof(void *), GFP_KERNEL);
3952
- if (!data)
3953
- return -ENOMEM;
3954
-
3955
- info.ReplaceIfExists = 1; /* 1 = replace existing target with new */
3956
- /* 0 = fail if target already exists */
3957
- info.RootDirectory = 0; /* MBZ for network ops (why does spec say?) */
3958
- info.FileNameLength = cpu_to_le32(len);
3959
-
3960
- data[0] = &info;
3961
- size[0] = sizeof(struct smb2_file_rename_info);
3962
-
3963
- data[1] = target_file;
3964
- size[1] = len + 2 /* null */;
3965
-
3966
- rc = send_set_info(xid, tcon, persistent_fid, volatile_fid,
3967
- current->tgid, FILE_RENAME_INFORMATION, SMB2_O_INFO_FILE,
3968
- 0, 2, data, size);
3969
- kfree(data);
3970
- return rc;
3971
-}
3972
-
3973
-int
3974
-SMB2_rmdir(const unsigned int xid, struct cifs_tcon *tcon,
3975
- u64 persistent_fid, u64 volatile_fid)
3976
-{
3977
- __u8 delete_pending = 1;
3978
- void *data;
3979
- unsigned int size;
3980
-
3981
- data = &delete_pending;
3982
- size = 1; /* sizeof __u8 */
3983
-
3984
- return send_set_info(xid, tcon, persistent_fid, volatile_fid,
3985
- current->tgid, FILE_DISPOSITION_INFORMATION, SMB2_O_INFO_FILE,
3986
- 0, 1, &data, &size);
3987
-}
3988
-
3989
-int
3990
-SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
3991
- u64 persistent_fid, u64 volatile_fid, __le16 *target_file)
3992
-{
3993
- struct smb2_file_link_info info;
3994
- void **data;
3995
- unsigned int size[2];
3996
- int rc;
3997
- int len = (2 * UniStrnlen((wchar_t *)target_file, PATH_MAX));
3998
-
3999
- data = kmalloc_array(2, sizeof(void *), GFP_KERNEL);
4000
- if (!data)
4001
- return -ENOMEM;
4002
-
4003
- info.ReplaceIfExists = 0; /* 1 = replace existing link with new */
4004
- /* 0 = fail if link already exists */
4005
- info.RootDirectory = 0; /* MBZ for network ops (why does spec say?) */
4006
- info.FileNameLength = cpu_to_le32(len);
4007
-
4008
- data[0] = &info;
4009
- size[0] = sizeof(struct smb2_file_link_info);
4010
-
4011
- data[1] = target_file;
4012
- size[1] = len + 2 /* null */;
4013
-
4014
- rc = send_set_info(xid, tcon, persistent_fid, volatile_fid,
4015
- current->tgid, FILE_LINK_INFORMATION, SMB2_O_INFO_FILE,
4016
- 0, 2, data, size);
4017
- kfree(data);
4018
- return rc;
4019
-}
4020
-
4021
-int
40224953 SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
4023
- u64 volatile_fid, u32 pid, __le64 *eof, bool is_falloc)
4954
+ u64 volatile_fid, u32 pid, __le64 *eof)
40244955 {
40254956 struct smb2_file_eof_info info;
40264957 void *data;
....@@ -4031,25 +4962,9 @@
40314962 data = &info;
40324963 size = sizeof(struct smb2_file_eof_info);
40334964
4034
- if (is_falloc)
4035
- return send_set_info(xid, tcon, persistent_fid, volatile_fid,
4036
- pid, FILE_ALLOCATION_INFORMATION, SMB2_O_INFO_FILE,
4037
- 0, 1, &data, &size);
4038
- else
4039
- return send_set_info(xid, tcon, persistent_fid, volatile_fid,
4965
+ return send_set_info(xid, tcon, persistent_fid, volatile_fid,
40404966 pid, FILE_END_OF_FILE_INFORMATION, SMB2_O_INFO_FILE,
40414967 0, 1, &data, &size);
4042
-}
4043
-
4044
-int
4045
-SMB2_set_info(const unsigned int xid, struct cifs_tcon *tcon,
4046
- u64 persistent_fid, u64 volatile_fid, FILE_BASIC_INFO *buf)
4047
-{
4048
- unsigned int size;
4049
- size = sizeof(FILE_BASIC_INFO);
4050
- return send_set_info(xid, tcon, persistent_fid, volatile_fid,
4051
- current->tgid, FILE_BASIC_INFORMATION, SMB2_O_INFO_FILE,
4052
- 0, 1, (void **)&buf, &size);
40534968 }
40544969
40554970 int
....@@ -4081,6 +4996,7 @@
40814996 int rc;
40824997 struct smb2_oplock_break *req = NULL;
40834998 struct cifs_ses *ses = tcon->ses;
4999
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
40845000 int flags = CIFS_OBREAK_OP;
40855001 unsigned int total_len;
40865002 struct kvec iov[1];
....@@ -4088,8 +5004,8 @@
40885004 int resp_buf_type;
40895005
40905006 cifs_dbg(FYI, "SMB2_oplock_break\n");
4091
- rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req,
4092
- &total_len);
5007
+ rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, server,
5008
+ (void **) &req, &total_len);
40935009 if (rc)
40945010 return rc;
40955011
....@@ -4101,7 +5017,7 @@
41015017 req->OplockLevel = oplock_level;
41025018 req->sync_hdr.CreditRequest = cpu_to_le16(1);
41035019
4104
- flags |= CIFS_NO_RESP;
5020
+ flags |= CIFS_NO_RSP_BUF;
41055021
41065022 iov[0].iov_base = (char *)req;
41075023 iov[0].iov_len = total_len;
....@@ -4110,7 +5026,8 @@
41105026 rqst.rq_iov = iov;
41115027 rqst.rq_nvec = 1;
41125028
4113
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
5029
+ rc = cifs_send_recv(xid, ses, server,
5030
+ &rqst, &resp_buf_type, flags, &rsp_iov);
41145031 cifs_small_buf_release(req);
41155032
41165033 if (rc) {
....@@ -4153,23 +5070,22 @@
41535070 }
41545071
41555072 static int
4156
-build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon, int level,
4157
- int outbuf_len, u64 persistent_fid, u64 volatile_fid)
5073
+build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon,
5074
+ struct TCP_Server_Info *server,
5075
+ int level, int outbuf_len, u64 persistent_fid,
5076
+ u64 volatile_fid)
41585077 {
4159
- struct TCP_Server_Info *server;
41605078 int rc;
41615079 struct smb2_query_info_req *req;
41625080 unsigned int total_len;
41635081
41645082 cifs_dbg(FYI, "Query FSInfo level %d\n", level);
41655083
4166
- if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
5084
+ if ((tcon->ses == NULL) || server == NULL)
41675085 return -EIO;
41685086
4169
- server = tcon->ses->server;
4170
-
4171
- rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, (void **) &req,
4172
- &total_len);
5087
+ rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server,
5088
+ (void **) &req, &total_len);
41735089 if (rc)
41745090 return rc;
41755091
....@@ -4199,10 +5115,12 @@
41995115 int rc = 0;
42005116 int resp_buftype;
42015117 struct cifs_ses *ses = tcon->ses;
5118
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
42025119 FILE_SYSTEM_POSIX_INFO *info = NULL;
42035120 int flags = 0;
42045121
4205
- rc = build_qfs_info_req(&iov, tcon, FS_POSIX_INFORMATION,
5122
+ rc = build_qfs_info_req(&iov, tcon, server,
5123
+ FS_POSIX_INFORMATION,
42065124 sizeof(FILE_SYSTEM_POSIX_INFO),
42075125 persistent_fid, volatile_fid);
42085126 if (rc)
....@@ -4215,7 +5133,8 @@
42155133 rqst.rq_iov = &iov;
42165134 rqst.rq_nvec = 1;
42175135
4218
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
5136
+ rc = cifs_send_recv(xid, ses, server,
5137
+ &rqst, &resp_buftype, flags, &rsp_iov);
42195138 cifs_small_buf_release(iov.iov_base);
42205139 if (rc) {
42215140 cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
....@@ -4247,10 +5166,12 @@
42475166 int rc = 0;
42485167 int resp_buftype;
42495168 struct cifs_ses *ses = tcon->ses;
5169
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
42505170 struct smb2_fs_full_size_info *info = NULL;
42515171 int flags = 0;
42525172
4253
- rc = build_qfs_info_req(&iov, tcon, FS_FULL_SIZE_INFORMATION,
5173
+ rc = build_qfs_info_req(&iov, tcon, server,
5174
+ FS_FULL_SIZE_INFORMATION,
42545175 sizeof(struct smb2_fs_full_size_info),
42555176 persistent_fid, volatile_fid);
42565177 if (rc)
....@@ -4263,7 +5184,8 @@
42635184 rqst.rq_iov = &iov;
42645185 rqst.rq_nvec = 1;
42655186
4266
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
5187
+ rc = cifs_send_recv(xid, ses, server,
5188
+ &rqst, &resp_buftype, flags, &rsp_iov);
42675189 cifs_small_buf_release(iov.iov_base);
42685190 if (rc) {
42695191 cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
....@@ -4295,6 +5217,7 @@
42955217 int rc = 0;
42965218 int resp_buftype, max_len, min_len;
42975219 struct cifs_ses *ses = tcon->ses;
5220
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
42985221 unsigned int rsp_len, offset;
42995222 int flags = 0;
43005223
....@@ -4315,7 +5238,8 @@
43155238 return -EINVAL;
43165239 }
43175240
4318
- rc = build_qfs_info_req(&iov, tcon, level, max_len,
5241
+ rc = build_qfs_info_req(&iov, tcon, server,
5242
+ level, max_len,
43195243 persistent_fid, volatile_fid);
43205244 if (rc)
43215245 return rc;
....@@ -4327,7 +5251,8 @@
43275251 rqst.rq_iov = &iov;
43285252 rqst.rq_nvec = 1;
43295253
4330
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
5254
+ rc = cifs_send_recv(xid, ses, server,
5255
+ &rqst, &resp_buftype, flags, &rsp_iov);
43315256 cifs_small_buf_release(iov.iov_base);
43325257 if (rc) {
43335258 cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
....@@ -4378,12 +5303,14 @@
43785303 struct kvec rsp_iov;
43795304 int resp_buf_type;
43805305 unsigned int count;
4381
- int flags = CIFS_NO_RESP;
5306
+ int flags = CIFS_NO_RSP_BUF;
43825307 unsigned int total_len;
5308
+ struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
43835309
43845310 cifs_dbg(FYI, "smb2_lockv num lock %d\n", num_lock);
43855311
4386
- rc = smb2_plain_req_init(SMB2_LOCK, tcon, (void **) &req, &total_len);
5312
+ rc = smb2_plain_req_init(SMB2_LOCK, tcon, server,
5313
+ (void **) &req, &total_len);
43875314 if (rc)
43885315 return rc;
43895316
....@@ -4409,7 +5336,8 @@
44095336 rqst.rq_iov = iov;
44105337 rqst.rq_nvec = 2;
44115338
4412
- rc = cifs_send_recv(xid, tcon->ses, &rqst, &resp_buf_type, flags,
5339
+ rc = cifs_send_recv(xid, tcon->ses, server,
5340
+ &rqst, &resp_buf_type, flags,
44135341 &rsp_iov);
44145342 cifs_small_buf_release(req);
44155343 if (rc) {
....@@ -4452,10 +5380,13 @@
44525380 struct kvec iov[1];
44535381 struct kvec rsp_iov;
44545382 int resp_buf_type;
5383
+ __u64 *please_key_high;
5384
+ __u64 *please_key_low;
5385
+ struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
44555386
44565387 cifs_dbg(FYI, "SMB2_lease_break\n");
4457
- rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req,
4458
- &total_len);
5388
+ rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, server,
5389
+ (void **) &req, &total_len);
44595390 if (rc)
44605391 return rc;
44615392
....@@ -4469,7 +5400,7 @@
44695400 memcpy(req->LeaseKey, lease_key, 16);
44705401 req->LeaseState = lease_state;
44715402
4472
- flags |= CIFS_NO_RESP;
5403
+ flags |= CIFS_NO_RSP_BUF;
44735404
44745405 iov[0].iov_base = (char *)req;
44755406 iov[0].iov_len = total_len;
....@@ -4478,13 +5409,20 @@
44785409 rqst.rq_iov = iov;
44795410 rqst.rq_nvec = 1;
44805411
4481
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
5412
+ rc = cifs_send_recv(xid, ses, server,
5413
+ &rqst, &resp_buf_type, flags, &rsp_iov);
44825414 cifs_small_buf_release(req);
44835415
5416
+ please_key_low = (__u64 *)lease_key;
5417
+ please_key_high = (__u64 *)(lease_key+8);
44845418 if (rc) {
44855419 cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE);
5420
+ trace_smb3_lease_err(le32_to_cpu(lease_state), tcon->tid,
5421
+ ses->Suid, *please_key_low, *please_key_high, rc);
44865422 cifs_dbg(FYI, "Send error in Lease Break = %d\n", rc);
4487
- }
5423
+ } else
5424
+ trace_smb3_lease_done(le32_to_cpu(lease_state), tcon->tid,
5425
+ ses->Suid, *please_key_low, *please_key_high);
44885426
44895427 return rc;
44905428 }