forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
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,10 +3920,10 @@
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],
31523928 .rq_nvec = 1,
31533929 .rq_pages = rdata->pages,
....@@ -3156,20 +3932,25 @@
31563932 .rq_pagesz = rdata->pagesz,
31573933 .rq_tailsz = rdata->tailsz };
31583934
3935
+ WARN_ONCE(rdata->server != mid->server,
3936
+ "rdata server %p != mid server %p",
3937
+ rdata->server, mid->server);
3938
+
31593939 cifs_dbg(FYI, "%s: mid=%llu state=%d result=%d bytes=%u\n",
31603940 __func__, mid->mid, mid->mid_state, rdata->result,
31613941 rdata->bytes);
31623942
31633943 switch (mid->mid_state) {
31643944 case MID_RESPONSE_RECEIVED:
3165
- credits_received = le16_to_cpu(shdr->CreditRequest);
3945
+ credits.value = le16_to_cpu(shdr->CreditRequest);
3946
+ credits.instance = server->reconnect_instance;
31663947 /* result already set, check signature */
31673948 if (server->sign && !mid->decrypted) {
31683949 int rc;
31693950
31703951 rc = smb2_verify_signature(&rqst, server);
31713952 if (rc)
3172
- cifs_dbg(VFS, "SMB signature verification returned error = %d\n",
3953
+ cifs_tcon_dbg(VFS, "SMB signature verification returned error = %d\n",
31733954 rc);
31743955 }
31753956 /* FIXME: should this be counted toward the initiating task? */
....@@ -3187,11 +3968,11 @@
31873968 cifs_stats_bytes_read(tcon, rdata->got_bytes);
31883969 break;
31893970 case MID_RESPONSE_MALFORMED:
3190
- credits_received = le16_to_cpu(shdr->CreditRequest);
3191
- /* fall through */
3971
+ credits.value = le16_to_cpu(shdr->CreditRequest);
3972
+ credits.instance = server->reconnect_instance;
3973
+ fallthrough;
31923974 default:
3193
- if (rdata->result != -ENODATA)
3194
- rdata->result = -EIO;
3975
+ rdata->result = -EIO;
31953976 }
31963977 #ifdef CONFIG_CIFS_SMB_DIRECT
31973978 /*
....@@ -3218,7 +3999,7 @@
32183999
32194000 queue_work(cifsiod_wq, &rdata->work);
32204001 DeleteMidQEntry(mid);
3221
- add_credits(server, credits_received, 0);
4002
+ add_credits(server, &credits, 0);
32224003 }
32234004
32244005 /* smb2_async_readv - send an async read, and set up mid to handle result */
....@@ -3232,33 +4013,27 @@
32324013 struct smb_rqst rqst = { .rq_iov = rdata->iov,
32334014 .rq_nvec = 1 };
32344015 struct TCP_Server_Info *server;
4016
+ struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
32354017 unsigned int total_len;
32364018
32374019 cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
32384020 __func__, rdata->offset, rdata->bytes);
32394021
4022
+ if (!rdata->server)
4023
+ rdata->server = cifs_pick_channel(tcon->ses);
4024
+
32404025 io_parms.tcon = tlink_tcon(rdata->cfile->tlink);
4026
+ io_parms.server = server = rdata->server;
32414027 io_parms.offset = rdata->offset;
32424028 io_parms.length = rdata->bytes;
32434029 io_parms.persistent_fid = rdata->cfile->fid.persistent_fid;
32444030 io_parms.volatile_fid = rdata->cfile->fid.volatile_fid;
32454031 io_parms.pid = rdata->pid;
32464032
3247
- server = io_parms.tcon->ses->server;
3248
-
32494033 rc = smb2_new_read_req(
32504034 (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
- }
4035
+ if (rc)
32604036 return rc;
3261
- }
32624037
32634038 if (smb3_encryption_required(io_parms.tcon))
32644039 flags |= CIFS_TRANSFORM_REQ;
....@@ -3268,24 +4043,23 @@
32684043
32694044 shdr = (struct smb2_sync_hdr *)buf;
32704045
3271
- if (rdata->credits) {
4046
+ if (rdata->credits.value > 0) {
32724047 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
32734048 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);
4049
+ shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
4050
+
4051
+ rc = adjust_credits(server, &rdata->credits, rdata->bytes);
4052
+ if (rc)
4053
+ goto async_readv_out;
4054
+
32824055 flags |= CIFS_HAS_CREDITS;
32834056 }
32844057
32854058 kref_get(&rdata->refcount);
3286
- rc = cifs_call_async(io_parms.tcon->ses->server, &rqst,
4059
+ rc = cifs_call_async(server, &rqst,
32874060 cifs_readv_receive, smb2_readv_callback,
3288
- smb3_handle_read_data, rdata, flags);
4061
+ smb3_handle_read_data, rdata, flags,
4062
+ &rdata->credits);
32894063 if (rc) {
32904064 kref_put(&rdata->refcount, cifs_readdata_release);
32914065 cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
....@@ -3295,6 +4069,7 @@
32954069 io_parms.offset, io_parms.length, rc);
32964070 }
32974071
4072
+async_readv_out:
32984073 cifs_small_buf_release(buf);
32994074 return rc;
33004075 }
....@@ -3304,7 +4079,7 @@
33044079 unsigned int *nbytes, char **buf, int *buf_type)
33054080 {
33064081 struct smb_rqst rqst;
3307
- int resp_buftype, rc = -EACCES;
4082
+ int resp_buftype, rc;
33084083 struct smb2_read_plain_req *req = NULL;
33094084 struct smb2_read_rsp *rsp = NULL;
33104085 struct kvec iov[1];
....@@ -3312,6 +4087,9 @@
33124087 unsigned int total_len;
33134088 int flags = CIFS_LOG_ERROR;
33144089 struct cifs_ses *ses = io_parms->tcon->ses;
4090
+
4091
+ if (!io_parms->server)
4092
+ io_parms->server = cifs_pick_channel(io_parms->tcon->ses);
33154093
33164094 *nbytes = 0;
33174095 rc = smb2_new_read_req((void **)&req, &total_len, io_parms, NULL, 0, 0);
....@@ -3328,7 +4106,8 @@
33284106 rqst.rq_iov = iov;
33294107 rqst.rq_nvec = 1;
33304108
3331
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
4109
+ rc = cifs_send_recv(xid, ses, io_parms->server,
4110
+ &rqst, &resp_buftype, flags, &rsp_iov);
33324111 rsp = (struct smb2_read_rsp *)rsp_iov.iov_base;
33334112
33344113 if (rc) {
....@@ -3339,7 +4118,10 @@
33394118 io_parms->tcon->tid, ses->Suid,
33404119 io_parms->offset, io_parms->length,
33414120 rc);
3342
- }
4121
+ } else
4122
+ trace_smb3_read_done(xid, req->PersistentFileId,
4123
+ io_parms->tcon->tid, ses->Suid,
4124
+ io_parms->offset, 0);
33434125 free_rsp_buf(resp_buftype, rsp_iov.iov_base);
33444126 cifs_small_buf_release(req);
33454127 return rc == -ENODATA ? 0 : rc;
....@@ -3381,14 +4163,20 @@
33814163 {
33824164 struct cifs_writedata *wdata = mid->callback_data;
33834165 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
4166
+ struct TCP_Server_Info *server = wdata->server;
33844167 unsigned int written;
33854168 struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
3386
- unsigned int credits_received = 0;
4169
+ struct cifs_credits credits = { .value = 0, .instance = 0 };
4170
+
4171
+ WARN_ONCE(wdata->server != mid->server,
4172
+ "wdata server %p != mid server %p",
4173
+ wdata->server, mid->server);
33874174
33884175 switch (mid->mid_state) {
33894176 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);
4177
+ credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
4178
+ credits.instance = server->reconnect_instance;
4179
+ wdata->result = smb2_check_receive(mid, server, 0);
33924180 if (wdata->result != 0)
33934181 break;
33944182
....@@ -3412,8 +4200,9 @@
34124200 wdata->result = -EAGAIN;
34134201 break;
34144202 case MID_RESPONSE_MALFORMED:
3415
- credits_received = le16_to_cpu(rsp->sync_hdr.CreditRequest);
3416
- /* fall through */
4203
+ credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
4204
+ credits.instance = server->reconnect_instance;
4205
+ fallthrough;
34174206 default:
34184207 wdata->result = -EIO;
34194208 break;
....@@ -3438,8 +4227,8 @@
34384227 tcon->tid, tcon->ses->Suid, wdata->offset,
34394228 wdata->bytes, wdata->result);
34404229 if (wdata->result == -ENOSPC)
3441
- printk_once(KERN_WARNING "Out of space writing to %s\n",
3442
- tcon->treeName);
4230
+ pr_warn_once("Out of space writing to %s\n",
4231
+ tcon->treeName);
34434232 } else
34444233 trace_smb3_write_done(0 /* no xid */,
34454234 wdata->cfile->fid.persistent_fid,
....@@ -3448,7 +4237,7 @@
34484237
34494238 queue_work(cifsiod_wq, &wdata->work);
34504239 DeleteMidQEntry(mid);
3451
- add_credits(tcon->ses->server, credits_received, 0);
4240
+ add_credits(server, &credits, 0);
34524241 }
34534242
34544243 /* smb2_async_writev - send an async write, and set up mid to handle result */
....@@ -3460,23 +4249,18 @@
34604249 struct smb2_write_req *req = NULL;
34614250 struct smb2_sync_hdr *shdr;
34624251 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
3463
- struct TCP_Server_Info *server = tcon->ses->server;
4252
+ struct TCP_Server_Info *server = wdata->server;
34644253 struct kvec iov[1];
34654254 struct smb_rqst rqst = { };
34664255 unsigned int total_len;
34674256
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
- }
4257
+ if (!wdata->server)
4258
+ server = wdata->server = cifs_pick_channel(tcon->ses);
4259
+
4260
+ rc = smb2_plain_req_init(SMB2_WRITE, tcon, server,
4261
+ (void **) &req, &total_len);
4262
+ if (rc)
4263
+ return rc;
34804264
34814265 if (smb3_encryption_required(tcon))
34824266 flags |= CIFS_TRANSFORM_REQ;
....@@ -3493,6 +4277,9 @@
34934277 req->DataOffset = cpu_to_le16(
34944278 offsetof(struct smb2_write_req, Buffer));
34954279 req->RemainingBytes = 0;
4280
+
4281
+ trace_smb3_write_enter(0 /* xid */, wdata->cfile->fid.persistent_fid,
4282
+ tcon->tid, tcon->ses->Suid, wdata->offset, wdata->bytes);
34964283 #ifdef CONFIG_CIFS_SMB_DIRECT
34974284 /*
34984285 * If we want to do a server RDMA read, fill in and append
....@@ -3509,7 +4296,7 @@
35094296 wdata->nr_pages, wdata->page_offset,
35104297 wdata->tailsz, false, need_invalidate);
35114298 if (!wdata->mr) {
3512
- rc = -ENOBUFS;
4299
+ rc = -EAGAIN;
35134300 goto async_writev_out;
35144301 }
35154302 req->Length = 0;
....@@ -3562,23 +4349,21 @@
35624349 req->Length = cpu_to_le32(wdata->bytes);
35634350 #endif
35644351
3565
- if (wdata->credits) {
4352
+ if (wdata->credits.value > 0) {
35664353 shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
35674354 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);
4355
+ shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
4356
+
4357
+ rc = adjust_credits(server, &wdata->credits, wdata->bytes);
4358
+ if (rc)
4359
+ goto async_writev_out;
4360
+
35764361 flags |= CIFS_HAS_CREDITS;
35774362 }
35784363
35794364 kref_get(&wdata->refcount);
35804365 rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL,
3581
- wdata, flags);
4366
+ wdata, flags, &wdata->credits);
35824367
35834368 if (rc) {
35844369 trace_smb3_write_err(0 /* no xid */, req->PersistentFileId,
....@@ -3611,19 +4396,23 @@
36114396 struct kvec rsp_iov;
36124397 int flags = 0;
36134398 unsigned int total_len;
4399
+ struct TCP_Server_Info *server;
36144400
36154401 *nbytes = 0;
36164402
36174403 if (n_vec < 1)
36184404 return rc;
36194405
3620
- rc = smb2_plain_req_init(SMB2_WRITE, io_parms->tcon, (void **) &req,
3621
- &total_len);
4406
+ if (!io_parms->server)
4407
+ io_parms->server = cifs_pick_channel(io_parms->tcon->ses);
4408
+ server = io_parms->server;
4409
+ if (server == NULL)
4410
+ return -ECONNABORTED;
4411
+
4412
+ rc = smb2_plain_req_init(SMB2_WRITE, io_parms->tcon, server,
4413
+ (void **) &req, &total_len);
36224414 if (rc)
36234415 return rc;
3624
-
3625
- if (io_parms->tcon->ses->server == NULL)
3626
- return -ECONNABORTED;
36274416
36284417 if (smb3_encryption_required(io_parms->tcon))
36294418 flags |= CIFS_TRANSFORM_REQ;
....@@ -3641,6 +4430,10 @@
36414430 offsetof(struct smb2_write_req, Buffer));
36424431 req->RemainingBytes = 0;
36434432
4433
+ trace_smb3_write_enter(xid, io_parms->persistent_fid,
4434
+ io_parms->tcon->tid, io_parms->tcon->ses->Suid,
4435
+ io_parms->offset, io_parms->length);
4436
+
36444437 iov[0].iov_base = (char *)req;
36454438 /* 1 for Buffer */
36464439 iov[0].iov_len = total_len - 1;
....@@ -3649,7 +4442,8 @@
36494442 rqst.rq_iov = iov;
36504443 rqst.rq_nvec = n_vec + 1;
36514444
3652
- rc = cifs_send_recv(xid, io_parms->tcon->ses, &rqst,
4445
+ rc = cifs_send_recv(xid, io_parms->tcon->ses, server,
4446
+ &rqst,
36534447 &resp_buftype, flags, &rsp_iov);
36544448 rsp = (struct smb2_write_rsp *)rsp_iov.iov_base;
36554449
....@@ -3673,8 +4467,104 @@
36734467 return rc;
36744468 }
36754469
4470
+int posix_info_sid_size(const void *beg, const void *end)
4471
+{
4472
+ size_t subauth;
4473
+ int total;
4474
+
4475
+ if (beg + 1 > end)
4476
+ return -1;
4477
+
4478
+ subauth = *(u8 *)(beg+1);
4479
+ if (subauth < 1 || subauth > 15)
4480
+ return -1;
4481
+
4482
+ total = 1 + 1 + 6 + 4*subauth;
4483
+ if (beg + total > end)
4484
+ return -1;
4485
+
4486
+ return total;
4487
+}
4488
+
4489
+int posix_info_parse(const void *beg, const void *end,
4490
+ struct smb2_posix_info_parsed *out)
4491
+
4492
+{
4493
+ int total_len = 0;
4494
+ int sid_len;
4495
+ int name_len;
4496
+ const void *owner_sid;
4497
+ const void *group_sid;
4498
+ const void *name;
4499
+
4500
+ /* if no end bound given, assume payload to be correct */
4501
+ if (!end) {
4502
+ const struct smb2_posix_info *p = beg;
4503
+
4504
+ end = beg + le32_to_cpu(p->NextEntryOffset);
4505
+ /* last element will have a 0 offset, pick a sensible bound */
4506
+ if (end == beg)
4507
+ end += 0xFFFF;
4508
+ }
4509
+
4510
+ /* check base buf */
4511
+ if (beg + sizeof(struct smb2_posix_info) > end)
4512
+ return -1;
4513
+ total_len = sizeof(struct smb2_posix_info);
4514
+
4515
+ /* check owner sid */
4516
+ owner_sid = beg + total_len;
4517
+ sid_len = posix_info_sid_size(owner_sid, end);
4518
+ if (sid_len < 0)
4519
+ return -1;
4520
+ total_len += sid_len;
4521
+
4522
+ /* check group sid */
4523
+ group_sid = beg + total_len;
4524
+ sid_len = posix_info_sid_size(group_sid, end);
4525
+ if (sid_len < 0)
4526
+ return -1;
4527
+ total_len += sid_len;
4528
+
4529
+ /* check name len */
4530
+ if (beg + total_len + 4 > end)
4531
+ return -1;
4532
+ name_len = le32_to_cpu(*(__le32 *)(beg + total_len));
4533
+ if (name_len < 1 || name_len > 0xFFFF)
4534
+ return -1;
4535
+ total_len += 4;
4536
+
4537
+ /* check name */
4538
+ name = beg + total_len;
4539
+ if (name + name_len > end)
4540
+ return -1;
4541
+ total_len += name_len;
4542
+
4543
+ if (out) {
4544
+ out->base = beg;
4545
+ out->size = total_len;
4546
+ out->name_len = name_len;
4547
+ out->name = name;
4548
+ memcpy(&out->owner, owner_sid,
4549
+ posix_info_sid_size(owner_sid, end));
4550
+ memcpy(&out->group, group_sid,
4551
+ posix_info_sid_size(group_sid, end));
4552
+ }
4553
+ return total_len;
4554
+}
4555
+
4556
+static int posix_info_extra_size(const void *beg, const void *end)
4557
+{
4558
+ int len = posix_info_parse(beg, end, NULL);
4559
+
4560
+ if (len < 0)
4561
+ return -1;
4562
+ return len - sizeof(struct smb2_posix_info);
4563
+}
4564
+
36764565 static unsigned int
3677
-num_entries(char *bufstart, char *end_of_buf, char **lastentry, size_t size)
4566
+num_entries(int infotype, char *bufstart, char *end_of_buf, char **lastentry,
4567
+ size_t size)
36784568 {
36794569 int len;
36804570 unsigned int entrycount = 0;
....@@ -3698,8 +4588,13 @@
36984588 entryptr = entryptr + next_offset;
36994589 dir_info = (FILE_DIRECTORY_INFO *)entryptr;
37004590
3701
- len = le32_to_cpu(dir_info->FileNameLength);
3702
- if (entryptr + len < entryptr ||
4591
+ if (infotype == SMB_FIND_FILE_POSIX_INFO)
4592
+ len = posix_info_extra_size(entryptr, end_of_buf);
4593
+ else
4594
+ len = le32_to_cpu(dir_info->FileNameLength);
4595
+
4596
+ if (len < 0 ||
4597
+ entryptr + len < entryptr ||
37034598 entryptr + len > end_of_buf ||
37044599 entryptr + len + size > end_of_buf) {
37054600 cifs_dbg(VFS, "directory entry name would overflow frame end of buf %p\n",
....@@ -3721,56 +4616,42 @@
37214616 /*
37224617 * Readdir/FindFirst
37234618 */
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)
4619
+int SMB2_query_directory_init(const unsigned int xid,
4620
+ struct cifs_tcon *tcon,
4621
+ struct TCP_Server_Info *server,
4622
+ struct smb_rqst *rqst,
4623
+ u64 persistent_fid, u64 volatile_fid,
4624
+ int index, int info_level)
37284625 {
3729
- struct smb_rqst rqst;
37304626 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;
37374627 unsigned char *bufptr;
3738
- struct TCP_Server_Info *server;
3739
- struct cifs_ses *ses = tcon->ses;
37404628 __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;
4629
+ unsigned int output_size = CIFSMaxBufSize -
4630
+ MAX_SMB2_CREATE_RESPONSE_SIZE -
4631
+ MAX_SMB2_CLOSE_RESPONSE_SIZE;
37454632 unsigned int total_len;
4633
+ struct kvec *iov = rqst->rq_iov;
4634
+ int len, rc;
37464635
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);
4636
+ rc = smb2_plain_req_init(SMB2_QUERY_DIRECTORY, tcon, server,
4637
+ (void **) &req, &total_len);
37544638 if (rc)
37554639 return rc;
37564640
3757
- if (smb3_encryption_required(tcon))
3758
- flags |= CIFS_TRANSFORM_REQ;
3759
-
3760
- switch (srch_inf->info_level) {
4641
+ switch (info_level) {
37614642 case SMB_FIND_FILE_DIRECTORY_INFO:
37624643 req->FileInformationClass = FILE_DIRECTORY_INFORMATION;
3763
- info_buf_size = sizeof(FILE_DIRECTORY_INFO) - 1;
37644644 break;
37654645 case SMB_FIND_FILE_ID_FULL_DIR_INFO:
37664646 req->FileInformationClass = FILEID_FULL_DIRECTORY_INFORMATION;
3767
- info_buf_size = sizeof(SEARCH_ID_FULL_DIR_INFO) - 1;
4647
+ break;
4648
+ case SMB_FIND_FILE_POSIX_INFO:
4649
+ req->FileInformationClass = SMB_FIND_FILE_POSIX_INFO;
37684650 break;
37694651 default:
3770
- cifs_dbg(VFS, "info level %u isn't supported\n",
3771
- srch_inf->info_level);
3772
- rc = -EINVAL;
3773
- goto qdir_exit;
4652
+ cifs_tcon_dbg(VFS, "info level %u isn't supported\n",
4653
+ info_level);
4654
+ return -EINVAL;
37744655 }
37754656
37764657 req->FileIndex = cpu_to_le32(index);
....@@ -3799,29 +4680,56 @@
37994680 iov[1].iov_base = (char *)(req->Buffer);
38004681 iov[1].iov_len = len;
38014682
3802
- memset(&rqst, 0, sizeof(struct smb_rqst));
3803
- rqst.rq_iov = iov;
3804
- rqst.rq_nvec = 2;
4683
+ trace_smb3_query_dir_enter(xid, persistent_fid, tcon->tid,
4684
+ tcon->ses->Suid, index, output_size);
38054685
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;
4686
+ return 0;
4687
+}
38094688
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;
4689
+void SMB2_query_directory_free(struct smb_rqst *rqst)
4690
+{
4691
+ if (rqst && rqst->rq_iov) {
4692
+ cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
4693
+ }
4694
+}
4695
+
4696
+int
4697
+smb2_parse_query_directory(struct cifs_tcon *tcon,
4698
+ struct kvec *rsp_iov,
4699
+ int resp_buftype,
4700
+ struct cifs_search_info *srch_inf)
4701
+{
4702
+ struct smb2_query_directory_rsp *rsp;
4703
+ size_t info_buf_size;
4704
+ char *end_of_smb;
4705
+ int rc;
4706
+
4707
+ rsp = (struct smb2_query_directory_rsp *)rsp_iov->iov_base;
4708
+
4709
+ switch (srch_inf->info_level) {
4710
+ case SMB_FIND_FILE_DIRECTORY_INFO:
4711
+ info_buf_size = sizeof(FILE_DIRECTORY_INFO) - 1;
4712
+ break;
4713
+ case SMB_FIND_FILE_ID_FULL_DIR_INFO:
4714
+ info_buf_size = sizeof(SEARCH_ID_FULL_DIR_INFO) - 1;
4715
+ break;
4716
+ case SMB_FIND_FILE_POSIX_INFO:
4717
+ /* note that posix payload are variable size */
4718
+ info_buf_size = sizeof(struct smb2_posix_info);
4719
+ break;
4720
+ default:
4721
+ cifs_tcon_dbg(VFS, "info level %u isn't supported\n",
4722
+ srch_inf->info_level);
4723
+ return -EINVAL;
38184724 }
38194725
38204726 rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset),
3821
- le32_to_cpu(rsp->OutputBufferLength), &rsp_iov,
4727
+ le32_to_cpu(rsp->OutputBufferLength), rsp_iov,
38224728 info_buf_size);
3823
- if (rc)
3824
- goto qdir_exit;
4729
+ if (rc) {
4730
+ cifs_tcon_dbg(VFS, "bad info payload");
4731
+ return rc;
4732
+ }
38254733
38264734 srch_inf->unicode = true;
38274735
....@@ -3834,10 +4742,15 @@
38344742 srch_inf->ntwrk_buf_start = (char *)rsp;
38354743 srch_inf->srch_entries_start = srch_inf->last_entry =
38364744 (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);
4745
+ end_of_smb = rsp_iov->iov_len + (char *)rsp;
4746
+
4747
+ srch_inf->entries_in_buffer = num_entries(
4748
+ srch_inf->info_level,
4749
+ srch_inf->srch_entries_start,
4750
+ end_of_smb,
4751
+ &srch_inf->last_entry,
4752
+ info_buf_size);
4753
+
38414754 srch_inf->index_of_last_entry += srch_inf->entries_in_buffer;
38424755 cifs_dbg(FYI, "num entries %d last_index %lld srch start %p srch end %p\n",
38434756 srch_inf->entries_in_buffer, srch_inf->index_of_last_entry,
....@@ -3847,54 +4760,99 @@
38474760 else if (resp_buftype == CIFS_SMALL_BUFFER)
38484761 srch_inf->smallBuf = true;
38494762 else
3850
- cifs_dbg(VFS, "illegal search buffer type\n");
4763
+ cifs_tcon_dbg(VFS, "Invalid search buffer type\n");
38514764
3852
- return rc;
3853
-
3854
-qdir_exit:
3855
- free_rsp_buf(resp_buftype, rsp);
3856
- return rc;
4765
+ return 0;
38574766 }
38584767
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)
4768
+int
4769
+SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
4770
+ u64 persistent_fid, u64 volatile_fid, int index,
4771
+ struct cifs_search_info *srch_inf)
38644772 {
38654773 struct smb_rqst rqst;
3866
- struct smb2_set_info_req *req;
3867
- struct smb2_set_info_rsp *rsp = NULL;
3868
- struct kvec *iov;
4774
+ struct kvec iov[SMB2_QUERY_DIRECTORY_IOV_SIZE];
4775
+ struct smb2_query_directory_rsp *rsp = NULL;
4776
+ int resp_buftype = CIFS_NO_BUFFER;
38694777 struct kvec rsp_iov;
38704778 int rc = 0;
3871
- int resp_buftype;
3872
- unsigned int i;
38734779 struct cifs_ses *ses = tcon->ses;
4780
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
38744781 int flags = 0;
3875
- unsigned int total_len;
38764782
38774783 if (!ses || !(ses->server))
38784784 return -EIO;
38794785
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
-
38934786 if (smb3_encryption_required(tcon))
38944787 flags |= CIFS_TRANSFORM_REQ;
38954788
3896
- req->sync_hdr.ProcessId = cpu_to_le32(pid);
4789
+ memset(&rqst, 0, sizeof(struct smb_rqst));
4790
+ memset(&iov, 0, sizeof(iov));
4791
+ rqst.rq_iov = iov;
4792
+ rqst.rq_nvec = SMB2_QUERY_DIRECTORY_IOV_SIZE;
38974793
4794
+ rc = SMB2_query_directory_init(xid, tcon, server,
4795
+ &rqst, persistent_fid,
4796
+ volatile_fid, index,
4797
+ srch_inf->info_level);
4798
+ if (rc)
4799
+ goto qdir_exit;
4800
+
4801
+ rc = cifs_send_recv(xid, ses, server,
4802
+ &rqst, &resp_buftype, flags, &rsp_iov);
4803
+ rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base;
4804
+
4805
+ if (rc) {
4806
+ if (rc == -ENODATA &&
4807
+ rsp->sync_hdr.Status == STATUS_NO_MORE_FILES) {
4808
+ trace_smb3_query_dir_done(xid, persistent_fid,
4809
+ tcon->tid, tcon->ses->Suid, index, 0);
4810
+ srch_inf->endOfSearch = true;
4811
+ rc = 0;
4812
+ } else {
4813
+ trace_smb3_query_dir_err(xid, persistent_fid, tcon->tid,
4814
+ tcon->ses->Suid, index, 0, rc);
4815
+ cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE);
4816
+ }
4817
+ goto qdir_exit;
4818
+ }
4819
+
4820
+ rc = smb2_parse_query_directory(tcon, &rsp_iov, resp_buftype,
4821
+ srch_inf);
4822
+ if (rc) {
4823
+ trace_smb3_query_dir_err(xid, persistent_fid, tcon->tid,
4824
+ tcon->ses->Suid, index, 0, rc);
4825
+ goto qdir_exit;
4826
+ }
4827
+ resp_buftype = CIFS_NO_BUFFER;
4828
+
4829
+ trace_smb3_query_dir_done(xid, persistent_fid, tcon->tid,
4830
+ tcon->ses->Suid, index, srch_inf->entries_in_buffer);
4831
+
4832
+qdir_exit:
4833
+ SMB2_query_directory_free(&rqst);
4834
+ free_rsp_buf(resp_buftype, rsp);
4835
+ return rc;
4836
+}
4837
+
4838
+int
4839
+SMB2_set_info_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server,
4840
+ struct smb_rqst *rqst,
4841
+ u64 persistent_fid, u64 volatile_fid, u32 pid,
4842
+ u8 info_class, u8 info_type, u32 additional_info,
4843
+ void **data, unsigned int *size)
4844
+{
4845
+ struct smb2_set_info_req *req;
4846
+ struct kvec *iov = rqst->rq_iov;
4847
+ unsigned int i, total_len;
4848
+ int rc;
4849
+
4850
+ rc = smb2_plain_req_init(SMB2_SET_INFO, tcon, server,
4851
+ (void **) &req, &total_len);
4852
+ if (rc)
4853
+ return rc;
4854
+
4855
+ req->sync_hdr.ProcessId = cpu_to_le32(pid);
38984856 req->InfoType = info_type;
38994857 req->FileInfoClass = info_class;
39004858 req->PersistentFileId = persistent_fid;
....@@ -3912,19 +4870,69 @@
39124870 /* 1 for Buffer */
39134871 iov[0].iov_len = total_len - 1;
39144872
3915
- for (i = 1; i < num; i++) {
4873
+ for (i = 1; i < rqst->rq_nvec; i++) {
39164874 le32_add_cpu(&req->BufferLength, size[i]);
39174875 iov[i].iov_base = (char *)data[i];
39184876 iov[i].iov_len = size[i];
39194877 }
39204878
4879
+ return 0;
4880
+}
4881
+
4882
+void
4883
+SMB2_set_info_free(struct smb_rqst *rqst)
4884
+{
4885
+ if (rqst && rqst->rq_iov)
4886
+ cifs_buf_release(rqst->rq_iov[0].iov_base); /* request */
4887
+}
4888
+
4889
+static int
4890
+send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
4891
+ u64 persistent_fid, u64 volatile_fid, u32 pid, u8 info_class,
4892
+ u8 info_type, u32 additional_info, unsigned int num,
4893
+ void **data, unsigned int *size)
4894
+{
4895
+ struct smb_rqst rqst;
4896
+ struct smb2_set_info_rsp *rsp = NULL;
4897
+ struct kvec *iov;
4898
+ struct kvec rsp_iov;
4899
+ int rc = 0;
4900
+ int resp_buftype;
4901
+ struct cifs_ses *ses = tcon->ses;
4902
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
4903
+ int flags = 0;
4904
+
4905
+ if (!ses || !server)
4906
+ return -EIO;
4907
+
4908
+ if (!num)
4909
+ return -EINVAL;
4910
+
4911
+ if (smb3_encryption_required(tcon))
4912
+ flags |= CIFS_TRANSFORM_REQ;
4913
+
4914
+ iov = kmalloc_array(num, sizeof(struct kvec), GFP_KERNEL);
4915
+ if (!iov)
4916
+ return -ENOMEM;
4917
+
39214918 memset(&rqst, 0, sizeof(struct smb_rqst));
39224919 rqst.rq_iov = iov;
39234920 rqst.rq_nvec = num;
39244921
3925
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
4922
+ rc = SMB2_set_info_init(tcon, server,
4923
+ &rqst, persistent_fid, volatile_fid, pid,
4924
+ info_class, info_type, additional_info,
4925
+ data, size);
4926
+ if (rc) {
4927
+ kfree(iov);
4928
+ return rc;
4929
+ }
4930
+
4931
+
4932
+ rc = cifs_send_recv(xid, ses, server,
4933
+ &rqst, &resp_buftype, flags,
39264934 &rsp_iov);
3927
- cifs_buf_release(req);
4935
+ SMB2_set_info_free(&rqst);
39284936 rsp = (struct smb2_set_info_rsp *)rsp_iov.iov_base;
39294937
39304938 if (rc != 0) {
....@@ -3939,88 +4947,8 @@
39394947 }
39404948
39414949 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
40224950 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)
4951
+ u64 volatile_fid, u32 pid, __le64 *eof)
40244952 {
40254953 struct smb2_file_eof_info info;
40264954 void *data;
....@@ -4031,25 +4959,9 @@
40314959 data = &info;
40324960 size = sizeof(struct smb2_file_eof_info);
40334961
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,
4962
+ return send_set_info(xid, tcon, persistent_fid, volatile_fid,
40404963 pid, FILE_END_OF_FILE_INFORMATION, SMB2_O_INFO_FILE,
40414964 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);
40534965 }
40544966
40554967 int
....@@ -4081,6 +4993,7 @@
40814993 int rc;
40824994 struct smb2_oplock_break *req = NULL;
40834995 struct cifs_ses *ses = tcon->ses;
4996
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
40844997 int flags = CIFS_OBREAK_OP;
40854998 unsigned int total_len;
40864999 struct kvec iov[1];
....@@ -4088,8 +5001,8 @@
40885001 int resp_buf_type;
40895002
40905003 cifs_dbg(FYI, "SMB2_oplock_break\n");
4091
- rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req,
4092
- &total_len);
5004
+ rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, server,
5005
+ (void **) &req, &total_len);
40935006 if (rc)
40945007 return rc;
40955008
....@@ -4101,7 +5014,7 @@
41015014 req->OplockLevel = oplock_level;
41025015 req->sync_hdr.CreditRequest = cpu_to_le16(1);
41035016
4104
- flags |= CIFS_NO_RESP;
5017
+ flags |= CIFS_NO_RSP_BUF;
41055018
41065019 iov[0].iov_base = (char *)req;
41075020 iov[0].iov_len = total_len;
....@@ -4110,7 +5023,8 @@
41105023 rqst.rq_iov = iov;
41115024 rqst.rq_nvec = 1;
41125025
4113
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
5026
+ rc = cifs_send_recv(xid, ses, server,
5027
+ &rqst, &resp_buf_type, flags, &rsp_iov);
41145028 cifs_small_buf_release(req);
41155029
41165030 if (rc) {
....@@ -4153,23 +5067,22 @@
41535067 }
41545068
41555069 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)
5070
+build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon,
5071
+ struct TCP_Server_Info *server,
5072
+ int level, int outbuf_len, u64 persistent_fid,
5073
+ u64 volatile_fid)
41585074 {
4159
- struct TCP_Server_Info *server;
41605075 int rc;
41615076 struct smb2_query_info_req *req;
41625077 unsigned int total_len;
41635078
41645079 cifs_dbg(FYI, "Query FSInfo level %d\n", level);
41655080
4166
- if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
5081
+ if ((tcon->ses == NULL) || server == NULL)
41675082 return -EIO;
41685083
4169
- server = tcon->ses->server;
4170
-
4171
- rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, (void **) &req,
4172
- &total_len);
5084
+ rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, server,
5085
+ (void **) &req, &total_len);
41735086 if (rc)
41745087 return rc;
41755088
....@@ -4199,10 +5112,12 @@
41995112 int rc = 0;
42005113 int resp_buftype;
42015114 struct cifs_ses *ses = tcon->ses;
5115
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
42025116 FILE_SYSTEM_POSIX_INFO *info = NULL;
42035117 int flags = 0;
42045118
4205
- rc = build_qfs_info_req(&iov, tcon, FS_POSIX_INFORMATION,
5119
+ rc = build_qfs_info_req(&iov, tcon, server,
5120
+ FS_POSIX_INFORMATION,
42065121 sizeof(FILE_SYSTEM_POSIX_INFO),
42075122 persistent_fid, volatile_fid);
42085123 if (rc)
....@@ -4215,7 +5130,8 @@
42155130 rqst.rq_iov = &iov;
42165131 rqst.rq_nvec = 1;
42175132
4218
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
5133
+ rc = cifs_send_recv(xid, ses, server,
5134
+ &rqst, &resp_buftype, flags, &rsp_iov);
42195135 cifs_small_buf_release(iov.iov_base);
42205136 if (rc) {
42215137 cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
....@@ -4247,10 +5163,12 @@
42475163 int rc = 0;
42485164 int resp_buftype;
42495165 struct cifs_ses *ses = tcon->ses;
5166
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
42505167 struct smb2_fs_full_size_info *info = NULL;
42515168 int flags = 0;
42525169
4253
- rc = build_qfs_info_req(&iov, tcon, FS_FULL_SIZE_INFORMATION,
5170
+ rc = build_qfs_info_req(&iov, tcon, server,
5171
+ FS_FULL_SIZE_INFORMATION,
42545172 sizeof(struct smb2_fs_full_size_info),
42555173 persistent_fid, volatile_fid);
42565174 if (rc)
....@@ -4263,7 +5181,8 @@
42635181 rqst.rq_iov = &iov;
42645182 rqst.rq_nvec = 1;
42655183
4266
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
5184
+ rc = cifs_send_recv(xid, ses, server,
5185
+ &rqst, &resp_buftype, flags, &rsp_iov);
42675186 cifs_small_buf_release(iov.iov_base);
42685187 if (rc) {
42695188 cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
....@@ -4295,6 +5214,7 @@
42955214 int rc = 0;
42965215 int resp_buftype, max_len, min_len;
42975216 struct cifs_ses *ses = tcon->ses;
5217
+ struct TCP_Server_Info *server = cifs_pick_channel(ses);
42985218 unsigned int rsp_len, offset;
42995219 int flags = 0;
43005220
....@@ -4315,7 +5235,8 @@
43155235 return -EINVAL;
43165236 }
43175237
4318
- rc = build_qfs_info_req(&iov, tcon, level, max_len,
5238
+ rc = build_qfs_info_req(&iov, tcon, server,
5239
+ level, max_len,
43195240 persistent_fid, volatile_fid);
43205241 if (rc)
43215242 return rc;
....@@ -4327,7 +5248,8 @@
43275248 rqst.rq_iov = &iov;
43285249 rqst.rq_nvec = 1;
43295250
4330
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
5251
+ rc = cifs_send_recv(xid, ses, server,
5252
+ &rqst, &resp_buftype, flags, &rsp_iov);
43315253 cifs_small_buf_release(iov.iov_base);
43325254 if (rc) {
43335255 cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
....@@ -4378,12 +5300,14 @@
43785300 struct kvec rsp_iov;
43795301 int resp_buf_type;
43805302 unsigned int count;
4381
- int flags = CIFS_NO_RESP;
5303
+ int flags = CIFS_NO_RSP_BUF;
43825304 unsigned int total_len;
5305
+ struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
43835306
43845307 cifs_dbg(FYI, "smb2_lockv num lock %d\n", num_lock);
43855308
4386
- rc = smb2_plain_req_init(SMB2_LOCK, tcon, (void **) &req, &total_len);
5309
+ rc = smb2_plain_req_init(SMB2_LOCK, tcon, server,
5310
+ (void **) &req, &total_len);
43875311 if (rc)
43885312 return rc;
43895313
....@@ -4409,7 +5333,8 @@
44095333 rqst.rq_iov = iov;
44105334 rqst.rq_nvec = 2;
44115335
4412
- rc = cifs_send_recv(xid, tcon->ses, &rqst, &resp_buf_type, flags,
5336
+ rc = cifs_send_recv(xid, tcon->ses, server,
5337
+ &rqst, &resp_buf_type, flags,
44135338 &rsp_iov);
44145339 cifs_small_buf_release(req);
44155340 if (rc) {
....@@ -4452,10 +5377,13 @@
44525377 struct kvec iov[1];
44535378 struct kvec rsp_iov;
44545379 int resp_buf_type;
5380
+ __u64 *please_key_high;
5381
+ __u64 *please_key_low;
5382
+ struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
44555383
44565384 cifs_dbg(FYI, "SMB2_lease_break\n");
4457
- rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, (void **) &req,
4458
- &total_len);
5385
+ rc = smb2_plain_req_init(SMB2_OPLOCK_BREAK, tcon, server,
5386
+ (void **) &req, &total_len);
44595387 if (rc)
44605388 return rc;
44615389
....@@ -4469,7 +5397,7 @@
44695397 memcpy(req->LeaseKey, lease_key, 16);
44705398 req->LeaseState = lease_state;
44715399
4472
- flags |= CIFS_NO_RESP;
5400
+ flags |= CIFS_NO_RSP_BUF;
44735401
44745402 iov[0].iov_base = (char *)req;
44755403 iov[0].iov_len = total_len;
....@@ -4478,13 +5406,20 @@
44785406 rqst.rq_iov = iov;
44795407 rqst.rq_nvec = 1;
44805408
4481
- rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
5409
+ rc = cifs_send_recv(xid, ses, server,
5410
+ &rqst, &resp_buf_type, flags, &rsp_iov);
44825411 cifs_small_buf_release(req);
44835412
5413
+ please_key_low = (__u64 *)lease_key;
5414
+ please_key_high = (__u64 *)(lease_key+8);
44845415 if (rc) {
44855416 cifs_stats_fail_inc(tcon, SMB2_OPLOCK_BREAK_HE);
5417
+ trace_smb3_lease_err(le32_to_cpu(lease_state), tcon->tid,
5418
+ ses->Suid, *please_key_low, *please_key_high, rc);
44865419 cifs_dbg(FYI, "Send error in Lease Break = %d\n", rc);
4487
- }
5420
+ } else
5421
+ trace_smb3_lease_done(le32_to_cpu(lease_state), tcon->tid,
5422
+ ses->Suid, *please_key_low, *please_key_high);
44885423
44895424 return rc;
44905425 }