diff options
author | Pavel Shilovsky <pshilovsky@samba.org> | 2013-07-04 11:41:24 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-07-10 14:08:39 -0400 |
commit | 59aa371841ddb3a1a434497c6590542a785fa37c (patch) | |
tree | 204bdacd79f3a1685c5b61710cac597fd03555d5 /fs | |
parent | ca81983fe5e095ee90c0f7b6013e7c446af17088 (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.c | 59 | ||||
-rw-r--r-- | fs/cifs/smb2pdu.h | 2 |
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 | ||
434 | struct smb2_create_rsp { | 434 | struct smb2_create_rsp { |