Skip to content

Commit 1eb9fb5

Browse files
Ronnie SahlbergSteve French
authored andcommitted
cifs: create SMB2_open_init()/SMB2_open_free() helpers.
Signed-off-by: Ronnie Sahlberg <[email protected]> Signed-off-by: Steve French <[email protected]> Reviewed-by: Paulo Alcantara <[email protected]> Reviewed-by: Pavel Shilovsky <[email protected]>
1 parent 296ecba commit 1eb9fb5

File tree

2 files changed

+78
-71
lines changed

2 files changed

+78
-71
lines changed

fs/cifs/smb2pdu.c

Lines changed: 74 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,43 +2052,27 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
20522052
}
20532053

20542054
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)
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;
22532259
creat_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
}

fs/cifs/smb2proto.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms,
133133
__le16 *path, __u8 *oplock,
134134
struct smb2_file_all_info *buf,
135135
struct kvec *err_iov, int *resp_buftype);
136+
extern int SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
137+
__u8 *oplock, struct cifs_open_parms *oparms,
138+
__le16 *path);
139+
extern void SMB2_open_free(struct smb_rqst *rqst);
136140
extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon,
137141
u64 persistent_fid, u64 volatile_fid, u32 opcode,
138142
bool is_fsctl, char *in_data, u32 indatalen,

0 commit comments

Comments
 (0)