summaryrefslogtreecommitdiff
path: root/fs/smb/client/smb2ops.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-08-30 21:01:40 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-08-30 21:01:40 -0700
commitb97d64c722598ffed42ece814a2cb791336c6679 (patch)
tree6a4e1062fd7a7bf14811ed39c332ad8bfc98ef01 /fs/smb/client/smb2ops.c
parent47d154eb2ac4e508555937207031ba062119e371 (diff)
parentf3a9b3758e0b6d40183929aba599a7da52313a3e (diff)
Merge tag '6.6-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6
Pull smb client updates from Steve French: - fixes for excessive stack usage - multichannel reconnect improvements - DFS fix and cleanup patches - move UCS-2 conversion code to fs/nls and update cifs and jfs to use them - cleanup patch for compounding, one to fix confusing function name - inode number collision fix - reparse point fixes (including avoiding an extra unneeded query on symlinks) and a minor cleanup - directory lease (caching) improvement * tag '6.6-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6: (24 commits) fs/jfs: Use common ucs2 upper case table fs/smb/client: Use common code in client fs/smb: Swing unicode common code from smb->NLS fs/smb: Remove unicode 'lower' tables SMB3: rename macro CIFS_SERVER_IS_CHAN to avoid confusion [SMB3] send channel sequence number in SMB3 requests after reconnects cifs: update desired access while requesting for directory lease smb: client: reduce stack usage in smb2_query_reparse_point() smb: client: reduce stack usage in smb2_query_info_compound() smb: client: reduce stack usage in smb2_set_ea() smb: client: reduce stack usage in smb_send_rqst() smb: client: reduce stack usage in cifs_demultiplex_thread() smb: client: reduce stack usage in cifs_try_adding_channels() smb: cilent: set reparse mount points as automounts smb: client: query reparse points in older dialects smb: client: do not query reparse points twice on symlinks smb: client: parse reparse point flag in create response smb: client: get rid of dfs code dep in namespace.c smb: client: get rid of dfs naming in automount code smb: client: rename cifs_dfs_ref.c to namespace.c ...
Diffstat (limited to 'fs/smb/client/smb2ops.c')
-rw-r--r--fs/smb/client/smb2ops.c298
1 files changed, 91 insertions, 207 deletions
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 182e2e879ecf..e3dd698854d6 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -172,8 +172,17 @@ smb2_set_credits(struct TCP_Server_Info *server, const int val)
spin_lock(&server->req_lock);
server->credits = val;
- if (val == 1)
+ if (val == 1) {
server->reconnect_instance++;
+ /*
+ * ChannelSequence updated for all channels in primary channel so that consistent
+ * across SMB3 requests sent on any channel. See MS-SMB2 3.2.4.1 and 3.2.7.1
+ */
+ if (SERVER_IS_CHAN(server))
+ server->primary_server->channel_sequence_num++;
+ else
+ server->channel_sequence_num++;
+ }
scredits = server->credits;
in_flight = server->in_flight;
spin_unlock(&server->req_lock);
@@ -1075,31 +1084,28 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
return rc;
}
-
static int
smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
const char *path, const char *ea_name, const void *ea_value,
const __u16 ea_value_len, const struct nls_table *nls_codepage,
struct cifs_sb_info *cifs_sb)
{
+ struct smb2_compound_vars *vars;
struct cifs_ses *ses = tcon->ses;
struct TCP_Server_Info *server = cifs_pick_channel(ses);
+ struct smb_rqst *rqst;
+ struct kvec *rsp_iov;
__le16 *utf16_path = NULL;
int ea_name_len = strlen(ea_name);
int flags = CIFS_CP_CREATE_CLOSE_OP;
int len;
- struct smb_rqst rqst[3];
int resp_buftype[3];
- struct kvec rsp_iov[3];
- struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
struct cifs_open_parms oparms;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
struct cifs_fid fid;
- struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
unsigned int size[1];
void *data[1];
struct smb2_file_full_ea_info *ea = NULL;
- struct kvec close_iov[1];
struct smb2_query_info_rsp *rsp;
int rc, used_len = 0;
@@ -1113,9 +1119,14 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
if (!utf16_path)
return -ENOMEM;
- memset(rqst, 0, sizeof(rqst));
resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
- memset(rsp_iov, 0, sizeof(rsp_iov));
+ vars = kzalloc(sizeof(*vars), GFP_KERNEL);
+ if (!vars) {
+ rc = -ENOMEM;
+ goto out_free_path;
+ }
+ rqst = vars->rqst;
+ rsp_iov = vars->rsp_iov;
if (ses->server->ops->query_all_EAs) {
if (!ea_value) {
@@ -1160,8 +1171,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
}
/* Open */
- memset(&open_iov, 0, sizeof(open_iov));
- rqst[0].rq_iov = open_iov;
+ rqst[0].rq_iov = vars->open_iov;
rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
oparms = (struct cifs_open_parms) {
@@ -1181,8 +1191,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
/* Set Info */
- memset(&si_iov, 0, sizeof(si_iov));
- rqst[1].rq_iov = si_iov;
+ rqst[1].rq_iov = vars->si_iov;
rqst[1].rq_nvec = 1;
len = sizeof(*ea) + ea_name_len + ea_value_len + 1;
@@ -1210,10 +1219,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
smb2_set_next_command(tcon, &rqst[1]);
smb2_set_related(&rqst[1]);
-
/* Close */
- memset(&close_iov, 0, sizeof(close_iov));
- rqst[2].rq_iov = close_iov;
+ rqst[2].rq_iov = &vars->close_iov;
rqst[2].rq_nvec = 1;
rc = SMB2_close_init(tcon, server,
&rqst[2], COMPOUND_FID, COMPOUND_FID, false);
@@ -1228,13 +1235,15 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
sea_exit:
kfree(ea);
- kfree(utf16_path);
SMB2_open_free(&rqst[0]);
SMB2_set_info_free(&rqst[1]);
SMB2_close_free(&rqst[2]);
free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
+ kfree(vars);
+out_free_path:
+ kfree(utf16_path);
return rc;
}
#endif
@@ -1446,16 +1455,6 @@ req_res_key_exit:
return rc;
}
-struct iqi_vars {
- struct smb_rqst rqst[3];
- struct kvec rsp_iov[3];
- struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
- struct kvec qi_iov[1];
- struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
- struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
- struct kvec close_iov[1];
-};
-
static int
smb2_ioctl_query_info(const unsigned int xid,
struct cifs_tcon *tcon,
@@ -1463,7 +1462,7 @@ smb2_ioctl_query_info(const unsigned int xid,
__le16 *path, int is_dir,
unsigned long p)
{
- struct iqi_vars *vars;
+ struct smb2_compound_vars *vars;
struct smb_rqst *rqst;
struct kvec *rsp_iov;
struct cifs_ses *ses = tcon->ses;
@@ -1581,7 +1580,7 @@ smb2_ioctl_query_info(const unsigned int xid,
rc = -EINVAL;
goto free_open_req;
}
- rqst[1].rq_iov = &vars->si_iov[0];
+ rqst[1].rq_iov = vars->si_iov;
rqst[1].rq_nvec = 1;
/* MS-FSCC 2.4.13 FileEndOfFileInformation */
@@ -1593,7 +1592,7 @@ smb2_ioctl_query_info(const unsigned int xid,
SMB2_O_INFO_FILE, 0, data, size);
free_req1_func = SMB2_set_info_free;
} else if (qi.flags == PASSTHRU_QUERY_INFO) {
- rqst[1].rq_iov = &vars->qi_iov[0];
+ rqst[1].rq_iov = &vars->qi_iov;
rqst[1].rq_nvec = 1;
rc = SMB2_query_info_init(tcon, server,
@@ -1615,7 +1614,7 @@ smb2_ioctl_query_info(const unsigned int xid,
smb2_set_related(&rqst[1]);
/* Close */
- rqst[2].rq_iov = &vars->close_iov[0];
+ rqst[2].rq_iov = &vars->close_iov;
rqst[2].rq_nvec = 1;
rc = SMB2_close_init(tcon, server,
@@ -2408,7 +2407,7 @@ smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server)
return false;
/* If server is a channel, select the primary channel */
- pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
+ pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
spin_lock(&cifs_tcp_ses_lock);
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
@@ -2524,15 +2523,13 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
struct kvec *rsp, int *buftype,
struct cifs_sb_info *cifs_sb)
{
+ struct smb2_compound_vars *vars;
struct cifs_ses *ses = tcon->ses;
struct TCP_Server_Info *server = cifs_pick_channel(ses);
int flags = CIFS_CP_CREATE_CLOSE_OP;
- struct smb_rqst rqst[3];
+ struct smb_rqst *rqst;
int resp_buftype[3];
- struct kvec rsp_iov[3];
- struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
- struct kvec qi_iov[1];
- struct kvec close_iov[1];
+ struct kvec *rsp_iov;
u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
struct cifs_open_parms oparms;
struct cifs_fid fid;
@@ -2549,9 +2546,14 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
if (smb3_encryption_required(tcon))
flags |= CIFS_TRANSFORM_REQ;
- memset(rqst, 0, sizeof(rqst));
resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
- memset(rsp_iov, 0, sizeof(rsp_iov));
+ vars = kzalloc(sizeof(*vars), GFP_KERNEL);
+ if (!vars) {
+ rc = -ENOMEM;
+ goto out_free_path;
+ }
+ rqst = vars->rqst;
+ rsp_iov = vars->rsp_iov;
/*
* We can only call this for things we know are directories.
@@ -2560,8 +2562,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
open_cached_dir(xid, tcon, path, cifs_sb, false,
&cfid); /* cfid null if open dir failed */
- memset(&open_iov, 0, sizeof(open_iov));
- rqst[0].rq_iov = open_iov;
+ rqst[0].rq_iov = vars->open_iov;
rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
oparms = (struct cifs_open_parms) {
@@ -2579,8 +2580,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
goto qic_exit;
smb2_set_next_command(tcon, &rqst[0]);
- memset(&qi_iov, 0, sizeof(qi_iov));
- rqst[1].rq_iov = qi_iov;
+ rqst[1].rq_iov = &vars->qi_iov;
rqst[1].rq_nvec = 1;
if (cfid) {
@@ -2607,8 +2607,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
smb2_set_related(&rqst[1]);
}
- memset(&close_iov, 0, sizeof(close_iov));
- rqst[2].rq_iov = close_iov;
+ rqst[2].rq_iov = &vars->close_iov;
rqst[2].rq_nvec = 1;
rc = SMB2_close_init(tcon, server,
@@ -2639,7 +2638,6 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
*buftype = resp_buftype[1];
qic_exit:
- kfree(utf16_path);
SMB2_open_free(&rqst[0]);
SMB2_query_info_free(&rqst[1]);
SMB2_close_free(&rqst[2]);
@@ -2647,6 +2645,9 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
if (cfid)
close_cached_dir(cfid);
+ kfree(vars);
+out_free_path:
+ kfree(utf16_path);
return rc;
}
@@ -2949,154 +2950,32 @@ parse_reparse_point(struct reparse_data_buffer *buf,
}
}
-static int
-smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
- struct cifs_sb_info *cifs_sb, const char *full_path,
- char **target_path, bool is_reparse_point)
+static int smb2_query_symlink(const unsigned int xid,
+ struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb,
+ const char *full_path,
+ char **target_path,
+ struct kvec *rsp_iov)
{
- int rc;
- __le16 *utf16_path = NULL;
- __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
- struct cifs_open_parms oparms;
- struct cifs_fid fid;
- struct kvec err_iov = {NULL, 0};
- struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
- int flags = CIFS_CP_CREATE_CLOSE_OP;
- struct smb_rqst rqst[3];
- int resp_buftype[3];
- struct kvec rsp_iov[3];
- struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
- struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
- struct kvec close_iov[1];
- struct smb2_create_rsp *create_rsp;
- struct smb2_ioctl_rsp *ioctl_rsp;
- struct reparse_data_buffer *reparse_buf;
- int create_options = is_reparse_point ? OPEN_REPARSE_POINT : 0;
- u32 plen;
+ struct reparse_data_buffer *buf;
+ struct smb2_ioctl_rsp *io = rsp_iov->iov_base;
+ u32 plen = le32_to_cpu(io->OutputCount);
cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
- *target_path = NULL;
-
- if (smb3_encryption_required(tcon))
- flags |= CIFS_TRANSFORM_REQ;
-
- memset(rqst, 0, sizeof(rqst));
- resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
- memset(rsp_iov, 0, sizeof(rsp_iov));
-
- utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
- if (!utf16_path)
- return -ENOMEM;
-
- /* Open */
- memset(&open_iov, 0, sizeof(open_iov));
- rqst[0].rq_iov = open_iov;
- rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
-
- oparms = (struct cifs_open_parms) {
- .tcon = tcon,
- .path = full_path,
- .desired_access = FILE_READ_ATTRIBUTES,
- .disposition = FILE_OPEN,
- .create_options = cifs_create_options(cifs_sb, create_options),
- .fid = &fid,
- };
-
- rc = SMB2_open_init(tcon, server,
- &rqst[0], &oplock, &oparms, utf16_path);
- if (rc)
- goto querty_exit;
- smb2_set_next_command(tcon, &rqst[0]);
-
-
- /* IOCTL */
- memset(&io_iov, 0, sizeof(io_iov));
- rqst[1].rq_iov = io_iov;
- rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
-
- rc = SMB2_ioctl_init(tcon, server,
- &rqst[1], fid.persistent_fid,
- fid.volatile_fid, FSCTL_GET_REPARSE_POINT, NULL, 0,
- CIFSMaxBufSize -
- MAX_SMB2_CREATE_RESPONSE_SIZE -
- MAX_SMB2_CLOSE_RESPONSE_SIZE);
- if (rc)
- goto querty_exit;
-
- smb2_set_next_command(tcon, &rqst[1]);
- smb2_set_related(&rqst[1]);
-
-
- /* Close */
- memset(&close_iov, 0, sizeof(close_iov));
- rqst[2].rq_iov = close_iov;
- rqst[2].rq_nvec = 1;
-
- rc = SMB2_close_init(tcon, server,
- &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
- if (rc)
- goto querty_exit;
-
- smb2_set_related(&rqst[2]);
-
- rc = compound_send_recv(xid, tcon->ses, server,
- flags, 3, rqst,
- resp_buftype, rsp_iov);
-
- create_rsp = rsp_iov[0].iov_base;
- if (create_rsp && create_rsp->hdr.Status)
- err_iov = rsp_iov[0];
- ioctl_rsp = rsp_iov[1].iov_base;
-
- /*
- * Open was successful and we got an ioctl response.
- */
- if ((rc == 0) && (is_reparse_point)) {
- /* See MS-FSCC 2.3.23 */
-
- reparse_buf = (struct reparse_data_buffer *)
- ((char *)ioctl_rsp +
- le32_to_cpu(ioctl_rsp->OutputOffset));
- plen = le32_to_cpu(ioctl_rsp->OutputCount);
-
- if (plen + le32_to_cpu(ioctl_rsp->OutputOffset) >
- rsp_iov[1].iov_len) {
- cifs_tcon_dbg(VFS, "srv returned invalid ioctl len: %d\n",
- plen);
- rc = -EIO;
- goto querty_exit;
- }
-
- rc = parse_reparse_point(reparse_buf, plen, target_path,
- cifs_sb);
- goto querty_exit;
- }
-
- if (!rc || !err_iov.iov_base) {
- rc = -ENOENT;
- goto querty_exit;
- }
-
- rc = smb2_parse_symlink_response(cifs_sb, &err_iov, target_path);
-
- querty_exit:
- cifs_dbg(FYI, "query symlink rc %d\n", rc);
- kfree(utf16_path);
- SMB2_open_free(&rqst[0]);
- SMB2_ioctl_free(&rqst[1]);
- SMB2_close_free(&rqst[2]);
- free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
- free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
- free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
- return rc;
+ buf = (struct reparse_data_buffer *)((u8 *)io +
+ le32_to_cpu(io->OutputOffset));
+ return parse_reparse_point(buf, plen, target_path, cifs_sb);
}
-int
-smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
- struct cifs_sb_info *cifs_sb, const char *full_path,
- __u32 *tag)
+static int smb2_query_reparse_point(const unsigned int xid,
+ struct cifs_tcon *tcon,
+ struct cifs_sb_info *cifs_sb,
+ const char *full_path,
+ u32 *tag, struct kvec *rsp,
+ int *rsp_buftype)
{
+ struct smb2_compound_vars *vars;
int rc;
__le16 *utf16_path = NULL;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
@@ -3104,12 +2983,9 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_fid fid;
struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
int flags = CIFS_CP_CREATE_CLOSE_OP;
- struct smb_rqst rqst[3];
+ struct smb_rqst *rqst;
int resp_buftype[3];
- struct kvec rsp_iov[3];
- struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
- struct kvec io_iov[SMB2_IOCTL_IOV_SIZE];
- struct kvec close_iov[1];
+ struct kvec *rsp_iov;
struct smb2_ioctl_rsp *ioctl_rsp;
struct reparse_data_buffer *reparse_buf;
u32 plen;
@@ -3119,20 +2995,24 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
if (smb3_encryption_required(tcon))
flags |= CIFS_TRANSFORM_REQ;
- memset(rqst, 0, sizeof(rqst));
- resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
- memset(rsp_iov, 0, sizeof(rsp_iov));
-
utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
if (!utf16_path)
return -ENOMEM;
+ resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
+ vars = kzalloc(sizeof(*vars), GFP_KERNEL);
+ if (!vars) {
+ rc = -ENOMEM;
+ goto out_free_path;
+ }
+ rqst = vars->rqst;
+ rsp_iov = vars->rsp_iov;
+
/*
* setup smb2open - TODO add optimization to call cifs_get_readable_path
* to see if there is a handle already open that we can use
*/
- memset(&open_iov, 0, sizeof(open_iov));
- rqst[0].rq_iov = open_iov;
+ rqst[0].rq_iov = vars->open_iov;
rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
oparms = (struct cifs_open_parms) {
@@ -3152,8 +3032,7 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
/* IOCTL */
- memset(&io_iov, 0, sizeof(io_iov));
- rqst[1].rq_iov = io_iov;
+ rqst[1].rq_iov = vars->io_iov;
rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
rc = SMB2_ioctl_init(tcon, server,
@@ -3168,10 +3047,8 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
smb2_set_next_command(tcon, &rqst[1]);
smb2_set_related(&rqst[1]);
-
/* Close */
- memset(&close_iov, 0, sizeof(close_iov));
- rqst[2].rq_iov = close_iov;
+ rqst[2].rq_iov = &vars->close_iov;
rqst[2].rq_nvec = 1;
rc = SMB2_close_init(tcon, server,
@@ -3206,16 +3083,21 @@ smb2_query_reparse_tag(const unsigned int xid, struct cifs_tcon *tcon,
goto query_rp_exit;
}
*tag = le32_to_cpu(reparse_buf->ReparseTag);
+ *rsp = rsp_iov[1];
+ *rsp_buftype = resp_buftype[1];
+ resp_buftype[1] = CIFS_NO_BUFFER;
}
query_rp_exit:
- kfree(utf16_path);
SMB2_open_free(&rqst[0]);
SMB2_ioctl_free(&rqst[1]);
SMB2_close_free(&rqst[2]);
free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
+ kfree(vars);
+out_free_path:
+ kfree(utf16_path);
return rc;
}
@@ -4401,7 +4283,7 @@ smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
u8 *ses_enc_key;
/* If server is a channel, select the primary channel */
- pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server;
+ pserver = SERVER_IS_CHAN(server) ? server->primary_server : server;
spin_lock(&cifs_tcp_ses_lock);
list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) {
@@ -5299,6 +5181,7 @@ struct smb_version_operations smb20_operations = {
.can_echo = smb2_can_echo,
.echo = SMB2_echo,
.query_path_info = smb2_query_path_info,
+ .query_reparse_point = smb2_query_reparse_point,
.get_srv_inum = smb2_get_srv_inum,
.query_file_info = smb2_query_file_info,
.set_path_size = smb2_set_path_size,
@@ -5400,6 +5283,7 @@ struct smb_version_operations smb21_operations = {
.can_echo = smb2_can_echo,
.echo = SMB2_echo,
.query_path_info = smb2_query_path_info,
+ .query_reparse_point = smb2_query_reparse_point,
.get_srv_inum = smb2_get_srv_inum,
.query_file_info = smb2_query_file_info,
.set_path_size = smb2_set_path_size,
@@ -5504,7 +5388,7 @@ struct smb_version_operations smb30_operations = {
.echo = SMB2_echo,
.query_path_info = smb2_query_path_info,
/* WSL tags introduced long after smb2.1, enable for SMB3, 3.11 only */
- .query_reparse_tag = smb2_query_reparse_tag,
+ .query_reparse_point = smb2_query_reparse_point,
.get_srv_inum = smb2_get_srv_inum,
.query_file_info = smb2_query_file_info,
.set_path_size = smb2_set_path_size,
@@ -5617,7 +5501,7 @@ struct smb_version_operations smb311_operations = {
.can_echo = smb2_can_echo,
.echo = SMB2_echo,
.query_path_info = smb2_query_path_info,
- .query_reparse_tag = smb2_query_reparse_tag,
+ .query_reparse_point = smb2_query_reparse_point,
.get_srv_inum = smb2_get_srv_inum,
.query_file_info = smb2_query_file_info,
.set_path_size = smb2_set_path_size,