@@ -2052,43 +2052,27 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
2052
2052
}
2053
2053
2054
2054
int
2055
- SMB2_open (const unsigned int xid , struct cifs_open_parms * oparms , __le16 * path ,
2056
- __u8 * oplock , struct smb2_file_all_info * buf ,
2057
- struct kvec * err_iov , int * buftype )
2055
+ SMB2_open_init (struct cifs_tcon * tcon , struct smb_rqst * rqst , __u8 * oplock ,
2056
+ struct cifs_open_parms * oparms , __le16 * path )
2058
2057
{
2059
- struct smb_rqst rqst ;
2058
+ struct TCP_Server_Info * server = tcon -> ses -> server ;
2060
2059
struct smb2_create_req * req ;
2061
- struct smb2_create_rsp * rsp ;
2062
- struct TCP_Server_Info * server ;
2063
- struct cifs_tcon * tcon = oparms -> tcon ;
2064
- struct cifs_ses * ses = tcon -> ses ;
2065
- struct kvec iov [5 ]; /* make sure at least one for each open context */
2066
- struct kvec rsp_iov = {NULL , 0 };
2067
- int resp_buftype ;
2068
- int uni_path_len ;
2069
- __le16 * copy_path = NULL ;
2070
- int copy_size ;
2071
- int rc = 0 ;
2072
2060
unsigned int n_iov = 2 ;
2073
2061
__u32 file_attributes = 0 ;
2074
- char * dhc_buf = NULL , * lc_buf = NULL , * pc_buf = NULL ;
2075
- int flags = 0 ;
2062
+ int copy_size ;
2063
+ int uni_path_len ;
2076
2064
unsigned int total_len ;
2077
-
2078
- cifs_dbg (FYI , "create/open\n" );
2079
-
2080
- if (ses && (ses -> server ))
2081
- server = ses -> server ;
2082
- else
2083
- return - EIO ;
2065
+ struct kvec * iov = rqst -> rq_iov ;
2066
+ __le16 * copy_path ;
2067
+ int rc ;
2084
2068
2085
2069
rc = smb2_plain_req_init (SMB2_CREATE , tcon , (void * * ) & req , & total_len );
2086
-
2087
2070
if (rc )
2088
2071
return rc ;
2089
2072
2090
- if (smb3_encryption_required (tcon ))
2091
- flags |= CIFS_TRANSFORM_REQ ;
2073
+ iov [0 ].iov_base = (char * )req ;
2074
+ /* -1 since last byte is buf[0] which is sent below (path) */
2075
+ iov [0 ].iov_len = total_len - 1 ;
2092
2076
2093
2077
if (oparms -> create_options & CREATE_OPTION_READONLY )
2094
2078
file_attributes |= ATTR_READONLY ;
@@ -2102,11 +2086,6 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
2102
2086
req -> ShareAccess = FILE_SHARE_ALL_LE ;
2103
2087
req -> CreateDisposition = cpu_to_le32 (oparms -> disposition );
2104
2088
req -> CreateOptions = cpu_to_le32 (oparms -> create_options & CREATE_OPTIONS_MASK );
2105
-
2106
- iov [0 ].iov_base = (char * )req ;
2107
- /* -1 since last byte is buf[0] which is sent below (path) */
2108
- iov [0 ].iov_len = total_len - 1 ;
2109
-
2110
2089
req -> NameOffset = cpu_to_le16 (sizeof (struct smb2_create_req ));
2111
2090
2112
2091
/* [MS-SMB2] 2.2.13 NameOffset:
@@ -2124,29 +2103,25 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
2124
2103
rc = alloc_path_with_tree_prefix (& copy_path , & copy_size ,
2125
2104
& name_len ,
2126
2105
tcon -> treeName , path );
2127
- if (rc ) {
2128
- cifs_small_buf_release (req );
2106
+ if (rc )
2129
2107
return rc ;
2130
- }
2131
2108
req -> NameLength = cpu_to_le16 (name_len * 2 );
2132
2109
uni_path_len = copy_size ;
2133
2110
path = copy_path ;
2134
2111
} else {
2135
2112
uni_path_len = (2 * UniStrnlen ((wchar_t * )path , PATH_MAX )) + 2 ;
2136
2113
/* MUST set path len (NameLength) to 0 opening root of share */
2137
2114
req -> NameLength = cpu_to_le16 (uni_path_len - 2 );
2138
- if (uni_path_len % 8 != 0 ) {
2139
- copy_size = roundup (uni_path_len , 8 );
2140
- copy_path = kzalloc (copy_size , GFP_KERNEL );
2141
- if (!copy_path ) {
2142
- cifs_small_buf_release (req );
2143
- return - ENOMEM ;
2144
- }
2145
- memcpy ((char * )copy_path , (const char * )path ,
2146
- uni_path_len );
2147
- uni_path_len = copy_size ;
2148
- path = copy_path ;
2149
- }
2115
+ copy_size = uni_path_len ;
2116
+ if (copy_size % 8 != 0 )
2117
+ copy_size = roundup (copy_size , 8 );
2118
+ copy_path = kzalloc (copy_size , GFP_KERNEL );
2119
+ if (!copy_path )
2120
+ return - ENOMEM ;
2121
+ memcpy ((char * )copy_path , (const char * )path ,
2122
+ uni_path_len );
2123
+ uni_path_len = copy_size ;
2124
+ path = copy_path ;
2150
2125
}
2151
2126
2152
2127
iov [1 ].iov_len = uni_path_len ;
@@ -2161,12 +2136,8 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
2161
2136
else {
2162
2137
rc = add_lease_context (server , iov , & n_iov ,
2163
2138
oparms -> fid -> lease_key , oplock );
2164
- if (rc ) {
2165
- cifs_small_buf_release (req );
2166
- kfree (copy_path );
2139
+ if (rc )
2167
2140
return rc ;
2168
- }
2169
- lc_buf = iov [n_iov - 1 ].iov_base ;
2170
2141
}
2171
2142
2172
2143
if (* oplock == SMB2_OPLOCK_LEVEL_BATCH ) {
@@ -2180,13 +2151,8 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
2180
2151
2181
2152
rc = add_durable_context (iov , & n_iov , oparms ,
2182
2153
tcon -> use_persistent );
2183
- if (rc ) {
2184
- cifs_small_buf_release (req );
2185
- kfree (copy_path );
2186
- kfree (lc_buf );
2154
+ if (rc )
2187
2155
return rc ;
2188
- }
2189
- dhc_buf = iov [n_iov - 1 ].iov_base ;
2190
2156
}
2191
2157
2192
2158
if (tcon -> posix_extensions ) {
@@ -2198,23 +2164,63 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
2198
2164
}
2199
2165
2200
2166
rc = add_posix_context (iov , & n_iov , oparms -> mode );
2201
- if (rc ) {
2202
- cifs_small_buf_release (req );
2203
- kfree (copy_path );
2204
- kfree (lc_buf );
2205
- kfree (dhc_buf );
2167
+ if (rc )
2206
2168
return rc ;
2207
- }
2208
- pc_buf = iov [n_iov - 1 ].iov_base ;
2209
2169
}
2210
2170
2171
+ rqst -> rq_nvec = n_iov ;
2172
+ return 0 ;
2173
+ }
2174
+
2175
+ /* rq_iov[0] is the request and is released by cifs_small_buf_release().
2176
+ * All other vectors are freed by kfree().
2177
+ */
2178
+ void
2179
+ SMB2_open_free (struct smb_rqst * rqst )
2180
+ {
2181
+ int i ;
2182
+
2183
+ cifs_small_buf_release (rqst -> rq_iov [0 ].iov_base );
2184
+ for (i = 1 ; i < rqst -> rq_nvec ; i ++ )
2185
+ kfree (rqst -> rq_iov [i ].iov_base );
2186
+ }
2187
+
2188
+ int
2189
+ SMB2_open (const unsigned int xid , struct cifs_open_parms * oparms , __le16 * path ,
2190
+ __u8 * oplock , struct smb2_file_all_info * buf ,
2191
+ struct kvec * err_iov , int * buftype )
2192
+ {
2193
+ struct smb_rqst rqst ;
2194
+ struct smb2_create_rsp * rsp = NULL ;
2195
+ struct TCP_Server_Info * server ;
2196
+ struct cifs_tcon * tcon = oparms -> tcon ;
2197
+ struct cifs_ses * ses = tcon -> ses ;
2198
+ struct kvec iov [5 ]; /* make sure at least one for each open context */
2199
+ struct kvec rsp_iov = {NULL , 0 };
2200
+ int resp_buftype ;
2201
+ int rc = 0 ;
2202
+ int flags = 0 ;
2203
+
2204
+ cifs_dbg (FYI , "create/open\n" );
2205
+ if (ses && (ses -> server ))
2206
+ server = ses -> server ;
2207
+ else
2208
+ return - EIO ;
2209
+
2210
+ if (smb3_encryption_required (tcon ))
2211
+ flags |= CIFS_TRANSFORM_REQ ;
2212
+
2211
2213
memset (& rqst , 0 , sizeof (struct smb_rqst ));
2214
+ memset (& iov , 0 , sizeof (iov ));
2212
2215
rqst .rq_iov = iov ;
2213
- rqst .rq_nvec = n_iov ;
2216
+ rqst .rq_nvec = 5 ;
2217
+
2218
+ rc = SMB2_open_init (tcon , & rqst , oplock , oparms , path );
2219
+ if (rc )
2220
+ goto creat_exit ;
2214
2221
2215
2222
rc = cifs_send_recv (xid , ses , & rqst , & resp_buftype , flags ,
2216
2223
& rsp_iov );
2217
- cifs_small_buf_release (req );
2218
2224
rsp = (struct smb2_create_rsp * )rsp_iov .iov_base ;
2219
2225
2220
2226
if (rc != 0 ) {
@@ -2251,10 +2257,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
2251
2257
else
2252
2258
* oplock = rsp -> OplockLevel ;
2253
2259
creat_exit :
2254
- kfree (copy_path );
2255
- kfree (lc_buf );
2256
- kfree (dhc_buf );
2257
- kfree (pc_buf );
2260
+ SMB2_open_free (& rqst );
2258
2261
free_rsp_buf (resp_buftype , rsp );
2259
2262
return rc ;
2260
2263
}
0 commit comments