@@ -2052,43 +2052,27 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
20522052}
20532053
20542054int
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 )
20582057{
2059- struct smb_rqst rqst ;
2058+ struct TCP_Server_Info * server = tcon -> ses -> server ;
20602059 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 ;
20722060 unsigned int n_iov = 2 ;
20732061 __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 ;
20762064 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 ;
20842068
20852069 rc = smb2_plain_req_init (SMB2_CREATE , tcon , (void * * ) & req , & total_len );
2086-
20872070 if (rc )
20882071 return rc ;
20892072
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 ;
20922076
20932077 if (oparms -> create_options & CREATE_OPTION_READONLY )
20942078 file_attributes |= ATTR_READONLY ;
@@ -2102,11 +2086,6 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
21022086 req -> ShareAccess = FILE_SHARE_ALL_LE ;
21032087 req -> CreateDisposition = cpu_to_le32 (oparms -> disposition );
21042088 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-
21102089 req -> NameOffset = cpu_to_le16 (sizeof (struct smb2_create_req ));
21112090
21122091 /* [MS-SMB2] 2.2.13 NameOffset:
@@ -2124,29 +2103,25 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
21242103 rc = alloc_path_with_tree_prefix (& copy_path , & copy_size ,
21252104 & name_len ,
21262105 tcon -> treeName , path );
2127- if (rc ) {
2128- cifs_small_buf_release (req );
2106+ if (rc )
21292107 return rc ;
2130- }
21312108 req -> NameLength = cpu_to_le16 (name_len * 2 );
21322109 uni_path_len = copy_size ;
21332110 path = copy_path ;
21342111 } else {
21352112 uni_path_len = (2 * UniStrnlen ((wchar_t * )path , PATH_MAX )) + 2 ;
21362113 /* MUST set path len (NameLength) to 0 opening root of share */
21372114 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 ;
21502125 }
21512126
21522127 iov [1 ].iov_len = uni_path_len ;
@@ -2161,12 +2136,8 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
21612136 else {
21622137 rc = add_lease_context (server , iov , & n_iov ,
21632138 oparms -> fid -> lease_key , oplock );
2164- if (rc ) {
2165- cifs_small_buf_release (req );
2166- kfree (copy_path );
2139+ if (rc )
21672140 return rc ;
2168- }
2169- lc_buf = iov [n_iov - 1 ].iov_base ;
21702141 }
21712142
21722143 if (* oplock == SMB2_OPLOCK_LEVEL_BATCH ) {
@@ -2180,13 +2151,8 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
21802151
21812152 rc = add_durable_context (iov , & n_iov , oparms ,
21822153 tcon -> use_persistent );
2183- if (rc ) {
2184- cifs_small_buf_release (req );
2185- kfree (copy_path );
2186- kfree (lc_buf );
2154+ if (rc )
21872155 return rc ;
2188- }
2189- dhc_buf = iov [n_iov - 1 ].iov_base ;
21902156 }
21912157
21922158 if (tcon -> posix_extensions ) {
@@ -2198,23 +2164,63 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
21982164 }
21992165
22002166 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 )
22062168 return rc ;
2207- }
2208- pc_buf = iov [n_iov - 1 ].iov_base ;
22092169 }
22102170
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+
22112213 memset (& rqst , 0 , sizeof (struct smb_rqst ));
2214+ memset (& iov , 0 , sizeof (iov ));
22122215 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 ;
22142221
22152222 rc = cifs_send_recv (xid , ses , & rqst , & resp_buftype , flags ,
22162223 & rsp_iov );
2217- cifs_small_buf_release (req );
22182224 rsp = (struct smb2_create_rsp * )rsp_iov .iov_base ;
22192225
22202226 if (rc != 0 ) {
@@ -2251,10 +2257,7 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
22512257 else
22522258 * oplock = rsp -> OplockLevel ;
22532259creat_exit :
2254- kfree (copy_path );
2255- kfree (lc_buf );
2256- kfree (dhc_buf );
2257- kfree (pc_buf );
2260+ SMB2_open_free (& rqst );
22582261 free_rsp_buf (resp_buftype , rsp );
22592262 return rc ;
22602263}
0 commit comments