aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2013-09-04 05:07:41 -0400
committerSteve French <smfrench@gmail.com>2013-09-09 23:52:08 -0400
commita41a28bda936ea627afbfe94a7f5cd63f23cf727 (patch)
tree4ec92f87632ab0e5e5ec018018a6a5e513bbdf7d
parent53ef1016fd0e4bab128a24f7fe06b9cdb2afdc31 (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.h9
-rw-r--r--fs/cifs/smb2ops.c41
-rw-r--r--fs/cifs/smb2pdu.c53
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
379struct smb_version_values { 381struct 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
717static char *
718smb2_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
717struct smb_version_operations smb20_operations = { 751struct 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
786struct smb_version_operations smb21_operations = { 821struct 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
855struct smb_version_operations smb30_operations = { 891struct 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
926struct smb_version_values smb20_values = { 963struct 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
945struct smb_version_values smb21_values = { 983struct 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
964struct smb_version_values smb30_values = { 1003struct 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
983struct smb_version_values smb302_values = { 1023struct 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
858static struct create_lease *
859create_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
892static struct create_durable * 859static struct create_durable *
893create_durable_buf(void) 860create_durable_buf(void)
@@ -967,22 +934,24 @@ parse_lease_state(struct smb2_create_rsp *rsp)
967} 934}
968 935
969static int 936static int
970add_lease_context(struct kvec *iov, unsigned int *num_iovec, __u8 *oplock) 937add_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) {