aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorPavel Shilovsky <pshilovsky@samba.org>2013-07-04 11:41:24 -0400
committerSteve French <smfrench@gmail.com>2013-07-10 14:08:39 -0400
commit59aa371841ddb3a1a434497c6590542a785fa37c (patch)
tree204bdacd79f3a1685c5b61710cac597fd03555d5 /fs
parentca81983fe5e095ee90c0f7b6013e7c446af17088 (diff)
CIFS: Simplify SMB2_open code path
by passing a filename to a separate iovec regardless of its length. Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steven French <steven@steven-GA-970A-DS3.(none)>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/smb2pdu.c59
-rw-r--r--fs/cifs/smb2pdu.h2
2 files changed, 25 insertions, 36 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 4c046a5b81af..9a35dcda9099 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -894,7 +894,7 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
894 __le16 *copy_path = NULL; 894 __le16 *copy_path = NULL;
895 int copy_size; 895 int copy_size;
896 int rc = 0; 896 int rc = 0;
897 int num_iovecs = 2; 897 unsigned int num_iovecs = 2;
898 __u32 file_attributes = 0; 898 __u32 file_attributes = 0;
899 899
900 cifs_dbg(FYI, "create/open\n"); 900 cifs_dbg(FYI, "create/open\n");
@@ -919,47 +919,36 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
919 req->CreateDisposition = cpu_to_le32(create_disposition); 919 req->CreateDisposition = cpu_to_le32(create_disposition);
920 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); 920 req->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
921 uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2; 921 uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
922 req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req) 922 /* do not count rfc1001 len field */
923 - 8 /* pad */ - 4 /* do not count rfc1001 len field */); 923 req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req) - 4);
924 924
925 iov[0].iov_base = (char *)req; 925 iov[0].iov_base = (char *)req;
926 /* 4 for rfc1002 length field */ 926 /* 4 for rfc1002 length field */
927 iov[0].iov_len = get_rfc1002_length(req) + 4; 927 iov[0].iov_len = get_rfc1002_length(req) + 4;
928 928
929 /* MUST set path len (NameLength) to 0 opening root of share */ 929 /* MUST set path len (NameLength) to 0 opening root of share */
930 if (uni_path_len >= 4) { 930 req->NameLength = cpu_to_le16(uni_path_len - 2);
931 req->NameLength = cpu_to_le16(uni_path_len - 2); 931 /* -1 since last byte is buf[0] which is sent below (path) */
932 /* -1 since last byte is buf[0] which is sent below (path) */ 932 iov[0].iov_len--;
933 iov[0].iov_len--; 933 if (uni_path_len % 8 != 0) {
934 if (uni_path_len % 8 != 0) { 934 copy_size = uni_path_len / 8 * 8;
935 copy_size = uni_path_len / 8 * 8; 935 if (copy_size < uni_path_len)
936 if (copy_size < uni_path_len) 936 copy_size += 8;
937 copy_size += 8; 937
938 938 copy_path = kzalloc(copy_size, GFP_KERNEL);
939 copy_path = kzalloc(copy_size, GFP_KERNEL); 939 if (!copy_path)
940 if (!copy_path) 940 return -ENOMEM;
941 return -ENOMEM; 941 memcpy((char *)copy_path, (const char *)path,
942 memcpy((char *)copy_path, (const char *)path, 942 uni_path_len);
943 uni_path_len); 943 uni_path_len = copy_size;
944 uni_path_len = copy_size; 944 path = copy_path;
945 path = copy_path;
946 }
947
948 iov[1].iov_len = uni_path_len;
949 iov[1].iov_base = path;
950 /*
951 * -1 since last byte is buf[0] which was counted in
952 * smb2_buf_len.
953 */
954 inc_rfc1001_len(req, uni_path_len - 1);
955 } else {
956 iov[0].iov_len += 7;
957 req->hdr.smb2_buf_length = cpu_to_be32(be32_to_cpu(
958 req->hdr.smb2_buf_length) + 8 - 1);
959 num_iovecs = 1;
960 req->NameLength = 0;
961 } 945 }
962 946
947 iov[1].iov_len = uni_path_len;
948 iov[1].iov_base = path;
949 /* -1 since last byte is buf[0] which was counted in smb2_buf_len */
950 inc_rfc1001_len(req, uni_path_len - 1);
951
963 if (!server->oplocks) 952 if (!server->oplocks)
964 *oplock = SMB2_OPLOCK_LEVEL_NONE; 953 *oplock = SMB2_OPLOCK_LEVEL_NONE;
965 954
@@ -976,7 +965,7 @@ SMB2_open(const unsigned int xid, struct cifs_tcon *tcon, __le16 *path,
976 iov[num_iovecs].iov_len = sizeof(struct create_lease); 965 iov[num_iovecs].iov_len = sizeof(struct create_lease);
977 req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_LEASE; 966 req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_LEASE;
978 req->CreateContextsOffset = cpu_to_le32( 967 req->CreateContextsOffset = cpu_to_le32(
979 sizeof(struct smb2_create_req) - 4 - 8 + 968 sizeof(struct smb2_create_req) - 4 +
980 iov[num_iovecs-1].iov_len); 969 iov[num_iovecs-1].iov_len);
981 req->CreateContextsLength = cpu_to_le32( 970 req->CreateContextsLength = cpu_to_le32(
982 sizeof(struct create_lease)); 971 sizeof(struct create_lease));
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
index f31043b26bd3..8b1025f6f0da 100644
--- a/fs/cifs/smb2pdu.h
+++ b/fs/cifs/smb2pdu.h
@@ -428,7 +428,7 @@ struct smb2_create_req {
428 __le16 NameLength; 428 __le16 NameLength;
429 __le32 CreateContextsOffset; 429 __le32 CreateContextsOffset;
430 __le32 CreateContextsLength; 430 __le32 CreateContextsLength;
431 __u8 Buffer[8]; 431 __u8 Buffer[0];
432} __packed; 432} __packed;
433 433
434struct smb2_create_rsp { 434struct smb2_create_rsp {