mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-08 15:04:45 +00:00
minor cleanup and fixes, one for stable, also adds SEEK_HOLE support
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAlzfKpcACgkQiiy9cAdy T1G35AwAh/uXfq+F8Zk9EqqE8akRo6X0HDLzps5ICriQdYI2r5I+hUDLoRwNn2AX qeife0CBfcOyib2jlGV7rYjIPJ6SNAIUPLzMvupgXfMQABt+aOeFiQ6KQz/cYgd4 bQEaLhOiCt7REc8vmhL6hKXjbypiO4wwLPl29kEjHr/ZNQUFCg8MBCpKY5uCpCQe paLfVusSzKTjuxRinSvUWSApASQ2GU9ys1hid3PN6/MUt1vD+IXnchWRUXBZ4sNi ztZgUNyH7AvdwoY+sM0hdT+jEehl4eTtDP1ZaeGz5Dhq4Fpe86OrfXBsySscUCgq wpjioh67ihSg9If8ZETfYJ2srn1VhyME01l30yuJB0HgRLebWXFXe4QDCbPYnUFh 9wWZavRUlQuiKx9x2mszHBL5L3r6mZXdOHEumm2DV8TJFTjlxDt6jhdxsZA3HAzB 6Rz0F24F/Dez4ONdYS0eO8am1CScW1tTJU9+6xyW2/XP3YZunx8B6SxU7lu3nzNN jqZ7pk7o =JhcA -----END PGP SIGNATURE----- Merge tag '5.2-rc-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6 Pull cifs fixes from Steve French: "Minor cleanup and fixes, one for stable, four rdma (smbdirect) related. Also adds SEEK_HOLE support" * tag '5.2-rc-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: cifs: add support for SEEK_DATA and SEEK_HOLE Fixed https://bugzilla.kernel.org/show_bug.cgi?id=202935 allow write on the same file cifs: Allocate memory for all iovs in smb2_ioctl cifs: Don't match port on SMBDirect transport cifs:smbd Use the correct DMA direction when sending data cifs:smbd When reconnecting to server, call smbd_destroy() after all MIDs have been called cifs: use the right include for signal_pending() smb3: trivial cleanup to smb2ops.c cifs: cleanup smb2ops.c and normalize strings smb3: display session id in debug data
This commit is contained in:
commit
d8848eefc1
@ -380,6 +380,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
|
||||
atomic_read(&server->in_send),
|
||||
atomic_read(&server->num_waiters));
|
||||
#endif
|
||||
/* dump session id helpful for use with network trace */
|
||||
seq_printf(m, " SessionId: 0x%llx", ses->Suid);
|
||||
if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
|
||||
seq_puts(m, " encrypted");
|
||||
if (ses->sign)
|
||||
|
@ -878,6 +878,9 @@ static ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
|
||||
static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
|
||||
{
|
||||
struct cifsFileInfo *cfile = file->private_data;
|
||||
struct cifs_tcon *tcon;
|
||||
|
||||
/*
|
||||
* whence == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
|
||||
* the cached file length
|
||||
@ -909,6 +912,12 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence)
|
||||
if (rc < 0)
|
||||
return (loff_t)rc;
|
||||
}
|
||||
if (cfile && cfile->tlink) {
|
||||
tcon = tlink_tcon(cfile->tlink);
|
||||
if (tcon->ses->server->ops->llseek)
|
||||
return tcon->ses->server->ops->llseek(file, tcon,
|
||||
offset, whence);
|
||||
}
|
||||
return generic_file_llseek(file, offset, whence);
|
||||
}
|
||||
|
||||
@ -1070,11 +1079,6 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
|
||||
|
||||
cifs_dbg(FYI, "copychunk range\n");
|
||||
|
||||
if (src_inode == target_inode) {
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!src_file->private_data || !dst_file->private_data) {
|
||||
rc = -EBADF;
|
||||
cifs_dbg(VFS, "missing cifsFileInfo on copy range src file\n");
|
||||
|
@ -497,6 +497,8 @@ struct smb_version_operations {
|
||||
/* version specific fiemap implementation */
|
||||
int (*fiemap)(struct cifs_tcon *tcon, struct cifsFileInfo *,
|
||||
struct fiemap_extent_info *, u64, u64);
|
||||
/* version specific llseek implementation */
|
||||
loff_t (*llseek)(struct file *, struct cifs_tcon *, loff_t, int);
|
||||
};
|
||||
|
||||
struct smb_version_values {
|
||||
|
@ -528,6 +528,21 @@ cifs_reconnect(struct TCP_Server_Info *server)
|
||||
/* do not want to be sending data on a socket we are freeing */
|
||||
cifs_dbg(FYI, "%s: tearing down socket\n", __func__);
|
||||
mutex_lock(&server->srv_mutex);
|
||||
if (server->ssocket) {
|
||||
cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
|
||||
server->ssocket->state, server->ssocket->flags);
|
||||
kernel_sock_shutdown(server->ssocket, SHUT_WR);
|
||||
cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
|
||||
server->ssocket->state, server->ssocket->flags);
|
||||
sock_release(server->ssocket);
|
||||
server->ssocket = NULL;
|
||||
}
|
||||
server->sequence_number = 0;
|
||||
server->session_estab = false;
|
||||
kfree(server->session_key.response);
|
||||
server->session_key.response = NULL;
|
||||
server->session_key.len = 0;
|
||||
server->lstrp = jiffies;
|
||||
|
||||
/* mark submitted MIDs for retry and issue callback */
|
||||
INIT_LIST_HEAD(&retry_list);
|
||||
@ -540,6 +555,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
|
||||
list_move(&mid_entry->qhead, &retry_list);
|
||||
}
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
mutex_unlock(&server->srv_mutex);
|
||||
|
||||
cifs_dbg(FYI, "%s: issuing mid callbacks\n", __func__);
|
||||
list_for_each_safe(tmp, tmp2, &retry_list) {
|
||||
@ -548,24 +564,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
|
||||
mid_entry->callback(mid_entry);
|
||||
}
|
||||
|
||||
if (server->ssocket) {
|
||||
cifs_dbg(FYI, "State: 0x%x Flags: 0x%lx\n",
|
||||
server->ssocket->state, server->ssocket->flags);
|
||||
kernel_sock_shutdown(server->ssocket, SHUT_WR);
|
||||
cifs_dbg(FYI, "Post shutdown state: 0x%x Flags: 0x%lx\n",
|
||||
server->ssocket->state, server->ssocket->flags);
|
||||
sock_release(server->ssocket);
|
||||
server->ssocket = NULL;
|
||||
} else if (cifs_rdma_enabled(server))
|
||||
if (cifs_rdma_enabled(server)) {
|
||||
mutex_lock(&server->srv_mutex);
|
||||
smbd_destroy(server);
|
||||
server->sequence_number = 0;
|
||||
server->session_estab = false;
|
||||
kfree(server->session_key.response);
|
||||
server->session_key.response = NULL;
|
||||
server->session_key.len = 0;
|
||||
server->lstrp = jiffies;
|
||||
|
||||
mutex_unlock(&server->srv_mutex);
|
||||
mutex_unlock(&server->srv_mutex);
|
||||
}
|
||||
|
||||
do {
|
||||
try_to_freeze();
|
||||
@ -2443,6 +2446,10 @@ match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
|
||||
{
|
||||
__be16 port, *sport;
|
||||
|
||||
/* SMBDirect manages its own ports, don't match it here */
|
||||
if (server->rdma)
|
||||
return true;
|
||||
|
||||
switch (addr->sa_family) {
|
||||
case AF_INET:
|
||||
sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
|
||||
|
@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* SMB2 version specific operations
|
||||
*
|
||||
@ -282,7 +283,7 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf)
|
||||
__u64 wire_mid = le64_to_cpu(shdr->MessageId);
|
||||
|
||||
if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) {
|
||||
cifs_dbg(VFS, "encrypted frame parsing not supported yet");
|
||||
cifs_dbg(VFS, "Encrypted frame parsing not supported yet\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -324,6 +325,7 @@ static int
|
||||
smb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
|
||||
{
|
||||
int rc;
|
||||
|
||||
ses->server->CurrentMid = 0;
|
||||
rc = SMB2_negotiate(xid, ses);
|
||||
/* BB we probably don't need to retry with modern servers */
|
||||
@ -789,8 +791,6 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
||||
SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
|
||||
else
|
||||
close_shroot(&tcon->crfid);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -818,7 +818,6 @@ smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
||||
SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
|
||||
FS_DEVICE_INFORMATION);
|
||||
SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -906,9 +905,8 @@ move_smb2_ea_to_cifs(char *dst, size_t dst_size,
|
||||
value = &src->ea_data[src->ea_name_length + 1];
|
||||
value_len = (size_t)le16_to_cpu(src->ea_value_length);
|
||||
|
||||
if (name_len == 0) {
|
||||
if (name_len == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (src_size < 8 + name_len + 1 + value_len) {
|
||||
cifs_dbg(FYI, "EA entry goes beyond length of list\n");
|
||||
@ -1161,6 +1159,7 @@ static void
|
||||
smb2_clear_stats(struct cifs_tcon *tcon)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
|
||||
atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
|
||||
atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0);
|
||||
@ -1529,7 +1528,7 @@ smb2_copychunk_range(const unsigned int xid,
|
||||
if (pcchunk == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
cifs_dbg(FYI, "in smb2_copychunk_range - about to call request res key\n");
|
||||
cifs_dbg(FYI, "%s: about to call request res key\n", __func__);
|
||||
/* Request a key from the server to identify the source of the copy */
|
||||
rc = SMB2_request_res_key(xid, tlink_tcon(srcfile->tlink),
|
||||
srcfile->fid.persistent_fid,
|
||||
@ -1649,6 +1648,7 @@ static unsigned int
|
||||
smb2_read_data_offset(char *buf)
|
||||
{
|
||||
struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
|
||||
|
||||
return rsp->DataOffset;
|
||||
}
|
||||
|
||||
@ -1777,7 +1777,7 @@ smb2_duplicate_extents(const unsigned int xid,
|
||||
dup_ext_buf.SourceFileOffset = cpu_to_le64(src_off);
|
||||
dup_ext_buf.TargetFileOffset = cpu_to_le64(dest_off);
|
||||
dup_ext_buf.ByteCount = cpu_to_le64(len);
|
||||
cifs_dbg(FYI, "duplicate extents: src off %lld dst off %lld len %lld",
|
||||
cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n",
|
||||
src_off, dest_off, len);
|
||||
|
||||
rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
|
||||
@ -1794,7 +1794,7 @@ smb2_duplicate_extents(const unsigned int xid,
|
||||
&ret_data_len);
|
||||
|
||||
if (ret_data_len > 0)
|
||||
cifs_dbg(FYI, "non-zero response length in duplicate extents");
|
||||
cifs_dbg(FYI, "Non-zero response length in duplicate extents\n");
|
||||
|
||||
duplicate_extents_out:
|
||||
return rc;
|
||||
@ -1983,9 +1983,9 @@ smb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
}
|
||||
|
||||
/*
|
||||
* If we negotiate SMB2 protocol and get STATUS_PENDING - update
|
||||
* the number of credits and return true. Otherwise - return false.
|
||||
*/
|
||||
* If we negotiate SMB2 protocol and get STATUS_PENDING - update
|
||||
* the number of credits and return true. Otherwise - return false.
|
||||
*/
|
||||
static bool
|
||||
smb2_is_status_pending(char *buf, struct TCP_Server_Info *server)
|
||||
{
|
||||
@ -2306,7 +2306,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
|
||||
struct get_dfs_referral_rsp *dfs_rsp = NULL;
|
||||
u32 dfs_req_size = 0, dfs_rsp_size = 0;
|
||||
|
||||
cifs_dbg(FYI, "smb2_get_dfs_refer path <%s>\n", search_name);
|
||||
cifs_dbg(FYI, "%s: path: %s\n", __func__, search_name);
|
||||
|
||||
/*
|
||||
* Try to use the IPC tcon, otherwise just use any
|
||||
@ -2360,7 +2360,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
|
||||
|
||||
if (rc) {
|
||||
if ((rc != -ENOENT) && (rc != -EOPNOTSUPP))
|
||||
cifs_dbg(VFS, "ioctl error in smb2_get_dfs_refer rc=%d\n", rc);
|
||||
cifs_dbg(VFS, "ioctl error in %s rc=%d\n", __func__, rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -2369,7 +2369,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses,
|
||||
nls_codepage, remap, search_name,
|
||||
true /* is_unicode */);
|
||||
if (rc) {
|
||||
cifs_dbg(VFS, "parse error in smb2_get_dfs_refer rc=%d\n", rc);
|
||||
cifs_dbg(VFS, "parse error in %s rc=%d\n", __func__, rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -2745,7 +2745,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
|
||||
inode = d_inode(cfile->dentry);
|
||||
cifsi = CIFS_I(inode);
|
||||
|
||||
trace_smb3_zero_enter(xid, cfile->fid.persistent_fid, tcon->tid,
|
||||
trace_smb3_zero_enter(xid, cfile->fid.persistent_fid, tcon->tid,
|
||||
ses->Suid, offset, len);
|
||||
|
||||
|
||||
@ -2759,7 +2759,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
|
||||
return rc;
|
||||
}
|
||||
|
||||
cifs_dbg(FYI, "offset %lld len %lld", offset, len);
|
||||
cifs_dbg(FYI, "Offset %lld len %lld\n", offset, len);
|
||||
|
||||
fsctl_buf.FileOffset = cpu_to_le64(offset);
|
||||
fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len);
|
||||
@ -2816,7 +2816,7 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
|
||||
return rc;
|
||||
}
|
||||
|
||||
cifs_dbg(FYI, "offset %lld len %lld", offset, len);
|
||||
cifs_dbg(FYI, "Offset %lld len %lld\n", offset, len);
|
||||
|
||||
fsctl_buf.FileOffset = cpu_to_le64(offset);
|
||||
fsctl_buf.BeyondFinalZero = cpu_to_le64(offset + len);
|
||||
@ -2922,6 +2922,90 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static loff_t smb3_llseek(struct file *file, struct cifs_tcon *tcon, loff_t offset, int whence)
|
||||
{
|
||||
struct cifsFileInfo *wrcfile, *cfile = file->private_data;
|
||||
struct cifsInodeInfo *cifsi;
|
||||
struct inode *inode;
|
||||
int rc = 0;
|
||||
struct file_allocated_range_buffer in_data, *out_data = NULL;
|
||||
u32 out_data_len;
|
||||
unsigned int xid;
|
||||
|
||||
if (whence != SEEK_HOLE && whence != SEEK_DATA)
|
||||
return generic_file_llseek(file, offset, whence);
|
||||
|
||||
inode = d_inode(cfile->dentry);
|
||||
cifsi = CIFS_I(inode);
|
||||
|
||||
if (offset < 0 || offset >= i_size_read(inode))
|
||||
return -ENXIO;
|
||||
|
||||
xid = get_xid();
|
||||
/*
|
||||
* We need to be sure that all dirty pages are written as they
|
||||
* might fill holes on the server.
|
||||
* Note that we also MUST flush any written pages since at least
|
||||
* some servers (Windows2016) will not reflect recent writes in
|
||||
* QUERY_ALLOCATED_RANGES until SMB2_flush is called.
|
||||
*/
|
||||
wrcfile = find_writable_file(cifsi, false);
|
||||
if (wrcfile) {
|
||||
filemap_write_and_wait(inode->i_mapping);
|
||||
smb2_flush_file(xid, tcon, &wrcfile->fid);
|
||||
cifsFileInfo_put(wrcfile);
|
||||
}
|
||||
|
||||
if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)) {
|
||||
if (whence == SEEK_HOLE)
|
||||
offset = i_size_read(inode);
|
||||
goto lseek_exit;
|
||||
}
|
||||
|
||||
in_data.file_offset = cpu_to_le64(offset);
|
||||
in_data.length = cpu_to_le64(i_size_read(inode));
|
||||
|
||||
rc = SMB2_ioctl(xid, tcon, cfile->fid.persistent_fid,
|
||||
cfile->fid.volatile_fid,
|
||||
FSCTL_QUERY_ALLOCATED_RANGES, true,
|
||||
(char *)&in_data, sizeof(in_data),
|
||||
sizeof(struct file_allocated_range_buffer),
|
||||
(char **)&out_data, &out_data_len);
|
||||
if (rc == -E2BIG)
|
||||
rc = 0;
|
||||
if (rc)
|
||||
goto lseek_exit;
|
||||
|
||||
if (whence == SEEK_HOLE && out_data_len == 0)
|
||||
goto lseek_exit;
|
||||
|
||||
if (whence == SEEK_DATA && out_data_len == 0) {
|
||||
rc = -ENXIO;
|
||||
goto lseek_exit;
|
||||
}
|
||||
|
||||
if (out_data_len < sizeof(struct file_allocated_range_buffer)) {
|
||||
rc = -EINVAL;
|
||||
goto lseek_exit;
|
||||
}
|
||||
if (whence == SEEK_DATA) {
|
||||
offset = le64_to_cpu(out_data->file_offset);
|
||||
goto lseek_exit;
|
||||
}
|
||||
if (offset < le64_to_cpu(out_data->file_offset))
|
||||
goto lseek_exit;
|
||||
|
||||
offset = le64_to_cpu(out_data->file_offset) + le64_to_cpu(out_data->length);
|
||||
|
||||
lseek_exit:
|
||||
free_xid(xid);
|
||||
kfree(out_data);
|
||||
if (!rc)
|
||||
return vfs_setpos(file, offset, inode->i_sb->s_maxbytes);
|
||||
else
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int smb3_fiemap(struct cifs_tcon *tcon,
|
||||
struct cifsFileInfo *cfile,
|
||||
struct fiemap_extent_info *fei, u64 start, u64 len)
|
||||
@ -3384,7 +3468,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
|
||||
|
||||
req = aead_request_alloc(tfm, GFP_KERNEL);
|
||||
if (!req) {
|
||||
cifs_dbg(VFS, "%s: Failed to alloc aead request", __func__);
|
||||
cifs_dbg(VFS, "%s: Failed to alloc aead request\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -3395,7 +3479,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
|
||||
|
||||
sg = init_sg(num_rqst, rqst, sign);
|
||||
if (!sg) {
|
||||
cifs_dbg(VFS, "%s: Failed to init sg", __func__);
|
||||
cifs_dbg(VFS, "%s: Failed to init sg\n", __func__);
|
||||
rc = -ENOMEM;
|
||||
goto free_req;
|
||||
}
|
||||
@ -3403,7 +3487,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
|
||||
iv_len = crypto_aead_ivsize(tfm);
|
||||
iv = kzalloc(iv_len, GFP_KERNEL);
|
||||
if (!iv) {
|
||||
cifs_dbg(VFS, "%s: Failed to alloc IV", __func__);
|
||||
cifs_dbg(VFS, "%s: Failed to alloc iv\n", __func__);
|
||||
rc = -ENOMEM;
|
||||
goto free_sg;
|
||||
}
|
||||
@ -3511,7 +3595,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
|
||||
fill_transform_hdr(tr_hdr, orig_len, old_rq);
|
||||
|
||||
rc = crypt_message(server, num_rqst, new_rq, 1);
|
||||
cifs_dbg(FYI, "encrypt message returned %d", rc);
|
||||
cifs_dbg(FYI, "Encrypt message returned %d\n", rc);
|
||||
if (rc)
|
||||
goto err_free;
|
||||
|
||||
@ -3552,7 +3636,7 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
|
||||
rqst.rq_tailsz = (page_data_size % PAGE_SIZE) ? : PAGE_SIZE;
|
||||
|
||||
rc = crypt_message(server, 1, &rqst, 0);
|
||||
cifs_dbg(FYI, "decrypt message returned %d\n", rc);
|
||||
cifs_dbg(FYI, "Decrypt message returned %d\n", rc);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
@ -4166,6 +4250,7 @@ struct smb_version_operations smb20_operations = {
|
||||
.ioctl_query_info = smb2_ioctl_query_info,
|
||||
.make_node = smb2_make_node,
|
||||
.fiemap = smb3_fiemap,
|
||||
.llseek = smb3_llseek,
|
||||
};
|
||||
|
||||
struct smb_version_operations smb21_operations = {
|
||||
@ -4266,6 +4351,7 @@ struct smb_version_operations smb21_operations = {
|
||||
.ioctl_query_info = smb2_ioctl_query_info,
|
||||
.make_node = smb2_make_node,
|
||||
.fiemap = smb3_fiemap,
|
||||
.llseek = smb3_llseek,
|
||||
};
|
||||
|
||||
struct smb_version_operations smb30_operations = {
|
||||
@ -4375,6 +4461,7 @@ struct smb_version_operations smb30_operations = {
|
||||
.ioctl_query_info = smb2_ioctl_query_info,
|
||||
.make_node = smb2_make_node,
|
||||
.fiemap = smb3_fiemap,
|
||||
.llseek = smb3_llseek,
|
||||
};
|
||||
|
||||
struct smb_version_operations smb311_operations = {
|
||||
@ -4485,6 +4572,7 @@ struct smb_version_operations smb311_operations = {
|
||||
.ioctl_query_info = smb2_ioctl_query_info,
|
||||
.make_node = smb2_make_node,
|
||||
.fiemap = smb3_fiemap,
|
||||
.llseek = smb3_llseek,
|
||||
};
|
||||
|
||||
struct smb_version_values smb20_values = {
|
||||
|
@ -2538,11 +2538,25 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
|
||||
struct kvec *iov = rqst->rq_iov;
|
||||
unsigned int total_len;
|
||||
int rc;
|
||||
char *in_data_buf;
|
||||
|
||||
rc = smb2_plain_req_init(SMB2_IOCTL, tcon, (void **) &req, &total_len);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (indatalen) {
|
||||
/*
|
||||
* indatalen is usually small at a couple of bytes max, so
|
||||
* just allocate through generic pool
|
||||
*/
|
||||
in_data_buf = kmalloc(indatalen, GFP_NOFS);
|
||||
if (!in_data_buf) {
|
||||
cifs_small_buf_release(req);
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(in_data_buf, in_data, indatalen);
|
||||
}
|
||||
|
||||
req->CtlCode = cpu_to_le32(opcode);
|
||||
req->PersistentFileId = persistent_fid;
|
||||
req->VolatileFileId = volatile_fid;
|
||||
@ -2563,7 +2577,7 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
|
||||
cpu_to_le32(offsetof(struct smb2_ioctl_req, Buffer));
|
||||
rqst->rq_nvec = 2;
|
||||
iov[0].iov_len = total_len - 1;
|
||||
iov[1].iov_base = in_data;
|
||||
iov[1].iov_base = in_data_buf;
|
||||
iov[1].iov_len = indatalen;
|
||||
} else {
|
||||
rqst->rq_nvec = 1;
|
||||
@ -2605,8 +2619,11 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
|
||||
void
|
||||
SMB2_ioctl_free(struct smb_rqst *rqst)
|
||||
{
|
||||
if (rqst && rqst->rq_iov)
|
||||
if (rqst && rqst->rq_iov) {
|
||||
cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */
|
||||
if (rqst->rq_iov[1].iov_len)
|
||||
kfree(rqst->rq_iov[1].iov_base);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -903,7 +903,7 @@ static int smbd_create_header(struct smbd_connection *info,
|
||||
request->sge[0].addr = ib_dma_map_single(info->id->device,
|
||||
(void *)packet,
|
||||
header_length,
|
||||
DMA_BIDIRECTIONAL);
|
||||
DMA_TO_DEVICE);
|
||||
if (ib_dma_mapping_error(info->id->device, request->sge[0].addr)) {
|
||||
mempool_free(request, info->request_mempool);
|
||||
rc = -EIO;
|
||||
@ -1005,7 +1005,7 @@ static int smbd_post_send_sgl(struct smbd_connection *info,
|
||||
for_each_sg(sgl, sg, num_sgs, i) {
|
||||
request->sge[i+1].addr =
|
||||
ib_dma_map_page(info->id->device, sg_page(sg),
|
||||
sg->offset, sg->length, DMA_BIDIRECTIONAL);
|
||||
sg->offset, sg->length, DMA_TO_DEVICE);
|
||||
if (ib_dma_mapping_error(
|
||||
info->id->device, request->sge[i+1].addr)) {
|
||||
rc = -EIO;
|
||||
@ -2110,8 +2110,10 @@ int smbd_send(struct TCP_Server_Info *server,
|
||||
goto done;
|
||||
}
|
||||
|
||||
rqst_idx = 0;
|
||||
log_write(INFO, "num_rqst=%d total length=%u\n",
|
||||
num_rqst, remaining_data_length);
|
||||
|
||||
rqst_idx = 0;
|
||||
next_rqst:
|
||||
rqst = &rqst_array[rqst_idx];
|
||||
iov = rqst->rq_iov;
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/processor.h>
|
||||
#include <linux/mempool.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include "cifspdu.h"
|
||||
#include "cifsglob.h"
|
||||
#include "cifsproto.h"
|
||||
|
Loading…
Reference in New Issue
Block a user