diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2013-09-04 05:44:05 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-09-09 23:52:14 -0400 |
commit | f047390a097e907ccccf8aa894dec49890578a1a (patch) | |
tree | 7b3e1d971275e86b51aa42bf7fa18c5c7445381f | |
parent | b5c7cde3fac35e33835d37be59cb4e5a0b9cf3c2 (diff) |
CIFS: Add create lease v2 context for SMB3
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r-- | fs/cifs/smb2ops.c | 67 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 19 |
2 files changed, 73 insertions, 13 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 0215e60267e2..a9256bd374f8 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -714,6 +714,19 @@ smb21_is_read_op(__u32 oplock) | |||
714 | !(oplock & SMB2_LEASE_WRITE_CACHING_HE); | 714 | !(oplock & SMB2_LEASE_WRITE_CACHING_HE); |
715 | } | 715 | } |
716 | 716 | ||
717 | static __le32 | ||
718 | map_oplock_to_lease(u8 oplock) | ||
719 | { | ||
720 | if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) | ||
721 | return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING; | ||
722 | else if (oplock == SMB2_OPLOCK_LEVEL_II) | ||
723 | return SMB2_LEASE_READ_CACHING; | ||
724 | else if (oplock == SMB2_OPLOCK_LEVEL_BATCH) | ||
725 | return SMB2_LEASE_HANDLE_CACHING | SMB2_LEASE_READ_CACHING | | ||
726 | SMB2_LEASE_WRITE_CACHING; | ||
727 | return 0; | ||
728 | } | ||
729 | |||
717 | static char * | 730 | static char * |
718 | smb2_create_lease_buf(u8 *lease_key, u8 oplock) | 731 | smb2_create_lease_buf(u8 *lease_key, u8 oplock) |
719 | { | 732 | { |
@@ -725,15 +738,7 @@ smb2_create_lease_buf(u8 *lease_key, u8 oplock) | |||
725 | 738 | ||
726 | buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key)); | 739 | buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key)); |
727 | buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8))); | 740 | buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8))); |
728 | if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) | 741 | buf->lcontext.LeaseState = map_oplock_to_lease(oplock); |
729 | buf->lcontext.LeaseState = SMB2_LEASE_WRITE_CACHING | | ||
730 | SMB2_LEASE_READ_CACHING; | ||
731 | else if (oplock == SMB2_OPLOCK_LEVEL_II) | ||
732 | buf->lcontext.LeaseState = SMB2_LEASE_READ_CACHING; | ||
733 | else if (oplock == SMB2_OPLOCK_LEVEL_BATCH) | ||
734 | buf->lcontext.LeaseState = SMB2_LEASE_HANDLE_CACHING | | ||
735 | SMB2_LEASE_READ_CACHING | | ||
736 | SMB2_LEASE_WRITE_CACHING; | ||
737 | 742 | ||
738 | buf->ccontext.DataOffset = cpu_to_le16(offsetof | 743 | buf->ccontext.DataOffset = cpu_to_le16(offsetof |
739 | (struct create_lease, lcontext)); | 744 | (struct create_lease, lcontext)); |
@@ -748,6 +753,32 @@ smb2_create_lease_buf(u8 *lease_key, u8 oplock) | |||
748 | return (char *)buf; | 753 | return (char *)buf; |
749 | } | 754 | } |
750 | 755 | ||
756 | static char * | ||
757 | smb3_create_lease_buf(u8 *lease_key, u8 oplock) | ||
758 | { | ||
759 | struct create_lease_v2 *buf; | ||
760 | |||
761 | buf = kzalloc(sizeof(struct create_lease_v2), GFP_KERNEL); | ||
762 | if (!buf) | ||
763 | return NULL; | ||
764 | |||
765 | buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key)); | ||
766 | buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8))); | ||
767 | buf->lcontext.LeaseState = map_oplock_to_lease(oplock); | ||
768 | |||
769 | buf->ccontext.DataOffset = cpu_to_le16(offsetof | ||
770 | (struct create_lease_v2, lcontext)); | ||
771 | buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2)); | ||
772 | buf->ccontext.NameOffset = cpu_to_le16(offsetof | ||
773 | (struct create_lease_v2, Name)); | ||
774 | buf->ccontext.NameLength = cpu_to_le16(4); | ||
775 | buf->Name[0] = 'R'; | ||
776 | buf->Name[1] = 'q'; | ||
777 | buf->Name[2] = 'L'; | ||
778 | buf->Name[3] = 's'; | ||
779 | return (char *)buf; | ||
780 | } | ||
781 | |||
751 | static __u8 | 782 | static __u8 |
752 | smb2_parse_lease_buf(void *buf) | 783 | smb2_parse_lease_buf(void *buf) |
753 | { | 784 | { |
@@ -758,6 +789,16 @@ smb2_parse_lease_buf(void *buf) | |||
758 | return le32_to_cpu(lc->lcontext.LeaseState); | 789 | return le32_to_cpu(lc->lcontext.LeaseState); |
759 | } | 790 | } |
760 | 791 | ||
792 | static __u8 | ||
793 | smb3_parse_lease_buf(void *buf) | ||
794 | { | ||
795 | struct create_lease_v2 *lc = (struct create_lease_v2 *)buf; | ||
796 | |||
797 | if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS) | ||
798 | return SMB2_OPLOCK_LEVEL_NOCHANGE; | ||
799 | return le32_to_cpu(lc->lcontext.LeaseState); | ||
800 | } | ||
801 | |||
761 | struct smb_version_operations smb20_operations = { | 802 | struct smb_version_operations smb20_operations = { |
762 | .compare_fids = smb2_compare_fids, | 803 | .compare_fids = smb2_compare_fids, |
763 | .setup_request = smb2_setup_request, | 804 | .setup_request = smb2_setup_request, |
@@ -969,8 +1010,8 @@ struct smb_version_operations smb30_operations = { | |||
969 | .calc_signature = smb3_calc_signature, | 1010 | .calc_signature = smb3_calc_signature, |
970 | .is_read_op = smb21_is_read_op, | 1011 | .is_read_op = smb21_is_read_op, |
971 | .set_oplock_level = smb21_set_oplock_level, | 1012 | .set_oplock_level = smb21_set_oplock_level, |
972 | .create_lease_buf = smb2_create_lease_buf, | 1013 | .create_lease_buf = smb3_create_lease_buf, |
973 | .parse_lease_buf = smb2_parse_lease_buf, | 1014 | .parse_lease_buf = smb3_parse_lease_buf, |
974 | }; | 1015 | }; |
975 | 1016 | ||
976 | struct smb_version_values smb20_values = { | 1017 | struct smb_version_values smb20_values = { |
@@ -1030,7 +1071,7 @@ struct smb_version_values smb30_values = { | |||
1030 | .cap_large_files = SMB2_LARGE_FILES, | 1071 | .cap_large_files = SMB2_LARGE_FILES, |
1031 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, | 1072 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, |
1032 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, | 1073 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, |
1033 | .create_lease_size = sizeof(struct create_lease), | 1074 | .create_lease_size = sizeof(struct create_lease_v2), |
1034 | }; | 1075 | }; |
1035 | 1076 | ||
1036 | struct smb_version_values smb302_values = { | 1077 | struct smb_version_values smb302_values = { |
@@ -1050,5 +1091,5 @@ struct smb_version_values smb302_values = { | |||
1050 | .cap_large_files = SMB2_LARGE_FILES, | 1091 | .cap_large_files = SMB2_LARGE_FILES, |
1051 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, | 1092 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, |
1052 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, | 1093 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, |
1053 | .create_lease_size = sizeof(struct create_lease), | 1094 | .create_lease_size = sizeof(struct create_lease_v2), |
1054 | }; | 1095 | }; |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index a2ec65ae626c..b83d0118a757 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -497,12 +497,31 @@ struct lease_context { | |||
497 | __le64 LeaseDuration; | 497 | __le64 LeaseDuration; |
498 | } __packed; | 498 | } __packed; |
499 | 499 | ||
500 | struct lease_context_v2 { | ||
501 | __le64 LeaseKeyLow; | ||
502 | __le64 LeaseKeyHigh; | ||
503 | __le32 LeaseState; | ||
504 | __le32 LeaseFlags; | ||
505 | __le64 LeaseDuration; | ||
506 | __le64 ParentLeaseKeyLow; | ||
507 | __le64 ParentLeaseKeyHigh; | ||
508 | __le16 Epoch; | ||
509 | __le16 Reserved; | ||
510 | } __packed; | ||
511 | |||
500 | struct create_lease { | 512 | struct create_lease { |
501 | struct create_context ccontext; | 513 | struct create_context ccontext; |
502 | __u8 Name[8]; | 514 | __u8 Name[8]; |
503 | struct lease_context lcontext; | 515 | struct lease_context lcontext; |
504 | } __packed; | 516 | } __packed; |
505 | 517 | ||
518 | struct create_lease_v2 { | ||
519 | struct create_context ccontext; | ||
520 | __u8 Name[8]; | ||
521 | struct lease_context_v2 lcontext; | ||
522 | __u8 Pad[4]; | ||
523 | } __packed; | ||
524 | |||
506 | struct create_durable { | 525 | struct create_durable { |
507 | struct create_context ccontext; | 526 | struct create_context ccontext; |
508 | __u8 Name[8]; | 527 | __u8 Name[8]; |