aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/smb2ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/smb2ops.c')
-rw-r--r--fs/cifs/smb2ops.c102
1 files changed, 83 insertions, 19 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index f2e76f3b0c61..f259e6cc8357 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -213,22 +213,29 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
213 struct cifs_sb_info *cifs_sb, const char *full_path) 213 struct cifs_sb_info *cifs_sb, const char *full_path)
214{ 214{
215 int rc; 215 int rc;
216 __u64 persistent_fid, volatile_fid;
217 __le16 *utf16_path; 216 __le16 *utf16_path;
218 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 217 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
218 struct cifs_open_parms oparms;
219 struct cifs_fid fid;
219 220
220 utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); 221 utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
221 if (!utf16_path) 222 if (!utf16_path)
222 return -ENOMEM; 223 return -ENOMEM;
223 224
224 rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid, 225 oparms.tcon = tcon;
225 FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0, &oplock, NULL); 226 oparms.desired_access = FILE_READ_ATTRIBUTES;
227 oparms.disposition = FILE_OPEN;
228 oparms.create_options = 0;
229 oparms.fid = &fid;
230 oparms.reconnect = false;
231
232 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL);
226 if (rc) { 233 if (rc) {
227 kfree(utf16_path); 234 kfree(utf16_path);
228 return rc; 235 return rc;
229 } 236 }
230 237
231 rc = SMB2_close(xid, tcon, persistent_fid, volatile_fid); 238 rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
232 kfree(utf16_path); 239 kfree(utf16_path);
233 return rc; 240 return rc;
234} 241}
@@ -281,6 +288,25 @@ smb2_clear_stats(struct cifs_tcon *tcon)
281} 288}
282 289
283static void 290static void
291smb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon)
292{
293 seq_puts(m, "\n\tShare Capabilities:");
294 if (tcon->capabilities & SMB2_SHARE_CAP_DFS)
295 seq_puts(m, " DFS,");
296 if (tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
297 seq_puts(m, " CONTINUOUS AVAILABILITY,");
298 if (tcon->capabilities & SMB2_SHARE_CAP_SCALEOUT)
299 seq_puts(m, " SCALEOUT,");
300 if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER)
301 seq_puts(m, " CLUSTER,");
302 if (tcon->capabilities & SMB2_SHARE_CAP_ASYMMETRIC)
303 seq_puts(m, " ASYMMETRIC,");
304 if (tcon->capabilities == 0)
305 seq_puts(m, " None");
306 seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags);
307}
308
309static void
284smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon) 310smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
285{ 311{
286#ifdef CONFIG_CIFS_STATS 312#ifdef CONFIG_CIFS_STATS
@@ -292,7 +318,6 @@ smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
292 seq_printf(m, "\nSessionSetups: %d sent %d failed", 318 seq_printf(m, "\nSessionSetups: %d sent %d failed",
293 atomic_read(&sent[SMB2_SESSION_SETUP_HE]), 319 atomic_read(&sent[SMB2_SESSION_SETUP_HE]),
294 atomic_read(&failed[SMB2_SESSION_SETUP_HE])); 320 atomic_read(&failed[SMB2_SESSION_SETUP_HE]));
295#define SMB2LOGOFF 0x0002 /* trivial request/resp */
296 seq_printf(m, "\nLogoffs: %d sent %d failed", 321 seq_printf(m, "\nLogoffs: %d sent %d failed",
297 atomic_read(&sent[SMB2_LOGOFF_HE]), 322 atomic_read(&sent[SMB2_LOGOFF_HE]),
298 atomic_read(&failed[SMB2_LOGOFF_HE])); 323 atomic_read(&failed[SMB2_LOGOFF_HE]));
@@ -425,15 +450,20 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
425 __le16 *utf16_path; 450 __le16 *utf16_path;
426 int rc; 451 int rc;
427 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 452 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
428 __u64 persistent_fid, volatile_fid; 453 struct cifs_open_parms oparms;
429 454
430 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); 455 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
431 if (!utf16_path) 456 if (!utf16_path)
432 return -ENOMEM; 457 return -ENOMEM;
433 458
434 rc = SMB2_open(xid, tcon, utf16_path, &persistent_fid, &volatile_fid, 459 oparms.tcon = tcon;
435 FILE_READ_ATTRIBUTES | FILE_READ_DATA, FILE_OPEN, 0, 0, 460 oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
436 &oplock, NULL); 461 oparms.disposition = FILE_OPEN;
462 oparms.create_options = 0;
463 oparms.fid = fid;
464 oparms.reconnect = false;
465
466 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL);
437 kfree(utf16_path); 467 kfree(utf16_path);
438 if (rc) { 468 if (rc) {
439 cifs_dbg(VFS, "open dir failed\n"); 469 cifs_dbg(VFS, "open dir failed\n");
@@ -442,14 +472,12 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
442 472
443 srch_inf->entries_in_buffer = 0; 473 srch_inf->entries_in_buffer = 0;
444 srch_inf->index_of_last_entry = 0; 474 srch_inf->index_of_last_entry = 0;
445 fid->persistent_fid = persistent_fid;
446 fid->volatile_fid = volatile_fid;
447 475
448 rc = SMB2_query_directory(xid, tcon, persistent_fid, volatile_fid, 0, 476 rc = SMB2_query_directory(xid, tcon, fid->persistent_fid,
449 srch_inf); 477 fid->volatile_fid, 0, srch_inf);
450 if (rc) { 478 if (rc) {
451 cifs_dbg(VFS, "query directory failed\n"); 479 cifs_dbg(VFS, "query directory failed\n");
452 SMB2_close(xid, tcon, persistent_fid, volatile_fid); 480 SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
453 } 481 }
454 return rc; 482 return rc;
455} 483}
@@ -510,17 +538,25 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
510 struct kstatfs *buf) 538 struct kstatfs *buf)
511{ 539{
512 int rc; 540 int rc;
513 u64 persistent_fid, volatile_fid;
514 __le16 srch_path = 0; /* Null - open root of share */ 541 __le16 srch_path = 0; /* Null - open root of share */
515 u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 542 u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
543 struct cifs_open_parms oparms;
544 struct cifs_fid fid;
545
546 oparms.tcon = tcon;
547 oparms.desired_access = FILE_READ_ATTRIBUTES;
548 oparms.disposition = FILE_OPEN;
549 oparms.create_options = 0;
550 oparms.fid = &fid;
551 oparms.reconnect = false;
516 552
517 rc = SMB2_open(xid, tcon, &srch_path, &persistent_fid, &volatile_fid, 553 rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL);
518 FILE_READ_ATTRIBUTES, FILE_OPEN, 0, 0, &oplock, NULL);
519 if (rc) 554 if (rc)
520 return rc; 555 return rc;
521 buf->f_type = SMB2_MAGIC_NUMBER; 556 buf->f_type = SMB2_MAGIC_NUMBER;
522 rc = SMB2_QFS_info(xid, tcon, persistent_fid, volatile_fid, buf); 557 rc = SMB2_QFS_info(xid, tcon, fid.persistent_fid, fid.volatile_fid,
523 SMB2_close(xid, tcon, persistent_fid, volatile_fid); 558 buf);
559 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
524 return rc; 560 return rc;
525} 561}
526 562
@@ -645,6 +681,7 @@ struct smb_version_operations smb30_operations = {
645 .dump_detail = smb2_dump_detail, 681 .dump_detail = smb2_dump_detail,
646 .clear_stats = smb2_clear_stats, 682 .clear_stats = smb2_clear_stats,
647 .print_stats = smb2_print_stats, 683 .print_stats = smb2_print_stats,
684 .dump_share_caps = smb2_dump_share_caps,
648 .is_oplock_break = smb2_is_valid_oplock_break, 685 .is_oplock_break = smb2_is_valid_oplock_break,
649 .need_neg = smb2_need_neg, 686 .need_neg = smb2_need_neg,
650 .negotiate = smb2_negotiate, 687 .negotiate = smb2_negotiate,
@@ -690,6 +727,7 @@ struct smb_version_operations smb30_operations = {
690 .get_lease_key = smb2_get_lease_key, 727 .get_lease_key = smb2_get_lease_key,
691 .set_lease_key = smb2_set_lease_key, 728 .set_lease_key = smb2_set_lease_key,
692 .new_lease_key = smb2_new_lease_key, 729 .new_lease_key = smb2_new_lease_key,
730 .generate_signingkey = generate_smb3signingkey,
693 .calc_signature = smb3_calc_signature, 731 .calc_signature = smb3_calc_signature,
694}; 732};
695 733
@@ -709,6 +747,8 @@ struct smb_version_values smb20_values = {
709 .cap_nt_find = SMB2_NT_FIND, 747 .cap_nt_find = SMB2_NT_FIND,
710 .cap_large_files = SMB2_LARGE_FILES, 748 .cap_large_files = SMB2_LARGE_FILES,
711 .oplock_read = SMB2_OPLOCK_LEVEL_II, 749 .oplock_read = SMB2_OPLOCK_LEVEL_II,
750 .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
751 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
712}; 752};
713 753
714struct smb_version_values smb21_values = { 754struct smb_version_values smb21_values = {
@@ -727,6 +767,8 @@ struct smb_version_values smb21_values = {
727 .cap_nt_find = SMB2_NT_FIND, 767 .cap_nt_find = SMB2_NT_FIND,
728 .cap_large_files = SMB2_LARGE_FILES, 768 .cap_large_files = SMB2_LARGE_FILES,
729 .oplock_read = SMB2_OPLOCK_LEVEL_II, 769 .oplock_read = SMB2_OPLOCK_LEVEL_II,
770 .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
771 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
730}; 772};
731 773
732struct smb_version_values smb30_values = { 774struct smb_version_values smb30_values = {
@@ -745,4 +787,26 @@ struct smb_version_values smb30_values = {
745 .cap_nt_find = SMB2_NT_FIND, 787 .cap_nt_find = SMB2_NT_FIND,
746 .cap_large_files = SMB2_LARGE_FILES, 788 .cap_large_files = SMB2_LARGE_FILES,
747 .oplock_read = SMB2_OPLOCK_LEVEL_II, 789 .oplock_read = SMB2_OPLOCK_LEVEL_II,
790 .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
791 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
792};
793
794struct smb_version_values smb302_values = {
795 .version_string = SMB302_VERSION_STRING,
796 .protocol_id = SMB302_PROT_ID,
797 .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
798 .large_lock_type = 0,
799 .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
800 .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
801 .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
802 .header_size = sizeof(struct smb2_hdr),
803 .max_header_size = MAX_SMB2_HDR_SIZE,
804 .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
805 .lock_cmd = SMB2_LOCK,
806 .cap_unix = 0,
807 .cap_nt_find = SMB2_NT_FIND,
808 .cap_large_files = SMB2_LARGE_FILES,
809 .oplock_read = SMB2_OPLOCK_LEVEL_II,
810 .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
811 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
748}; 812};