diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2013-09-04 05:07:41 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-09-09 23:52:08 -0400 |
commit | a41a28bda936ea627afbfe94a7f5cd63f23cf727 (patch) | |
tree | 4ec92f87632ab0e5e5ec018018a6a5e513bbdf7d | |
parent | 53ef1016fd0e4bab128a24f7fe06b9cdb2afdc31 (diff) |
CIFS: Move creating lease buffer to ops struct
to make adding new types of lease buffers easier.
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r-- | fs/cifs/cifsglob.h | 9 | ||||
-rw-r--r-- | fs/cifs/smb2ops.c | 41 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.c | 53 |
3 files changed, 58 insertions, 45 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index e87f89f778f4..cb53e24ae9b2 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -361,11 +361,11 @@ struct smb_version_operations { | |||
361 | /* push brlocks from the cache to the server */ | 361 | /* push brlocks from the cache to the server */ |
362 | int (*push_mand_locks)(struct cifsFileInfo *); | 362 | int (*push_mand_locks)(struct cifsFileInfo *); |
363 | /* get lease key of the inode */ | 363 | /* get lease key of the inode */ |
364 | void (*get_lease_key)(struct inode *, struct cifs_fid *fid); | 364 | void (*get_lease_key)(struct inode *, struct cifs_fid *); |
365 | /* set lease key of the inode */ | 365 | /* set lease key of the inode */ |
366 | void (*set_lease_key)(struct inode *, struct cifs_fid *fid); | 366 | void (*set_lease_key)(struct inode *, struct cifs_fid *); |
367 | /* generate new lease key */ | 367 | /* generate new lease key */ |
368 | void (*new_lease_key)(struct cifs_fid *fid); | 368 | void (*new_lease_key)(struct cifs_fid *); |
369 | int (*generate_signingkey)(struct cifs_ses *); | 369 | int (*generate_signingkey)(struct cifs_ses *); |
370 | int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *); | 370 | int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *); |
371 | int (*query_mf_symlink)(const unsigned char *, char *, unsigned int *, | 371 | int (*query_mf_symlink)(const unsigned char *, char *, unsigned int *, |
@@ -374,6 +374,8 @@ struct smb_version_operations { | |||
374 | bool (*is_read_op)(__u32); | 374 | bool (*is_read_op)(__u32); |
375 | /* set oplock level for the inode */ | 375 | /* set oplock level for the inode */ |
376 | void (*set_oplock_level)(struct cifsInodeInfo *, __u32); | 376 | void (*set_oplock_level)(struct cifsInodeInfo *, __u32); |
377 | /* create lease context buffer for CREATE request */ | ||
378 | char * (*create_lease_buf)(u8 *, u8); | ||
377 | }; | 379 | }; |
378 | 380 | ||
379 | struct smb_version_values { | 381 | struct smb_version_values { |
@@ -393,6 +395,7 @@ struct smb_version_values { | |||
393 | unsigned int cap_large_files; | 395 | unsigned int cap_large_files; |
394 | __u16 signing_enabled; | 396 | __u16 signing_enabled; |
395 | __u16 signing_required; | 397 | __u16 signing_required; |
398 | size_t create_lease_size; | ||
396 | }; | 399 | }; |
397 | 400 | ||
398 | #define HEADER_SIZE(server) (server->vals->header_size) | 401 | #define HEADER_SIZE(server) (server->vals->header_size) |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 4656656d5c0f..ecff4d6e4b16 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -714,6 +714,40 @@ 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 char * | ||
718 | smb2_create_lease_buf(u8 *lease_key, u8 oplock) | ||
719 | { | ||
720 | struct create_lease *buf; | ||
721 | |||
722 | buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL); | ||
723 | if (!buf) | ||
724 | return NULL; | ||
725 | |||
726 | buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key)); | ||
727 | buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8))); | ||
728 | if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) | ||
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 | |||
738 | buf->ccontext.DataOffset = cpu_to_le16(offsetof | ||
739 | (struct create_lease, lcontext)); | ||
740 | buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context)); | ||
741 | buf->ccontext.NameOffset = cpu_to_le16(offsetof | ||
742 | (struct create_lease, Name)); | ||
743 | buf->ccontext.NameLength = cpu_to_le16(4); | ||
744 | buf->Name[0] = 'R'; | ||
745 | buf->Name[1] = 'q'; | ||
746 | buf->Name[2] = 'L'; | ||
747 | buf->Name[3] = 's'; | ||
748 | return (char *)buf; | ||
749 | } | ||
750 | |||
717 | struct smb_version_operations smb20_operations = { | 751 | struct smb_version_operations smb20_operations = { |
718 | .compare_fids = smb2_compare_fids, | 752 | .compare_fids = smb2_compare_fids, |
719 | .setup_request = smb2_setup_request, | 753 | .setup_request = smb2_setup_request, |
@@ -781,6 +815,7 @@ struct smb_version_operations smb20_operations = { | |||
781 | .calc_signature = smb2_calc_signature, | 815 | .calc_signature = smb2_calc_signature, |
782 | .is_read_op = smb2_is_read_op, | 816 | .is_read_op = smb2_is_read_op, |
783 | .set_oplock_level = smb2_set_oplock_level, | 817 | .set_oplock_level = smb2_set_oplock_level, |
818 | .create_lease_buf = smb2_create_lease_buf, | ||
784 | }; | 819 | }; |
785 | 820 | ||
786 | struct smb_version_operations smb21_operations = { | 821 | struct smb_version_operations smb21_operations = { |
@@ -850,6 +885,7 @@ struct smb_version_operations smb21_operations = { | |||
850 | .calc_signature = smb2_calc_signature, | 885 | .calc_signature = smb2_calc_signature, |
851 | .is_read_op = smb21_is_read_op, | 886 | .is_read_op = smb21_is_read_op, |
852 | .set_oplock_level = smb21_set_oplock_level, | 887 | .set_oplock_level = smb21_set_oplock_level, |
888 | .create_lease_buf = smb2_create_lease_buf, | ||
853 | }; | 889 | }; |
854 | 890 | ||
855 | struct smb_version_operations smb30_operations = { | 891 | struct smb_version_operations smb30_operations = { |
@@ -921,6 +957,7 @@ struct smb_version_operations smb30_operations = { | |||
921 | .calc_signature = smb3_calc_signature, | 957 | .calc_signature = smb3_calc_signature, |
922 | .is_read_op = smb21_is_read_op, | 958 | .is_read_op = smb21_is_read_op, |
923 | .set_oplock_level = smb21_set_oplock_level, | 959 | .set_oplock_level = smb21_set_oplock_level, |
960 | .create_lease_buf = smb2_create_lease_buf, | ||
924 | }; | 961 | }; |
925 | 962 | ||
926 | struct smb_version_values smb20_values = { | 963 | struct smb_version_values smb20_values = { |
@@ -940,6 +977,7 @@ struct smb_version_values smb20_values = { | |||
940 | .cap_large_files = SMB2_LARGE_FILES, | 977 | .cap_large_files = SMB2_LARGE_FILES, |
941 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, | 978 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, |
942 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, | 979 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, |
980 | .create_lease_size = sizeof(struct create_lease), | ||
943 | }; | 981 | }; |
944 | 982 | ||
945 | struct smb_version_values smb21_values = { | 983 | struct smb_version_values smb21_values = { |
@@ -959,6 +997,7 @@ struct smb_version_values smb21_values = { | |||
959 | .cap_large_files = SMB2_LARGE_FILES, | 997 | .cap_large_files = SMB2_LARGE_FILES, |
960 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, | 998 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, |
961 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, | 999 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, |
1000 | .create_lease_size = sizeof(struct create_lease), | ||
962 | }; | 1001 | }; |
963 | 1002 | ||
964 | struct smb_version_values smb30_values = { | 1003 | struct smb_version_values smb30_values = { |
@@ -978,6 +1017,7 @@ struct smb_version_values smb30_values = { | |||
978 | .cap_large_files = SMB2_LARGE_FILES, | 1017 | .cap_large_files = SMB2_LARGE_FILES, |
979 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, | 1018 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, |
980 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, | 1019 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, |
1020 | .create_lease_size = sizeof(struct create_lease), | ||
981 | }; | 1021 | }; |
982 | 1022 | ||
983 | struct smb_version_values smb302_values = { | 1023 | struct smb_version_values smb302_values = { |
@@ -997,4 +1037,5 @@ struct smb_version_values smb302_values = { | |||
997 | .cap_large_files = SMB2_LARGE_FILES, | 1037 | .cap_large_files = SMB2_LARGE_FILES, |
998 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, | 1038 | .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED, |
999 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, | 1039 | .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, |
1040 | .create_lease_size = sizeof(struct create_lease), | ||
1000 | }; | 1041 | }; |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index fdf697bcdf9f..f5f1f5341f04 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -855,39 +855,6 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon) | |||
855 | return rc; | 855 | return rc; |
856 | } | 856 | } |
857 | 857 | ||
858 | static struct create_lease * | ||
859 | create_lease_buf(u8 *lease_key, u8 oplock) | ||
860 | { | ||
861 | struct create_lease *buf; | ||
862 | |||
863 | buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL); | ||
864 | if (!buf) | ||
865 | return NULL; | ||
866 | |||
867 | buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key)); | ||
868 | buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8))); | ||
869 | if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) | ||
870 | buf->lcontext.LeaseState = SMB2_LEASE_WRITE_CACHING | | ||
871 | SMB2_LEASE_READ_CACHING; | ||
872 | else if (oplock == SMB2_OPLOCK_LEVEL_II) | ||
873 | buf->lcontext.LeaseState = SMB2_LEASE_READ_CACHING; | ||
874 | else if (oplock == SMB2_OPLOCK_LEVEL_BATCH) | ||
875 | buf->lcontext.LeaseState = SMB2_LEASE_HANDLE_CACHING | | ||
876 | SMB2_LEASE_READ_CACHING | | ||
877 | SMB2_LEASE_WRITE_CACHING; | ||
878 | |||
879 | buf->ccontext.DataOffset = cpu_to_le16(offsetof | ||
880 | (struct create_lease, lcontext)); | ||
881 | buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context)); | ||
882 | buf->ccontext.NameOffset = cpu_to_le16(offsetof | ||
883 | (struct create_lease, Name)); | ||
884 | buf->ccontext.NameLength = cpu_to_le16(4); | ||
885 | buf->Name[0] = 'R'; | ||
886 | buf->Name[1] = 'q'; | ||
887 | buf->Name[2] = 'L'; | ||
888 | buf->Name[3] = 's'; | ||
889 | return buf; | ||
890 | } | ||
891 | 858 | ||
892 | static struct create_durable * | 859 | static struct create_durable * |
893 | create_durable_buf(void) | 860 | create_durable_buf(void) |
@@ -967,22 +934,24 @@ parse_lease_state(struct smb2_create_rsp *rsp) | |||
967 | } | 934 | } |
968 | 935 | ||
969 | static int | 936 | static int |
970 | add_lease_context(struct kvec *iov, unsigned int *num_iovec, __u8 *oplock) | 937 | add_lease_context(struct TCP_Server_Info *server, struct kvec *iov, |
938 | unsigned int *num_iovec, __u8 *oplock) | ||
971 | { | 939 | { |
972 | struct smb2_create_req *req = iov[0].iov_base; | 940 | struct smb2_create_req *req = iov[0].iov_base; |
973 | unsigned int num = *num_iovec; | 941 | unsigned int num = *num_iovec; |
974 | 942 | ||
975 | iov[num].iov_base = create_lease_buf(oplock+1, *oplock); | 943 | iov[num].iov_base = server->ops->create_lease_buf(oplock+1, *oplock); |
976 | if (iov[num].iov_base == NULL) | 944 | if (iov[num].iov_base == NULL) |
977 | return -ENOMEM; | 945 | return -ENOMEM; |
978 | iov[num].iov_len = sizeof(struct create_lease); | 946 | iov[num].iov_len = server->vals->create_lease_size; |
979 | req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_LEASE; | 947 | req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_LEASE; |
980 | if (!req->CreateContextsOffset) | 948 | if (!req->CreateContextsOffset) |
981 | req->CreateContextsOffset = cpu_to_le32( | 949 | req->CreateContextsOffset = cpu_to_le32( |
982 | sizeof(struct smb2_create_req) - 4 + | 950 | sizeof(struct smb2_create_req) - 4 + |
983 | iov[num - 1].iov_len); | 951 | iov[num - 1].iov_len); |
984 | le32_add_cpu(&req->CreateContextsLength, sizeof(struct create_lease)); | 952 | le32_add_cpu(&req->CreateContextsLength, |
985 | inc_rfc1001_len(&req->hdr, sizeof(struct create_lease)); | 953 | server->vals->create_lease_size); |
954 | inc_rfc1001_len(&req->hdr, server->vals->create_lease_size); | ||
986 | *num_iovec = num + 1; | 955 | *num_iovec = num + 1; |
987 | return 0; | 956 | return 0; |
988 | } | 957 | } |
@@ -1087,11 +1056,11 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, | |||
1087 | if (!server->oplocks) | 1056 | if (!server->oplocks) |
1088 | *oplock = SMB2_OPLOCK_LEVEL_NONE; | 1057 | *oplock = SMB2_OPLOCK_LEVEL_NONE; |
1089 | 1058 | ||
1090 | if (!(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) || | 1059 | if (!(server->capabilities & SMB2_GLOBAL_CAP_LEASING) || |
1091 | *oplock == SMB2_OPLOCK_LEVEL_NONE) | 1060 | *oplock == SMB2_OPLOCK_LEVEL_NONE) |
1092 | req->RequestedOplockLevel = *oplock; | 1061 | req->RequestedOplockLevel = *oplock; |
1093 | else { | 1062 | else { |
1094 | rc = add_lease_context(iov, &num_iovecs, oplock); | 1063 | rc = add_lease_context(server, iov, &num_iovecs, oplock); |
1095 | if (rc) { | 1064 | if (rc) { |
1096 | cifs_small_buf_release(req); | 1065 | cifs_small_buf_release(req); |
1097 | kfree(copy_path); | 1066 | kfree(copy_path); |
@@ -1101,11 +1070,11 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, | |||
1101 | 1070 | ||
1102 | if (*oplock == SMB2_OPLOCK_LEVEL_BATCH) { | 1071 | if (*oplock == SMB2_OPLOCK_LEVEL_BATCH) { |
1103 | /* need to set Next field of lease context if we request it */ | 1072 | /* need to set Next field of lease context if we request it */ |
1104 | if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) { | 1073 | if (server->capabilities & SMB2_GLOBAL_CAP_LEASING) { |
1105 | struct create_context *ccontext = | 1074 | struct create_context *ccontext = |
1106 | (struct create_context *)iov[num_iovecs-1].iov_base; | 1075 | (struct create_context *)iov[num_iovecs-1].iov_base; |
1107 | ccontext->Next = | 1076 | ccontext->Next = |
1108 | cpu_to_le32(sizeof(struct create_lease)); | 1077 | cpu_to_le32(server->vals->create_lease_size); |
1109 | } | 1078 | } |
1110 | rc = add_durable_context(iov, &num_iovecs, oparms); | 1079 | rc = add_durable_context(iov, &num_iovecs, oparms); |
1111 | if (rc) { | 1080 | if (rc) { |