|
@@ -602,6 +602,7 @@ static void assemble_neg_contexts(struct smb2_negotiate_req *req,
|
|
|
int
|
|
|
SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_negotiate_req *req;
|
|
|
struct smb2_negotiate_rsp *rsp;
|
|
|
struct kvec iov[1];
|
|
@@ -673,7 +674,11 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses)
|
|
|
iov[0].iov_base = (char *)req;
|
|
|
iov[0].iov_len = total_len;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
rsp = (struct smb2_negotiate_rsp *)rsp_iov.iov_base;
|
|
|
/*
|
|
@@ -990,8 +995,9 @@ SMB2_sess_alloc_buffer(struct SMB2_sess_data *sess_data)
|
|
|
req->PreviousSessionId = sess_data->previous_session;
|
|
|
|
|
|
req->Flags = 0; /* MBZ */
|
|
|
- /* to enable echos and oplocks */
|
|
|
- req->sync_hdr.CreditRequest = cpu_to_le16(3);
|
|
|
+
|
|
|
+ /* enough to enable echos and oplocks and one max size write */
|
|
|
+ req->sync_hdr.CreditRequest = cpu_to_le16(130);
|
|
|
|
|
|
/* only one of SMB2 signing flags may be set in SMB2 request */
|
|
|
if (server->sign)
|
|
@@ -1027,6 +1033,7 @@ static int
|
|
|
SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data)
|
|
|
{
|
|
|
int rc;
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_sess_setup_req *req = sess_data->iov[0].iov_base;
|
|
|
struct kvec rsp_iov = { NULL, 0 };
|
|
|
|
|
@@ -1035,10 +1042,13 @@ SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data)
|
|
|
cpu_to_le16(sizeof(struct smb2_sess_setup_req) - 1 /* pad */);
|
|
|
req->SecurityBufferLength = cpu_to_le16(sess_data->iov[1].iov_len);
|
|
|
|
|
|
- /* BB add code to build os and lm fields */
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = sess_data->iov;
|
|
|
+ rqst.rq_nvec = 2;
|
|
|
|
|
|
- rc = smb2_send_recv(sess_data->xid, sess_data->ses,
|
|
|
- sess_data->iov, 2,
|
|
|
+ /* BB add code to build os and lm fields */
|
|
|
+ rc = cifs_send_recv(sess_data->xid, sess_data->ses,
|
|
|
+ &rqst,
|
|
|
&sess_data->buf0_type,
|
|
|
CIFS_LOG_ERROR | CIFS_NEG_OP, &rsp_iov);
|
|
|
cifs_small_buf_release(sess_data->iov[0].iov_base);
|
|
@@ -1376,6 +1386,7 @@ out:
|
|
|
int
|
|
|
SMB2_logoff(const unsigned int xid, struct cifs_ses *ses)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_logoff_req *req; /* response is also trivial struct */
|
|
|
int rc = 0;
|
|
|
struct TCP_Server_Info *server;
|
|
@@ -1413,7 +1424,11 @@ SMB2_logoff(const unsigned int xid, struct cifs_ses *ses)
|
|
|
iov[0].iov_base = (char *)req;
|
|
|
iov[0].iov_len = total_len;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
/*
|
|
|
* No tcon so can't do
|
|
@@ -1443,6 +1458,7 @@ int
|
|
|
SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
|
|
|
struct cifs_tcon *tcon, const struct nls_table *cp)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_tree_connect_req *req;
|
|
|
struct smb2_tree_connect_rsp *rsp = NULL;
|
|
|
struct kvec iov[2];
|
|
@@ -1499,7 +1515,11 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree,
|
|
|
!smb3_encryption_required(tcon))
|
|
|
req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 2, &resp_buftype, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 2;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
rsp = (struct smb2_tree_connect_rsp *)rsp_iov.iov_base;
|
|
|
|
|
@@ -1563,6 +1583,7 @@ tcon_error_exit:
|
|
|
int
|
|
|
SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_tree_disconnect_req *req; /* response is trivial */
|
|
|
int rc = 0;
|
|
|
struct cifs_ses *ses = tcon->ses;
|
|
@@ -1593,7 +1614,11 @@ SMB2_tdis(const unsigned int xid, struct cifs_tcon *tcon)
|
|
|
iov[0].iov_base = (char *)req;
|
|
|
iov[0].iov_len = total_len;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
if (rc)
|
|
|
cifs_stats_fail_inc(tcon, SMB2_TREE_DISCONNECT_HE);
|
|
@@ -1886,11 +1911,165 @@ alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_CIFS_SMB311
|
|
|
+int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
|
|
|
+ umode_t mode, struct cifs_tcon *tcon,
|
|
|
+ const char *full_path,
|
|
|
+ struct cifs_sb_info *cifs_sb)
|
|
|
+{
|
|
|
+ struct smb_rqst rqst;
|
|
|
+ struct smb2_create_req *req;
|
|
|
+ struct smb2_create_rsp *rsp;
|
|
|
+ struct TCP_Server_Info *server;
|
|
|
+ struct cifs_ses *ses = tcon->ses;
|
|
|
+ struct kvec iov[3]; /* make sure at least one for each open context */
|
|
|
+ struct kvec rsp_iov = {NULL, 0};
|
|
|
+ int resp_buftype;
|
|
|
+ int uni_path_len;
|
|
|
+ __le16 *copy_path = NULL;
|
|
|
+ int copy_size;
|
|
|
+ int rc = 0;
|
|
|
+ unsigned int n_iov = 2;
|
|
|
+ __u32 file_attributes = 0;
|
|
|
+ char *pc_buf = NULL;
|
|
|
+ int flags = 0;
|
|
|
+ unsigned int total_len;
|
|
|
+ __le16 *path = cifs_convert_path_to_utf16(full_path, cifs_sb);
|
|
|
+
|
|
|
+ if (!path)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ cifs_dbg(FYI, "mkdir\n");
|
|
|
+
|
|
|
+ if (ses && (ses->server))
|
|
|
+ server = ses->server;
|
|
|
+ else
|
|
|
+ return -EIO;
|
|
|
+
|
|
|
+ rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len);
|
|
|
+
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
+ if (smb3_encryption_required(tcon))
|
|
|
+ flags |= CIFS_TRANSFORM_REQ;
|
|
|
+
|
|
|
+
|
|
|
+ req->ImpersonationLevel = IL_IMPERSONATION;
|
|
|
+ req->DesiredAccess = cpu_to_le32(FILE_WRITE_ATTRIBUTES);
|
|
|
+ /* File attributes ignored on open (used in create though) */
|
|
|
+ req->FileAttributes = cpu_to_le32(file_attributes);
|
|
|
+ req->ShareAccess = FILE_SHARE_ALL_LE;
|
|
|
+ req->CreateDisposition = cpu_to_le32(FILE_CREATE);
|
|
|
+ req->CreateOptions = cpu_to_le32(CREATE_NOT_FILE);
|
|
|
+
|
|
|
+ iov[0].iov_base = (char *)req;
|
|
|
+ /* -1 since last byte is buf[0] which is sent below (path) */
|
|
|
+ iov[0].iov_len = total_len - 1;
|
|
|
+
|
|
|
+ req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req));
|
|
|
+
|
|
|
+ /* [MS-SMB2] 2.2.13 NameOffset:
|
|
|
+ * If SMB2_FLAGS_DFS_OPERATIONS is set in the Flags field of
|
|
|
+ * the SMB2 header, the file name includes a prefix that will
|
|
|
+ * be processed during DFS name normalization as specified in
|
|
|
+ * section 3.3.5.9. Otherwise, the file name is relative to
|
|
|
+ * the share that is identified by the TreeId in the SMB2
|
|
|
+ * header.
|
|
|
+ */
|
|
|
+ if (tcon->share_flags & SHI1005_FLAGS_DFS) {
|
|
|
+ int name_len;
|
|
|
+
|
|
|
+ req->sync_hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
|
|
|
+ rc = alloc_path_with_tree_prefix(©_path, ©_size,
|
|
|
+ &name_len,
|
|
|
+ tcon->treeName, path);
|
|
|
+ if (rc) {
|
|
|
+ cifs_small_buf_release(req);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+ req->NameLength = cpu_to_le16(name_len * 2);
|
|
|
+ uni_path_len = copy_size;
|
|
|
+ path = copy_path;
|
|
|
+ } else {
|
|
|
+ uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2;
|
|
|
+ /* MUST set path len (NameLength) to 0 opening root of share */
|
|
|
+ req->NameLength = cpu_to_le16(uni_path_len - 2);
|
|
|
+ if (uni_path_len % 8 != 0) {
|
|
|
+ copy_size = roundup(uni_path_len, 8);
|
|
|
+ copy_path = kzalloc(copy_size, GFP_KERNEL);
|
|
|
+ if (!copy_path) {
|
|
|
+ cifs_small_buf_release(req);
|
|
|
+ return -ENOMEM;
|
|
|
+ }
|
|
|
+ memcpy((char *)copy_path, (const char *)path,
|
|
|
+ uni_path_len);
|
|
|
+ uni_path_len = copy_size;
|
|
|
+ path = copy_path;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ iov[1].iov_len = uni_path_len;
|
|
|
+ iov[1].iov_base = path;
|
|
|
+ req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_NONE;
|
|
|
+
|
|
|
+ if (tcon->posix_extensions) {
|
|
|
+ if (n_iov > 2) {
|
|
|
+ struct create_context *ccontext =
|
|
|
+ (struct create_context *)iov[n_iov-1].iov_base;
|
|
|
+ ccontext->Next =
|
|
|
+ cpu_to_le32(iov[n_iov-1].iov_len);
|
|
|
+ }
|
|
|
+
|
|
|
+ rc = add_posix_context(iov, &n_iov, mode);
|
|
|
+ if (rc) {
|
|
|
+ cifs_small_buf_release(req);
|
|
|
+ kfree(copy_path);
|
|
|
+ return rc;
|
|
|
+ }
|
|
|
+ pc_buf = iov[n_iov-1].iov_base;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = n_iov;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
|
|
|
+ &rsp_iov);
|
|
|
+
|
|
|
+ cifs_small_buf_release(req);
|
|
|
+ rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
|
|
|
+
|
|
|
+ if (rc != 0) {
|
|
|
+ cifs_stats_fail_inc(tcon, SMB2_CREATE_HE);
|
|
|
+ trace_smb3_posix_mkdir_err(xid, tcon->tid, ses->Suid,
|
|
|
+ CREATE_NOT_FILE, FILE_WRITE_ATTRIBUTES, rc);
|
|
|
+ goto smb311_mkdir_exit;
|
|
|
+ } else
|
|
|
+ trace_smb3_posix_mkdir_done(xid, rsp->PersistentFileId, tcon->tid,
|
|
|
+ ses->Suid, CREATE_NOT_FILE,
|
|
|
+ FILE_WRITE_ATTRIBUTES);
|
|
|
+
|
|
|
+ SMB2_close(xid, tcon, rsp->PersistentFileId, rsp->VolatileFileId);
|
|
|
+
|
|
|
+ /* Eventually save off posix specific response info and timestaps */
|
|
|
+
|
|
|
+smb311_mkdir_exit:
|
|
|
+ kfree(copy_path);
|
|
|
+ kfree(pc_buf);
|
|
|
+ free_rsp_buf(resp_buftype, rsp);
|
|
|
+ return rc;
|
|
|
+
|
|
|
+}
|
|
|
+#endif /* SMB311 */
|
|
|
+
|
|
|
int
|
|
|
SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
|
|
|
__u8 *oplock, struct smb2_file_all_info *buf,
|
|
|
struct kvec *err_iov, int *buftype)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_create_req *req;
|
|
|
struct smb2_create_rsp *rsp;
|
|
|
struct TCP_Server_Info *server;
|
|
@@ -2043,7 +2222,11 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path,
|
|
|
}
|
|
|
#endif /* SMB311 */
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, n_iov, &resp_buftype, flags,
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = n_iov;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
|
|
|
&rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
|
|
@@ -2099,6 +2282,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
|
|
|
char *in_data, u32 indatalen,
|
|
|
char **out_data, u32 *plen /* returned data len */)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_ioctl_req *req;
|
|
|
struct smb2_ioctl_rsp *rsp;
|
|
|
struct cifs_ses *ses;
|
|
@@ -2189,7 +2373,11 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
|
|
|
if (opcode == FSCTL_VALIDATE_NEGOTIATE_INFO)
|
|
|
req->sync_hdr.Flags |= SMB2_FLAGS_SIGNED;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, n_iov, &resp_buftype, flags,
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = n_iov;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
|
|
|
&rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
rsp = (struct smb2_ioctl_rsp *)rsp_iov.iov_base;
|
|
@@ -2274,6 +2462,7 @@ int
|
|
|
SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
u64 persistent_fid, u64 volatile_fid, int flags)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_close_req *req;
|
|
|
struct smb2_close_rsp *rsp;
|
|
|
struct cifs_ses *ses = tcon->ses;
|
|
@@ -2301,7 +2490,11 @@ SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
iov[0].iov_base = (char *)req;
|
|
|
iov[0].iov_len = total_len;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
rsp = (struct smb2_close_rsp *)rsp_iov.iov_base;
|
|
|
|
|
@@ -2387,6 +2580,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
u32 additional_info, size_t output_len, size_t min_len, void **data,
|
|
|
u32 *dlen)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_query_info_req *req;
|
|
|
struct smb2_query_info_rsp *rsp = NULL;
|
|
|
struct kvec iov[2];
|
|
@@ -2427,7 +2621,11 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
/* 1 for Buffer */
|
|
|
iov[0].iov_len = total_len - 1;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base;
|
|
|
|
|
@@ -2594,11 +2792,10 @@ SMB2_echo(struct TCP_Server_Info *server)
|
|
|
{
|
|
|
struct smb2_echo_req *req;
|
|
|
int rc = 0;
|
|
|
- struct kvec iov[2];
|
|
|
+ struct kvec iov[1];
|
|
|
struct smb_rqst rqst = { .rq_iov = iov,
|
|
|
- .rq_nvec = 2 };
|
|
|
+ .rq_nvec = 1 };
|
|
|
unsigned int total_len;
|
|
|
- __be32 rfc1002_marker;
|
|
|
|
|
|
cifs_dbg(FYI, "In echo request\n");
|
|
|
|
|
@@ -2614,11 +2811,8 @@ SMB2_echo(struct TCP_Server_Info *server)
|
|
|
|
|
|
req->sync_hdr.CreditRequest = cpu_to_le16(1);
|
|
|
|
|
|
- iov[0].iov_len = 4;
|
|
|
- rfc1002_marker = cpu_to_be32(total_len);
|
|
|
- iov[0].iov_base = &rfc1002_marker;
|
|
|
- iov[1].iov_len = total_len;
|
|
|
- iov[1].iov_base = (char *)req;
|
|
|
+ iov[0].iov_len = total_len;
|
|
|
+ iov[0].iov_base = (char *)req;
|
|
|
|
|
|
rc = cifs_call_async(server, &rqst, NULL, smb2_echo_callback, NULL,
|
|
|
server, CIFS_ECHO_OP);
|
|
@@ -2633,6 +2827,7 @@ int
|
|
|
SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
|
|
|
u64 volatile_fid)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_flush_req *req;
|
|
|
struct cifs_ses *ses = tcon->ses;
|
|
|
struct kvec iov[1];
|
|
@@ -2660,7 +2855,11 @@ SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid,
|
|
|
iov[0].iov_base = (char *)req;
|
|
|
iov[0].iov_len = total_len;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
|
|
|
if (rc != 0) {
|
|
@@ -2848,10 +3047,9 @@ smb2_async_readv(struct cifs_readdata *rdata)
|
|
|
struct smb2_sync_hdr *shdr;
|
|
|
struct cifs_io_parms io_parms;
|
|
|
struct smb_rqst rqst = { .rq_iov = rdata->iov,
|
|
|
- .rq_nvec = 2 };
|
|
|
+ .rq_nvec = 1 };
|
|
|
struct TCP_Server_Info *server;
|
|
|
unsigned int total_len;
|
|
|
- __be32 req_len;
|
|
|
|
|
|
cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n",
|
|
|
__func__, rdata->offset, rdata->bytes);
|
|
@@ -2882,12 +3080,8 @@ smb2_async_readv(struct cifs_readdata *rdata)
|
|
|
if (smb3_encryption_required(io_parms.tcon))
|
|
|
flags |= CIFS_TRANSFORM_REQ;
|
|
|
|
|
|
- req_len = cpu_to_be32(total_len);
|
|
|
-
|
|
|
- rdata->iov[0].iov_base = &req_len;
|
|
|
- rdata->iov[0].iov_len = sizeof(__be32);
|
|
|
- rdata->iov[1].iov_base = buf;
|
|
|
- rdata->iov[1].iov_len = total_len;
|
|
|
+ rdata->iov[0].iov_base = buf;
|
|
|
+ rdata->iov[0].iov_len = total_len;
|
|
|
|
|
|
shdr = (struct smb2_sync_hdr *)buf;
|
|
|
|
|
@@ -2926,6 +3120,7 @@ int
|
|
|
SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|
|
unsigned int *nbytes, char **buf, int *buf_type)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
int resp_buftype, rc = -EACCES;
|
|
|
struct smb2_read_plain_req *req = NULL;
|
|
|
struct smb2_read_rsp *rsp = NULL;
|
|
@@ -2946,7 +3141,11 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|
|
iov[0].iov_base = (char *)req;
|
|
|
iov[0].iov_len = total_len;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 1, &resp_buftype, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
|
|
|
rsp = (struct smb2_read_rsp *)rsp_iov.iov_base;
|
|
@@ -3062,10 +3261,9 @@ smb2_async_writev(struct cifs_writedata *wdata,
|
|
|
struct smb2_sync_hdr *shdr;
|
|
|
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
|
|
|
struct TCP_Server_Info *server = tcon->ses->server;
|
|
|
- struct kvec iov[2];
|
|
|
+ struct kvec iov[1];
|
|
|
struct smb_rqst rqst = { };
|
|
|
unsigned int total_len;
|
|
|
- __be32 rfc1002_marker;
|
|
|
|
|
|
rc = smb2_plain_req_init(SMB2_WRITE, tcon, (void **) &req, &total_len);
|
|
|
if (rc) {
|
|
@@ -3137,15 +3335,11 @@ smb2_async_writev(struct cifs_writedata *wdata,
|
|
|
v1->length = cpu_to_le32(wdata->mr->mr->length);
|
|
|
}
|
|
|
#endif
|
|
|
- /* 4 for rfc1002 length field and 1 for Buffer */
|
|
|
- iov[0].iov_len = 4;
|
|
|
- rfc1002_marker = cpu_to_be32(total_len - 1 + wdata->bytes);
|
|
|
- iov[0].iov_base = &rfc1002_marker;
|
|
|
- iov[1].iov_len = total_len - 1;
|
|
|
- iov[1].iov_base = (char *)req;
|
|
|
+ iov[0].iov_len = total_len - 1;
|
|
|
+ iov[0].iov_base = (char *)req;
|
|
|
|
|
|
rqst.rq_iov = iov;
|
|
|
- rqst.rq_nvec = 2;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
rqst.rq_pages = wdata->pages;
|
|
|
rqst.rq_offset = wdata->page_offset;
|
|
|
rqst.rq_npages = wdata->nr_pages;
|
|
@@ -3153,7 +3347,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
|
|
|
rqst.rq_tailsz = wdata->tailsz;
|
|
|
#ifdef CONFIG_CIFS_SMB_DIRECT
|
|
|
if (wdata->mr) {
|
|
|
- iov[1].iov_len += sizeof(struct smbd_buffer_descriptor_v1);
|
|
|
+ iov[0].iov_len += sizeof(struct smbd_buffer_descriptor_v1);
|
|
|
rqst.rq_npages = 0;
|
|
|
}
|
|
|
#endif
|
|
@@ -3210,6 +3404,7 @@ int
|
|
|
SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|
|
unsigned int *nbytes, struct kvec *iov, int n_vec)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
int rc = 0;
|
|
|
struct smb2_write_req *req = NULL;
|
|
|
struct smb2_write_rsp *rsp = NULL;
|
|
@@ -3251,7 +3446,11 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|
|
/* 1 for Buffer */
|
|
|
iov[0].iov_len = total_len - 1;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, io_parms->tcon->ses, iov, n_vec + 1,
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = n_vec + 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, io_parms->tcon->ses, &rqst,
|
|
|
&resp_buftype, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
rsp = (struct smb2_write_rsp *)rsp_iov.iov_base;
|
|
@@ -3323,6 +3522,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
u64 persistent_fid, u64 volatile_fid, int index,
|
|
|
struct cifs_search_info *srch_inf)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_query_directory_req *req;
|
|
|
struct smb2_query_directory_rsp *rsp = NULL;
|
|
|
struct kvec iov[2];
|
|
@@ -3395,7 +3595,11 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
iov[1].iov_base = (char *)(req->Buffer);
|
|
|
iov[1].iov_len = len;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 2, &resp_buftype, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 2;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
rsp = (struct smb2_query_directory_rsp *)rsp_iov.iov_base;
|
|
|
|
|
@@ -3454,6 +3658,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
u8 info_type, u32 additional_info, unsigned int num,
|
|
|
void **data, unsigned int *size)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_set_info_req *req;
|
|
|
struct smb2_set_info_rsp *rsp = NULL;
|
|
|
struct kvec *iov;
|
|
@@ -3509,7 +3714,11 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
iov[i].iov_len = size[i];
|
|
|
}
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, num, &resp_buftype, flags,
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = num;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
|
|
|
&rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
rsp = (struct smb2_set_info_rsp *)rsp_iov.iov_base;
|
|
@@ -3664,6 +3873,7 @@ SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
const u64 persistent_fid, const u64 volatile_fid,
|
|
|
__u8 oplock_level)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
int rc;
|
|
|
struct smb2_oplock_break *req = NULL;
|
|
|
struct cifs_ses *ses = tcon->ses;
|
|
@@ -3692,7 +3902,11 @@ SMB2_oplock_break(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
iov[0].iov_base = (char *)req;
|
|
|
iov[0].iov_len = total_len;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
|
|
|
if (rc) {
|
|
@@ -3755,6 +3969,7 @@ int
|
|
|
SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_query_info_rsp *rsp = NULL;
|
|
|
struct kvec iov;
|
|
|
struct kvec rsp_iov;
|
|
@@ -3773,7 +3988,11 @@ SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
if (smb3_encryption_required(tcon))
|
|
|
flags |= CIFS_TRANSFORM_REQ;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, &iov, 1, &resp_buftype, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = &iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(iov.iov_base);
|
|
|
if (rc) {
|
|
|
cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
|
|
@@ -3798,6 +4017,7 @@ int
|
|
|
SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
u64 persistent_fid, u64 volatile_fid, int level)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
struct smb2_query_info_rsp *rsp = NULL;
|
|
|
struct kvec iov;
|
|
|
struct kvec rsp_iov;
|
|
@@ -3829,7 +4049,11 @@ SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
if (smb3_encryption_required(tcon))
|
|
|
flags |= CIFS_TRANSFORM_REQ;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, &iov, 1, &resp_buftype, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = &iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(iov.iov_base);
|
|
|
if (rc) {
|
|
|
cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE);
|
|
@@ -3868,6 +4092,7 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
const __u64 persist_fid, const __u64 volatile_fid, const __u32 pid,
|
|
|
const __u32 num_lock, struct smb2_lock_element *buf)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
int rc = 0;
|
|
|
struct smb2_lock_req *req = NULL;
|
|
|
struct kvec iov[2];
|
|
@@ -3900,7 +4125,12 @@ smb2_lockv(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
iov[1].iov_len = count;
|
|
|
|
|
|
cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
|
|
|
- rc = smb2_send_recv(xid, tcon->ses, iov, 2, &resp_buf_type, flags,
|
|
|
+
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 2;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, tcon->ses, &rqst, &resp_buf_type, flags,
|
|
|
&rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
if (rc) {
|
|
@@ -3934,6 +4164,7 @@ int
|
|
|
SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
__u8 *lease_key, const __le32 lease_state)
|
|
|
{
|
|
|
+ struct smb_rqst rqst;
|
|
|
int rc;
|
|
|
struct smb2_lease_ack *req = NULL;
|
|
|
struct cifs_ses *ses = tcon->ses;
|
|
@@ -3964,7 +4195,11 @@ SMB2_lease_break(const unsigned int xid, struct cifs_tcon *tcon,
|
|
|
iov[0].iov_base = (char *)req;
|
|
|
iov[0].iov_len = total_len;
|
|
|
|
|
|
- rc = smb2_send_recv(xid, ses, iov, 1, &resp_buf_type, flags, &rsp_iov);
|
|
|
+ memset(&rqst, 0, sizeof(struct smb_rqst));
|
|
|
+ rqst.rq_iov = iov;
|
|
|
+ rqst.rq_nvec = 1;
|
|
|
+
|
|
|
+ rc = cifs_send_recv(xid, ses, &rqst, &resp_buf_type, flags, &rsp_iov);
|
|
|
cifs_small_buf_release(req);
|
|
|
|
|
|
if (rc) {
|