diff options
Diffstat (limited to 'fs/cifs/smb2ops.c')
-rw-r--r-- | fs/cifs/smb2ops.c | 102 |
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 | ||
283 | static void | 290 | static void |
291 | smb2_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 | |||
309 | static void | ||
284 | smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon) | 310 | smb2_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 | ||
714 | struct smb_version_values smb21_values = { | 754 | struct 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 | ||
732 | struct smb_version_values smb30_values = { | 774 | struct 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 | |||
794 | struct 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 | }; |