22 changesets, 2 for stable. Includes big performance improvement for large i/o when using multichannel, also includes DFS fixes

-----BEGIN PGP SIGNATURE-----
 
 iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAl7aelsACgkQiiy9cAdy
 T1HDmwv9Fj6OaXXx+btNvbB6xTWvCwMVKHwTPURMx+IjBYjJC65yPGkInPPkfUVo
 7L9h55XCLwFohECleZJCkKOrJtnX1P8SsHtZck6QqjvUETJl/L3pAXpMMYACHLpg
 x4DE/NFkcW95J38s9Jtjhphq8ZGUhuDhaT+QeEd2Iq8HzAxk5ND47ZXkomMx1EEM
 ZsOrmJF+k2YQyDDpfhJeVF5iZDkbpASqA/TlLxxGH34IdAZIUB9qtGKADNLZ6YyT
 qpG601CSrEdl3tVY+SlRMHqwVTRhCViPD6Q3fMw8Xha436RIiWJJ4Rvn6bSP/ZQl
 PDPuSVRB2zmd70C/3ojXdku9+VfQLO52qkO3bf2IjgVJ3ARrxFxW7cb7bmYRqdyT
 WI5N1+8gETrIAK7aB3QKdmkcRFDtJD3wOTfBcgctuB8WrYrDvW2MNKkPbQdY5tnN
 xfp4f10Dg4d+/8knSytJrdKkDublU0kGbfLAa0oupjAzV6WB0qNt0TNGxE42L+ug
 iFSJOZxi
 =gCcP
 -----END PGP SIGNATURE-----

Merge tag '5.8-rc-smb3-fixes-part-1' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs updates from Steve French:
 "22 changesets, 2 for stable.

  Includes big performance improvement for large i/o when using
  multichannel, also includes DFS fixes"

* tag '5.8-rc-smb3-fixes-part-1' of git://git.samba.org/sfrench/cifs-2.6: (22 commits)
  cifs: update internal module version number
  cifs: multichannel: try to rebind when reconnecting a channel
  cifs: multichannel: use pointer for binding channel
  smb3: remove static checker warning
  cifs: multichannel: move channel selection above transport layer
  cifs: multichannel: always zero struct cifs_io_parms
  cifs: dump Security Type info in DebugData
  smb3: fix incorrect number of credits when ioctl MaxOutputResponse > 64K
  smb3: default to minimum of two channels when multichannel specified
  cifs: multichannel: move channel selection in function
  cifs: fix minor typos in comments and log messages
  smb3: minor update to compression header definitions
  cifs: minor fix to two debug messages
  cifs: Standardize logging output
  smb3: Add new parm "nodelete"
  cifs: move some variables off the stack in smb2_ioctl_query_info
  cifs: reduce stack use in smb2_compound_op
  cifs: get rid of unused parameter in reconn_setup_dfs_targets()
  cifs: handle hostnames that resolve to same ip in failover
  cifs: set up next DFS target before generic_ip_connect()
  ...
This commit is contained in:
Linus Torvalds 2020-06-05 16:40:53 -07:00
commit 3803d5e4d3
27 changed files with 1040 additions and 728 deletions

View file

@ -221,6 +221,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
struct cifs_ses *ses;
struct cifs_tcon *tcon;
int i, j;
const char *security_types[] = {"Unspecified", "LANMAN", "NTLM",
"NTLMv2", "RawNTLMSSP", "Kerberos"};
seq_puts(m,
"Display Internal CIFS Data Structures for Debugging\n"
@ -375,6 +377,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
ses->ses_count, ses->serverOS, ses->serverNOS,
ses->capabilities, ses->status);
}
seq_printf(m,"Security type: %s\n",
security_types[server->ops->select_sectype(server, ses->sectype)]);
if (server->rdma)
seq_printf(m, "RDMA\n\t");
seq_printf(m, "TCP status: %d Instance: %d\n\tLocal Users To "

View file

@ -8,6 +8,12 @@
#ifndef _H_CIFS_DEBUG
#define _H_CIFS_DEBUG
#ifdef pr_fmt
#undef pr_fmt
#endif
#define pr_fmt(fmt) "CIFS: " fmt
void cifs_dump_mem(char *label, void *data, int length);
void cifs_dump_detail(void *buf, struct TCP_Server_Info *ptcp_info);
void cifs_dump_mids(struct TCP_Server_Info *);
@ -46,92 +52,81 @@ extern int cifsFYI;
*/
/* Information level messages, minor events */
#define cifs_info_func(ratefunc, fmt, ...) \
do { \
pr_info_ ## ratefunc("CIFS: " fmt, ##__VA_ARGS__); \
} while (0)
#define cifs_info_func(ratefunc, fmt, ...) \
pr_info_ ## ratefunc(fmt, ##__VA_ARGS__)
#define cifs_info(fmt, ...) \
do { \
cifs_info_func(ratelimited, fmt, ##__VA_ARGS__); \
} while (0)
#define cifs_info(fmt, ...) \
cifs_info_func(ratelimited, fmt, ##__VA_ARGS__)
/* information message: e.g., configuration, major event */
#define cifs_dbg_func(ratefunc, type, fmt, ...) \
do { \
if ((type) & FYI && cifsFYI & CIFS_INFO) { \
pr_debug_ ## ratefunc("%s: " \
fmt, __FILE__, ##__VA_ARGS__); \
} else if ((type) & VFS) { \
pr_err_ ## ratefunc("CIFS VFS: " \
fmt, ##__VA_ARGS__); \
} else if ((type) & NOISY && (NOISY != 0)) { \
pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__); \
} \
#define cifs_dbg_func(ratefunc, type, fmt, ...) \
do { \
if ((type) & FYI && cifsFYI & CIFS_INFO) { \
pr_debug_ ## ratefunc("%s: " fmt, \
__FILE__, ##__VA_ARGS__); \
} else if ((type) & VFS) { \
pr_err_ ## ratefunc("VFS: " fmt, ##__VA_ARGS__); \
} else if ((type) & NOISY && (NOISY != 0)) { \
pr_debug_ ## ratefunc(fmt, ##__VA_ARGS__); \
} \
} while (0)
#define cifs_dbg(type, fmt, ...) \
do { \
if ((type) & ONCE) \
cifs_dbg_func(once, \
type, fmt, ##__VA_ARGS__); \
else \
cifs_dbg_func(ratelimited, \
type, fmt, ##__VA_ARGS__); \
#define cifs_dbg(type, fmt, ...) \
do { \
if ((type) & ONCE) \
cifs_dbg_func(once, type, fmt, ##__VA_ARGS__); \
else \
cifs_dbg_func(ratelimited, type, fmt, ##__VA_ARGS__); \
} while (0)
#define cifs_server_dbg_func(ratefunc, type, fmt, ...) \
do { \
const char *sn = ""; \
if (server && server->hostname) \
sn = server->hostname; \
if ((type) & FYI && cifsFYI & CIFS_INFO) { \
pr_debug_ ## ratefunc("%s: \\\\%s " fmt, \
__FILE__, sn, ##__VA_ARGS__); \
} else if ((type) & VFS) { \
pr_err_ ## ratefunc("CIFS VFS: \\\\%s " fmt, \
sn, ##__VA_ARGS__); \
} else if ((type) & NOISY && (NOISY != 0)) { \
pr_debug_ ## ratefunc("\\\\%s " fmt, \
sn, ##__VA_ARGS__); \
} \
#define cifs_server_dbg_func(ratefunc, type, fmt, ...) \
do { \
const char *sn = ""; \
if (server && server->hostname) \
sn = server->hostname; \
if ((type) & FYI && cifsFYI & CIFS_INFO) { \
pr_debug_ ## ratefunc("%s: \\\\%s " fmt, \
__FILE__, sn, ##__VA_ARGS__); \
} else if ((type) & VFS) { \
pr_err_ ## ratefunc("VFS: \\\\%s " fmt, \
sn, ##__VA_ARGS__); \
} else if ((type) & NOISY && (NOISY != 0)) { \
pr_debug_ ## ratefunc("\\\\%s " fmt, \
sn, ##__VA_ARGS__); \
} \
} while (0)
#define cifs_server_dbg(type, fmt, ...) \
do { \
if ((type) & ONCE) \
cifs_server_dbg_func(once, \
type, fmt, ##__VA_ARGS__); \
else \
cifs_server_dbg_func(ratelimited, \
type, fmt, ##__VA_ARGS__); \
#define cifs_server_dbg(type, fmt, ...) \
do { \
if ((type) & ONCE) \
cifs_server_dbg_func(once, type, fmt, ##__VA_ARGS__); \
else \
cifs_server_dbg_func(ratelimited, type, fmt, \
##__VA_ARGS__); \
} while (0)
#define cifs_tcon_dbg_func(ratefunc, type, fmt, ...) \
do { \
const char *tn = ""; \
if (tcon && tcon->treeName) \
tn = tcon->treeName; \
if ((type) & FYI && cifsFYI & CIFS_INFO) { \
pr_debug_ ## ratefunc("%s: %s " fmt, \
__FILE__, tn, ##__VA_ARGS__); \
} else if ((type) & VFS) { \
pr_err_ ## ratefunc("CIFS VFS: %s " fmt, \
tn, ##__VA_ARGS__); \
} else if ((type) & NOISY && (NOISY != 0)) { \
pr_debug_ ## ratefunc("%s " fmt, \
tn, ##__VA_ARGS__); \
} \
#define cifs_tcon_dbg_func(ratefunc, type, fmt, ...) \
do { \
const char *tn = ""; \
if (tcon && tcon->treeName) \
tn = tcon->treeName; \
if ((type) & FYI && cifsFYI & CIFS_INFO) { \
pr_debug_ ## ratefunc("%s: %s " fmt, \
__FILE__, tn, ##__VA_ARGS__); \
} else if ((type) & VFS) { \
pr_err_ ## ratefunc("VFS: %s " fmt, tn, ##__VA_ARGS__); \
} else if ((type) & NOISY && (NOISY != 0)) { \
pr_debug_ ## ratefunc("%s " fmt, tn, ##__VA_ARGS__); \
} \
} while (0)
#define cifs_tcon_dbg(type, fmt, ...) \
do { \
if ((type) & ONCE) \
cifs_tcon_dbg_func(once, \
type, fmt, ##__VA_ARGS__); \
else \
cifs_tcon_dbg_func(ratelimited, \
type, fmt, ##__VA_ARGS__); \
#define cifs_tcon_dbg(type, fmt, ...) \
do { \
if ((type) & ONCE) \
cifs_tcon_dbg_func(once, type, fmt, ##__VA_ARGS__); \
else \
cifs_tcon_dbg_func(ratelimited, type, fmt, \
##__VA_ARGS__); \
} while (0)
/*
@ -159,9 +154,7 @@ do { \
} while (0)
#define cifs_info(fmt, ...) \
do { \
pr_info("CIFS: "fmt, ##__VA_ARGS__); \
} while (0)
pr_info(fmt, ##__VA_ARGS__)
#endif
#endif /* _H_CIFS_DEBUG */

View file

@ -520,7 +520,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
if (rc) {
cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__);
cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
return rc;
}
@ -624,7 +624,7 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
if (rc) {
cifs_dbg(VFS, "%s: could not init hmacmd5\n", __func__);
cifs_dbg(VFS, "%s: Could not init hmacmd5\n", __func__);
return rc;
}
@ -723,7 +723,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
/* calculate ntlmv2_hash */
rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
if (rc) {
cifs_dbg(VFS, "could not get v2 hash rc %d\n", rc);
cifs_dbg(VFS, "Could not get v2 hash rc %d\n", rc);
goto unlock;
}
@ -783,7 +783,7 @@ calc_seckey(struct cifs_ses *ses)
ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL);
if (!ctx_arc4) {
cifs_dbg(VFS, "could not allocate arc4 context\n");
cifs_dbg(VFS, "Could not allocate arc4 context\n");
return -ENOMEM;
}

View file

@ -534,6 +534,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
seq_puts(s, ",signloosely");
if (tcon->nocase)
seq_puts(s, ",nocase");
if (tcon->nodelete)
seq_puts(s, ",nodelete");
if (tcon->local_lease)
seq_puts(s, ",locallease");
if (tcon->retry)

View file

@ -156,5 +156,5 @@ extern int cifs_truncate_page(struct address_space *mapping, loff_t from);
extern const struct export_operations cifs_export_ops;
#endif /* CONFIG_CIFS_NFSD_EXPORT */
#define CIFS_VERSION "2.26"
#define CIFS_VERSION "2.27"
#endif /* _CIFSFS_H */

View file

@ -562,6 +562,7 @@ struct smb_vol {
bool override_gid:1;
bool dynperm:1;
bool noperm:1;
bool nodelete:1;
bool mode_ace:1;
bool no_psx_acl:1; /* set if posix acl support should be disabled */
bool cifs_acl:1;
@ -1029,6 +1030,7 @@ struct cifs_ses {
#define CIFS_MAX_CHANNELS 16
struct cifs_chan chans[CIFS_MAX_CHANNELS];
struct cifs_chan *binding_chan;
size_t chan_count;
size_t chan_max;
atomic_t chan_seq; /* round robin state */
@ -1036,23 +1038,31 @@ struct cifs_ses {
/*
* When binding a new channel, we need to access the channel which isn't fully
* established yet (one past the established count)
* established yet.
*/
static inline
struct cifs_chan *cifs_ses_binding_channel(struct cifs_ses *ses)
{
if (ses->binding)
return &ses->chans[ses->chan_count];
return ses->binding_chan;
else
return NULL;
}
/*
* Returns the server pointer of the session. When binding a new
* channel this returns the last channel which isn't fully established
* yet.
*
* This function should be use for negprot/sess.setup codepaths. For
* the other requests see cifs_pick_channel().
*/
static inline
struct TCP_Server_Info *cifs_ses_server(struct cifs_ses *ses)
{
if (ses->binding)
return ses->chans[ses->chan_count].server;
return ses->binding_chan->server;
else
return ses->server;
}
@ -1136,6 +1146,7 @@ struct cifs_tcon {
bool retry:1;
bool nocase:1;
bool nohandlecache:1; /* if strange server resource prob can turn off */
bool nodelete:1;
bool seal:1; /* transport encryption for this mounted share */
bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol
for this mount even if server would support */
@ -1333,6 +1344,7 @@ struct cifs_io_parms {
__u64 offset;
unsigned int length;
struct cifs_tcon *tcon;
struct TCP_Server_Info *server;
};
struct cifs_aio_ctx {
@ -1380,6 +1392,7 @@ struct cifs_readdata {
struct cifs_readdata *rdata,
struct iov_iter *iter);
struct kvec iov[2];
struct TCP_Server_Info *server;
#ifdef CONFIG_CIFS_SMB_DIRECT
struct smbd_mr *mr;
#endif
@ -1406,6 +1419,7 @@ struct cifs_writedata {
pid_t pid;
unsigned int bytes;
int result;
struct TCP_Server_Info *server;
#ifdef CONFIG_CIFS_SMB_DIRECT
struct smbd_mr *mr;
#endif

View file

@ -45,25 +45,25 @@ extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *,
unsigned int /* length */);
extern unsigned int _get_xid(void);
extern void _free_xid(unsigned int);
#define get_xid() \
({ \
#define get_xid() \
({ \
unsigned int __xid = _get_xid(); \
cifs_dbg(FYI, "CIFS VFS: in %s as Xid: %u with uid: %d\n", \
cifs_dbg(FYI, "VFS: in %s as Xid: %u with uid: %d\n", \
__func__, __xid, \
from_kuid(&init_user_ns, current_fsuid())); \
trace_smb3_enter(__xid, __func__); \
__xid; \
trace_smb3_enter(__xid, __func__); \
__xid; \
})
#define free_xid(curr_xid) \
do { \
_free_xid(curr_xid); \
cifs_dbg(FYI, "CIFS VFS: leaving %s (xid = %u) rc = %d\n", \
__func__, curr_xid, (int)rc); \
if (rc) \
#define free_xid(curr_xid) \
do { \
_free_xid(curr_xid); \
cifs_dbg(FYI, "VFS: leaving %s (xid = %u) rc = %d\n", \
__func__, curr_xid, (int)rc); \
if (rc) \
trace_smb3_exit_err(curr_xid, __func__, (int)rc); \
else \
trace_smb3_exit_done(curr_xid, __func__); \
else \
trace_smb3_exit_done(curr_xid, __func__); \
} while (0)
extern int init_cifs_idmap(void);
extern void exit_cifs_idmap(void);
@ -89,16 +89,20 @@ extern void cifs_mid_q_entry_release(struct mid_q_entry *midEntry);
extern void cifs_wake_up_task(struct mid_q_entry *mid);
extern int cifs_handle_standard(struct TCP_Server_Info *server,
struct mid_q_entry *mid);
extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs);
extern int cifs_discard_remaining_data(struct TCP_Server_Info *server);
extern int cifs_call_async(struct TCP_Server_Info *server,
struct smb_rqst *rqst,
mid_receive_t *receive, mid_callback_t *callback,
mid_handle_t *handle, void *cbdata, const int flags,
const struct cifs_credits *exist_credits);
extern struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses);
extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
struct TCP_Server_Info *server,
struct smb_rqst *rqst, int *resp_buf_type,
const int flags, struct kvec *resp_iov);
extern int compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
struct TCP_Server_Info *server,
const int flags, const int num_rqst,
struct smb_rqst *rqst, int *resp_buf_type,
struct kvec *resp_iov);
@ -589,6 +593,8 @@ void cifs_free_hash(struct crypto_shash **shash, struct sdesc **sdesc);
extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
unsigned int *len, unsigned int *offset);
struct cifs_chan *
cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
int cifs_try_adding_channels(struct cifs_ses *ses);
int cifs_ses_add_channel(struct cifs_ses *ses,
struct cifs_server_iface *iface);
@ -616,6 +622,10 @@ static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
return dfs_cache_find(xid, ses, nls_codepage, remap, old_path,
referral, NULL);
}
int match_target_ip(struct TCP_Server_Info *server,
const char *share, size_t share_len,
bool *result);
#endif
static inline int cifs_create_options(struct cifs_sb_info *cifs_sb, int options)

View file

@ -56,7 +56,7 @@ static int __init cifs_root_setup(char *line)
/* len is strlen(unc) + '\0' */
len = s - line + 1;
if (len > sizeof(root_dev)) {
printk(KERN_ERR "Root-CIFS: UNC path too long\n");
pr_err("Root-CIFS: UNC path too long\n");
return 1;
}
strlcpy(root_dev, line, len);
@ -66,7 +66,7 @@ static int __init cifs_root_setup(char *line)
sizeof(root_opts), "%s,%s",
DEFAULT_MNT_OPTS, s + 1);
if (n >= sizeof(root_opts)) {
printk(KERN_ERR "Root-CIFS: mount options string too long\n");
pr_err("Root-CIFS: mount options string too long\n");
root_opts[sizeof(root_opts)-1] = '\0';
return 1;
}
@ -83,7 +83,7 @@ __setup("cifsroot=", cifs_root_setup);
int __init cifs_root_data(char **dev, char **opts)
{
if (!root_dev[0] || root_server_addr == htonl(INADDR_NONE)) {
printk(KERN_ERR "Root-CIFS: no SMB server address\n");
pr_err("Root-CIFS: no SMB server address\n");
return -1;
}

View file

@ -129,6 +129,7 @@ static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
struct cifs_tcon *tcon)
{
int rc;
struct TCP_Server_Info *server = tcon->ses->server;
struct dfs_cache_tgt_list tl;
struct dfs_cache_tgt_iterator *it = NULL;
char *tree;
@ -141,15 +142,14 @@ static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
if (!tree)
return -ENOMEM;
if (tcon->ipc) {
scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
tcon->ses->server->hostname);
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
goto out;
}
if (!tcon->dfs_path) {
rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
if (tcon->ipc) {
scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
server->hostname);
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
} else {
rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
}
goto out;
}
@ -157,13 +157,13 @@ static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
if (rc)
goto out;
extract_unc_hostname(tcon->ses->server->hostname, &tcp_host,
&tcp_host_len);
extract_unc_hostname(server->hostname, &tcp_host, &tcp_host_len);
for (it = dfs_cache_get_tgt_iterator(&tl); it;
it = dfs_cache_get_next_tgt(&tl, it)) {
const char *share, *prefix;
size_t share_len, prefix_len;
bool target_match;
rc = dfs_cache_get_tgt_share(it, &share, &share_len, &prefix,
&prefix_len);
@ -177,19 +177,38 @@ static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
if (dfs_host_len != tcp_host_len
|| strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
cifs_dbg(FYI, "%s: skipping %.*s, doesn't match %.*s",
cifs_dbg(FYI, "%s: %.*s doesn't match %.*s\n",
__func__,
(int)dfs_host_len, dfs_host,
(int)tcp_host_len, tcp_host);
continue;
rc = match_target_ip(server, dfs_host, dfs_host_len,
&target_match);
if (rc) {
cifs_dbg(VFS, "%s: failed to match target ip: %d\n",
__func__, rc);
break;
}
if (!target_match) {
cifs_dbg(FYI, "%s: skipping target\n", __func__);
continue;
}
}
scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len, share);
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
if (!rc) {
rc = update_super_prepath(tcon, prefix, prefix_len);
break;
if (tcon->ipc) {
scnprintf(tree, MAX_TREE_SIZE, "\\\\%.*s\\IPC$",
(int)share_len, share);
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
} else {
scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len,
share);
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
if (!rc) {
rc = update_super_prepath(tcon, prefix,
prefix_len);
break;
}
}
if (rc == -EREMOTE)
break;
@ -262,8 +281,8 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
(server->tcpStatus != CifsNeedReconnect),
10 * HZ);
if (rc < 0) {
cifs_dbg(FYI, "%s: aborting reconnect due to a received"
" signal by the process\n", __func__);
cifs_dbg(FYI, "%s: aborting reconnect due to a received signal by the process\n",
__func__);
return -ERESTARTSYS;
}
@ -324,7 +343,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);
if (rc) {
printk_once(KERN_WARNING "reconnect tcon failed rc = %d\n", rc);
pr_warn_once("reconnect tcon failed rc = %d\n", rc);
goto out;
}
@ -557,7 +576,7 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
/* If server requires signing, does client allow it? */
if (srv_sign_required) {
if (!mnt_sign_enabled) {
cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!");
cifs_dbg(VFS, "Server requires signing, but it's disabled in SecurityFlags!\n");
return -ENOTSUPP;
}
server->sign = true;
@ -566,14 +585,14 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
/* If client requires signing, does server allow it? */
if (mnt_sign_required) {
if (!srv_sign_enabled) {
cifs_dbg(VFS, "Server does not support signing!");
cifs_dbg(VFS, "Server does not support signing!\n");
return -ENOTSUPP;
}
server->sign = true;
}
if (cifs_rdma_enabled(server) && server->sign)
cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled");
cifs_dbg(VFS, "Signing is enabled, and RDMA read/write will be disabled\n");
return 0;
}
@ -703,7 +722,7 @@ CIFSSMBNegotiate(const unsigned int xid, struct cifs_ses *ses)
pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
if (should_set_ext_sec_flag(ses->sectype)) {
cifs_dbg(FYI, "Requesting extended security.");
cifs_dbg(FYI, "Requesting extended security\n");
pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
}
@ -2375,7 +2394,7 @@ int
CIFSSMBWrite2(const unsigned int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, struct kvec *iov, int n_vec)
{
int rc = -EACCES;
int rc;
WRITE_REQ *pSMB = NULL;
int wct;
int smb_hdr_len;
@ -3868,7 +3887,7 @@ CIFSGetExtAttr(const unsigned int xid, struct cifs_tcon *tcon,
struct file_chattr_info *pfinfo;
/* BB Do we need a cast or hash here ? */
if (count != 16) {
cifs_dbg(FYI, "Illegal size ret in GetExtAttr\n");
cifs_dbg(FYI, "Invalid size ret in GetExtAttr\n");
rc = -EIO;
goto GetExtAttrOut;
}
@ -4244,7 +4263,7 @@ CIFSSMBQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cifs_dbg(FYI, "Send error in QFileInfo = %d", rc);
cifs_dbg(FYI, "Send error in QFileInfo = %d\n", rc);
} else { /* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@ -4411,7 +4430,7 @@ CIFSSMBUnixQFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cifs_dbg(FYI, "Send error in UnixQFileInfo = %d", rc);
cifs_dbg(FYI, "Send error in UnixQFileInfo = %d\n", rc);
} else { /* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@ -4493,7 +4512,7 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) {
cifs_dbg(FYI, "Send error in UnixQPathInfo = %d", rc);
cifs_dbg(FYI, "Send error in UnixQPathInfo = %d\n", rc);
} else { /* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@ -4913,7 +4932,7 @@ CIFSGetSrvInodeNumber(const unsigned int xid, struct cifs_tcon *tcon,
struct file_internal_info *pfinfo;
/* BB Do we need a cast or hash here ? */
if (count < 8) {
cifs_dbg(FYI, "Illegal size ret in QryIntrnlInf\n");
cifs_dbg(FYI, "Invalid size ret in QryIntrnlInf\n");
rc = -EIO;
goto GetInodeNumOut;
}

View file

@ -75,7 +75,7 @@ enum {
Opt_forceuid, Opt_noforceuid,
Opt_forcegid, Opt_noforcegid,
Opt_noblocksend, Opt_noautotune, Opt_nolease,
Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
Opt_hard, Opt_soft, Opt_perm, Opt_noperm, Opt_nodelete,
Opt_mapposix, Opt_nomapposix,
Opt_mapchars, Opt_nomapchars, Opt_sfu,
Opt_nosfu, Opt_nodfs, Opt_posixpaths,
@ -141,6 +141,7 @@ static const match_table_t cifs_mount_option_tokens = {
{ Opt_soft, "soft" },
{ Opt_perm, "perm" },
{ Opt_noperm, "noperm" },
{ Opt_nodelete, "nodelete" },
{ Opt_mapchars, "mapchars" }, /* SFU style */
{ Opt_nomapchars, "nomapchars" },
{ Opt_mapposix, "mapposix" }, /* SFM style */
@ -426,8 +427,7 @@ static void reconn_inval_dfs_target(struct TCP_Server_Info *server,
}
static inline int reconn_setup_dfs_targets(struct cifs_sb_info *cifs_sb,
struct dfs_cache_tgt_list *tl,
struct dfs_cache_tgt_iterator **it)
struct dfs_cache_tgt_list *tl)
{
if (!cifs_sb->origin_fullpath)
return -EOPNOTSUPP;
@ -472,7 +472,7 @@ cifs_reconnect(struct TCP_Server_Info *server)
} else {
cifs_sb = CIFS_SB(sb);
rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list, &tgt_it);
rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list);
if (rc && (rc != -EOPNOTSUPP)) {
cifs_server_dbg(VFS, "%s: no target servers for DFS failover\n",
__func__);
@ -572,26 +572,26 @@ cifs_reconnect(struct TCP_Server_Info *server)
try_to_freeze();
mutex_lock(&server->srv_mutex);
#ifdef CONFIG_CIFS_DFS_UPCALL
/*
* Set up next DFS target server (if any) for reconnect. If DFS
* feature is disabled, then we will retry last server we
* connected to before.
*/
reconn_inval_dfs_target(server, cifs_sb, &tgt_list, &tgt_it);
#endif
rc = reconn_set_ipaddr(server);
if (rc) {
cifs_dbg(FYI, "%s: failed to resolve hostname: %d\n",
__func__, rc);
}
if (cifs_rdma_enabled(server))
rc = smbd_reconnect(server);
else
rc = generic_ip_connect(server);
if (rc) {
cifs_dbg(FYI, "reconnect error %d\n", rc);
#ifdef CONFIG_CIFS_DFS_UPCALL
reconn_inval_dfs_target(server, cifs_sb, &tgt_list,
&tgt_it);
#endif
rc = reconn_set_ipaddr(server);
if (rc) {
cifs_dbg(FYI, "%s: failed to resolve hostname: %d\n",
__func__, rc);
}
mutex_unlock(&server->srv_mutex);
msleep(3000);
} else {
@ -879,8 +879,7 @@ dequeue_mid(struct mid_q_entry *mid, bool malformed)
* function has finished processing it is a bug.
*/
if (mid->mid_flags & MID_DELETED)
printk_once(KERN_WARNING
"trying to dequeue a deleted mid\n");
pr_warn_once("trying to dequeue a deleted mid\n");
else {
list_del_init(&mid->qhead);
mid->mid_flags |= MID_DELETED;
@ -1229,9 +1228,8 @@ cifs_demultiplex_thread(void *p)
smb2_add_credits_from_hdr(bufs[i], server);
cifs_dbg(FYI, "Received oplock break\n");
} else {
cifs_server_dbg(VFS, "No task to wake, unknown frame "
"received! NumMids %d\n",
atomic_read(&midCount));
cifs_server_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n",
atomic_read(&midCount));
cifs_dump_mem("Received Data is: ", bufs[i],
HEADER_SIZE(server));
smb2_add_credits_from_hdr(bufs[i], server);
@ -1476,9 +1474,7 @@ cifs_parse_smb_version(char *value, struct smb_vol *vol, bool is_smb3)
cifs_dbg(VFS, "vers=1.0 (cifs) not permitted when mounting with smb3\n");
return 1;
}
cifs_dbg(VFS, "Use of the less secure dialect vers=1.0 "
"is not recommended unless required for "
"access to very old servers\n");
cifs_dbg(VFS, "Use of the less secure dialect vers=1.0 is not recommended unless required for access to very old servers\n");
vol->ops = &smb1_operations;
vol->vals = &smb1_values;
break;
@ -1545,7 +1541,7 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol)
size_t len;
if (unlikely(!devname || !*devname)) {
cifs_dbg(VFS, "Device name not specified.\n");
cifs_dbg(VFS, "Device name not specified\n");
return -EINVAL;
}
@ -1695,13 +1691,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
case 0:
break;
case -ENOMEM:
cifs_dbg(VFS, "Unable to allocate memory for devname.\n");
cifs_dbg(VFS, "Unable to allocate memory for devname\n");
goto cifs_parse_mount_err;
case -EINVAL:
cifs_dbg(VFS, "Malformed UNC in devname.\n");
cifs_dbg(VFS, "Malformed UNC in devname\n");
goto cifs_parse_mount_err;
default:
cifs_dbg(VFS, "Unknown error parsing devname.\n");
cifs_dbg(VFS, "Unknown error parsing devname\n");
goto cifs_parse_mount_err;
}
@ -1761,6 +1757,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
case Opt_noperm:
vol->noperm = 1;
break;
case Opt_nodelete:
vol->nodelete = 1;
break;
case Opt_mapchars:
vol->sfu_remap = true;
vol->remap = false; /* disable SFM mapping */
@ -1909,7 +1908,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
vol->seal = 1;
break;
case Opt_noac:
pr_warn("CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
pr_warn("Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
break;
case Opt_fsc:
#ifndef CONFIG_CIFS_FSCACHE
@ -1965,9 +1964,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
break;
case Opt_multichannel:
vol->multichannel = true;
/* if number of channels not specified, default to 2 */
if (vol->max_channels < 2)
vol->max_channels = 2;
break;
case Opt_nomultichannel:
vol->multichannel = false;
vol->max_channels = 1;
break;
case Opt_compress:
vol->compression = UNKNOWN_TYPE;
@ -2156,7 +2159,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
if (strnlen(string, CIFS_MAX_USERNAME_LEN) >
CIFS_MAX_USERNAME_LEN) {
pr_warn("CIFS: username too long\n");
pr_warn("username too long\n");
goto cifs_parse_mount_err;
}
@ -2222,7 +2225,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
temp_len = strlen(value);
vol->password = kzalloc(temp_len+1, GFP_KERNEL);
if (vol->password == NULL) {
pr_warn("CIFS: no memory for password\n");
pr_warn("no memory for password\n");
goto cifs_parse_mount_err;
}
@ -2246,7 +2249,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
if (!cifs_convert_address(dstaddr, string,
strlen(string))) {
pr_err("CIFS: bad ip= option (%s).\n", string);
pr_err("bad ip= option (%s)\n", string);
goto cifs_parse_mount_err;
}
got_ip = true;
@ -2258,14 +2261,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
if (strnlen(string, CIFS_MAX_DOMAINNAME_LEN)
== CIFS_MAX_DOMAINNAME_LEN) {
pr_warn("CIFS: domain name too long\n");
pr_warn("domain name too long\n");
goto cifs_parse_mount_err;
}
kfree(vol->domainname);
vol->domainname = kstrdup(string, GFP_KERNEL);
if (!vol->domainname) {
pr_warn("CIFS: no memory for domainname\n");
pr_warn("no memory for domainname\n");
goto cifs_parse_mount_err;
}
cifs_dbg(FYI, "Domain name set\n");
@ -2278,7 +2281,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
if (!cifs_convert_address(
(struct sockaddr *)&vol->srcaddr,
string, strlen(string))) {
pr_warn("CIFS: Could not parse srcaddr: %s\n",
pr_warn("Could not parse srcaddr: %s\n",
string);
goto cifs_parse_mount_err;
}
@ -2289,7 +2292,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
goto out_nomem;
if (strnlen(string, 1024) >= 65) {
pr_warn("CIFS: iocharset name too long.\n");
pr_warn("iocharset name too long\n");
goto cifs_parse_mount_err;
}
@ -2298,7 +2301,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
vol->iocharset = kstrdup(string,
GFP_KERNEL);
if (!vol->iocharset) {
pr_warn("CIFS: no memory for charset\n");
pr_warn("no memory for charset\n");
goto cifs_parse_mount_err;
}
}
@ -2329,7 +2332,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
* set at top of the function
*/
if (i == RFC1001_NAME_LEN && string[i] != 0)
pr_warn("CIFS: netbiosname longer than 15 truncated.\n");
pr_warn("netbiosname longer than 15 truncated\n");
break;
case Opt_servern:
/* servernetbiosname specified override *SMBSERVER */
@ -2355,7 +2358,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
/* The string has 16th byte zero still from
set at top of the function */
if (i == RFC1001_NAME_LEN && string[i] != 0)
pr_warn("CIFS: server netbiosname longer than 15 truncated.\n");
pr_warn("server netbiosname longer than 15 truncated\n");
break;
case Opt_ver:
/* version of mount userspace tools, not dialect */
@ -2366,17 +2369,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
/* If interface changes in mount.cifs bump to new ver */
if (strncasecmp(string, "1", 1) == 0) {
if (strlen(string) > 1) {
pr_warn("Bad mount helper ver=%s. Did "
"you want SMB1 (CIFS) dialect "
"and mean to type vers=1.0 "
"instead?\n", string);
pr_warn("Bad mount helper ver=%s. Did you want SMB1 (CIFS) dialect and mean to type vers=1.0 instead?\n",
string);
goto cifs_parse_mount_err;
}
/* This is the default */
break;
}
/* For all other value, error */
pr_warn("CIFS: Invalid mount helper version specified\n");
pr_warn("Invalid mount helper version specified\n");
goto cifs_parse_mount_err;
case Opt_vers:
/* protocol version (dialect) */
@ -2419,7 +2420,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
}
if (!sloppy && invalid) {
pr_err("CIFS: Unknown mount option \"%s\"\n", invalid);
pr_err("Unknown mount option \"%s\"\n", invalid);
goto cifs_parse_mount_err;
}
@ -2455,7 +2456,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
slash = strchr(&vol->UNC[2], '\\');
len = slash - &vol->UNC[2];
if (!cifs_convert_address(dstaddr, &vol->UNC[2], len)) {
pr_err("Unable to determine destination address.\n");
pr_err("Unable to determine destination address\n");
goto cifs_parse_mount_err;
}
}
@ -2466,20 +2467,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
if (uid_specified)
vol->override_uid = override_uid;
else if (override_uid == 1)
pr_notice("CIFS: ignoring forceuid mount option specified with no uid= option.\n");
pr_notice("ignoring forceuid mount option specified with no uid= option\n");
if (gid_specified)
vol->override_gid = override_gid;
else if (override_gid == 1)
pr_notice("CIFS: ignoring forcegid mount option specified with no gid= option.\n");
pr_notice("ignoring forcegid mount option specified with no gid= option\n");
if (got_version == false)
pr_warn_once("No dialect specified on mount. Default has changed"
" to a more secure dialect, SMB2.1 or later (e.g. "
"SMB3.1.1), from CIFS (SMB1). To use the less secure "
"SMB1 dialect to access old servers which do not "
"support SMB3.1.1 (or even SMB3 or SMB2.1) specify "
"vers=1.0 on mount.\n");
pr_warn_once("No dialect specified on mount. Default has changed to a more secure dialect, SMB2.1 or later (e.g. SMB3.1.1), from CIFS (SMB1). To use the less secure SMB1 dialect to access old servers which do not support SMB3.1.1 (or even SMB3 or SMB2.1) specify vers=1.0 on mount.\n");
kfree(mountdata_copy);
return 0;
@ -2496,8 +2492,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
* specified, or if srcaddr is specified and
* matches the IP address of the rhs argument.
*/
static bool
srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
bool
cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs)
{
switch (srcaddr->sa_family) {
case AF_UNSPEC:
@ -2588,7 +2584,7 @@ match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
return false; /* don't expect to be here */
}
if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
if (!cifs_match_ipaddr(srcaddr, (struct sockaddr *)&server->srcaddr))
return false;
return true;
@ -3197,8 +3193,8 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
strlen(ses->domainName),
GFP_KERNEL);
if (!vol->domainname) {
cifs_dbg(FYI, "Unable to allocate %zd bytes for "
"domain\n", len);
cifs_dbg(FYI, "Unable to allocate %zd bytes for domain\n",
len);
rc = -ENOMEM;
kfree(vol->username);
vol->username = NULL;
@ -3363,6 +3359,8 @@ static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info)
return 0;
if (tcon->no_lease != volume_info->no_lease)
return 0;
if (tcon->nodelete != volume_info->nodelete)
return 0;
return 1;
}
@ -3519,10 +3517,9 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
if (volume_info->linux_ext) {
if (ses->server->posix_ext_supported) {
tcon->posix_extensions = true;
printk_once(KERN_WARNING
"SMB3.11 POSIX Extensions are experimental\n");
pr_warn_once("SMB3.11 POSIX Extensions are experimental\n");
} else {
cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions.\n");
cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions\n");
rc = -EOPNOTSUPP;
goto out_fail;
}
@ -3580,6 +3577,16 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
cifs_dbg(VFS, "cache=singleclient requested on mount but NO_CACHING flag set on share\n");
}
if (volume_info->no_lease) {
if (ses->server->vals->protocol_id == 0) {
cifs_dbg(VFS,
"SMB2 or later required for nolease option\n");
rc = -EOPNOTSUPP;
goto out_fail;
} else
tcon->no_lease = volume_info->no_lease;
}
/*
* We can have only one retry value for a connection to a share so for
* resources mounted more than once to the same server share the last
@ -3588,8 +3595,8 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
tcon->retry = volume_info->retry;
tcon->nocase = volume_info->nocase;
tcon->nohandlecache = volume_info->nohandlecache;
tcon->nodelete = volume_info->nodelete;
tcon->local_lease = volume_info->local_lease;
tcon->no_lease = volume_info->no_lease;
INIT_LIST_HEAD(&tcon->pending_opens);
spin_lock(&cifs_tcp_ses_lock);
@ -4736,8 +4743,7 @@ static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol,
rc = cifs_are_all_path_components_accessible(server, xid, tcon,
cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS);
if (rc != 0) {
cifs_server_dbg(VFS, "cannot query dirs between root and final path, "
"enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
cifs_server_dbg(VFS, "cannot query dirs between root and final path, enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
rc = 0;
}

View file

@ -198,7 +198,7 @@ static ssize_t dfscache_proc_write(struct file *file, const char __user *buffer,
if (c != '0')
return -EINVAL;
cifs_dbg(FYI, "clearing dfs cache");
cifs_dbg(FYI, "clearing dfs cache\n");
down_write(&htable_rw_lock);
flush_cache_ents();
@ -234,8 +234,8 @@ static inline void dump_tgts(const struct cache_entry *ce)
static inline void dump_ce(const struct cache_entry *ce)
{
cifs_dbg(FYI, "cache entry: path=%s,type=%s,ttl=%d,etime=%ld,"
"interlink=%s,path_consumed=%d,expired=%s\n", ce->path,
cifs_dbg(FYI, "cache entry: path=%s,type=%s,ttl=%d,etime=%ld,interlink=%s,path_consumed=%d,expired=%s\n",
ce->path,
ce->srvtype == DFS_TYPE_ROOT ? "root" : "link", ce->ttl,
ce->etime.tv_nsec,
IS_INTERLINK_SET(ce->flags) ? "yes" : "no",
@ -453,11 +453,11 @@ static void remove_oldest_entry(void)
}
if (!to_del) {
cifs_dbg(FYI, "%s: no entry to remove", __func__);
cifs_dbg(FYI, "%s: no entry to remove\n", __func__);
return;
}
cifs_dbg(FYI, "%s: removing entry", __func__);
cifs_dbg(FYI, "%s: removing entry\n", __func__);
dump_ce(to_del);
flush_cache_ent(to_del);
}
@ -696,8 +696,8 @@ static int __dfs_cache_find(const unsigned int xid, struct cifs_ses *ses,
}
if (atomic_read(&cache_count) >= CACHE_MAX_ENTRIES) {
cifs_dbg(FYI, "%s: reached max cache size (%d)", __func__,
CACHE_MAX_ENTRIES);
cifs_dbg(FYI, "%s: reached max cache size (%d)\n",
__func__, CACHE_MAX_ENTRIES);
down_write(&htable_rw_lock);
remove_oldest_entry();
up_write(&htable_rw_lock);

View file

@ -857,7 +857,7 @@ cifs_reopen_persistent_handles(struct cifs_tcon *tcon)
tcon->need_reopen_files = false;
cifs_dbg(FYI, "Reopen persistent handles");
cifs_dbg(FYI, "Reopen persistent handles\n");
INIT_LIST_HEAD(&tmp_list);
/* list all files open on tree connection, reopen resilient handles */
@ -1853,7 +1853,7 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data,
unsigned int xid;
struct dentry *dentry = open_file->dentry;
struct cifsInodeInfo *cifsi = CIFS_I(d_inode(dentry));
struct cifs_io_parms io_parms;
struct cifs_io_parms io_parms = {0};
cifs_dbg(FYI, "write %zd bytes to offset %lld of %pd\n",
write_size, *offset, dentry);
@ -2056,7 +2056,7 @@ find_writable_file(struct cifsInodeInfo *cifs_inode, int flags)
rc = cifs_get_writable_file(cifs_inode, flags, &cfile);
if (rc)
cifs_dbg(FYI, "couldn't find writable handle rc=%d", rc);
cifs_dbg(FYI, "Couldn't find writable handle rc=%d\n", rc);
return cfile;
}
@ -2292,8 +2292,6 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
struct address_space *mapping, struct writeback_control *wbc)
{
int rc;
struct TCP_Server_Info *server =
tlink_tcon(wdata->cfile->tlink)->ses->server;
wdata->sync_mode = wbc->sync_mode;
wdata->nr_pages = nr_pages;
@ -2305,14 +2303,15 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
wdata->bytes = ((nr_pages - 1) * PAGE_SIZE) + wdata->tailsz;
wdata->pid = wdata->cfile->pid;
rc = adjust_credits(server, &wdata->credits, wdata->bytes);
rc = adjust_credits(wdata->server, &wdata->credits, wdata->bytes);
if (rc)
return rc;
if (wdata->cfile->invalidHandle)
rc = -EAGAIN;
else
rc = server->ops->async_writev(wdata, cifs_writedata_release);
rc = wdata->server->ops->async_writev(wdata,
cifs_writedata_release);
return rc;
}
@ -2349,7 +2348,8 @@ static int cifs_writepages(struct address_space *mapping,
range_whole = true;
scanned = true;
}
server = cifs_sb_master_tcon(cifs_sb)->ses->server;
server = cifs_pick_channel(cifs_sb_master_tcon(cifs_sb)->ses);
retry:
while (!done && index <= end) {
unsigned int i, nr_pages, found_pages, wsize;
@ -2403,6 +2403,7 @@ static int cifs_writepages(struct address_space *mapping,
wdata->credits = credits_on_stack;
wdata->cfile = cfile;
wdata->server = server;
cfile = NULL;
if (!wdata->cfile) {
@ -2806,8 +2807,7 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
unsigned int wsize;
struct cifs_credits credits;
int rc;
struct TCP_Server_Info *server =
tlink_tcon(wdata->cfile->tlink)->ses->server;
struct TCP_Server_Info *server = wdata->server;
do {
if (wdata->cfile->invalidHandle) {
@ -2893,7 +2893,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
else
pid = current->tgid;
server = tlink_tcon(open_file->tlink)->ses->server;
server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
xid = get_xid();
do {
@ -2923,11 +2923,9 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
from, &pagevec, cur_len, &start);
if (result < 0) {
cifs_dbg(VFS,
"direct_writev couldn't get user pages "
"(rc=%zd) iter type %d iov_offset %zd "
"count %zd\n",
result, iov_iter_type(from),
from->iov_offset, from->count);
"direct_writev couldn't get user pages (rc=%zd) iter type %d iov_offset %zd count %zd\n",
result, iov_iter_type(from),
from->iov_offset, from->count);
dump_stack();
rc = result;
@ -2999,6 +2997,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
wdata->nr_pages = nr_pages;
wdata->offset = (__u64)offset;
wdata->cfile = cifsFileInfo_get(open_file);
wdata->server = server;
wdata->pid = pid;
wdata->bytes = cur_len;
wdata->pagesz = PAGE_SIZE;
@ -3540,8 +3539,10 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
unsigned int rsize;
struct cifs_credits credits;
int rc;
struct TCP_Server_Info *server =
tlink_tcon(rdata->cfile->tlink)->ses->server;
struct TCP_Server_Info *server;
/* XXX: should we pick a new channel here? */
server = rdata->server;
do {
if (rdata->cfile->invalidHandle) {
@ -3620,7 +3621,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
size_t start;
struct iov_iter direct_iov = ctx->iter;
server = tlink_tcon(open_file->tlink)->ses->server;
server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
@ -3654,12 +3655,10 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
cur_len, &start);
if (result < 0) {
cifs_dbg(VFS,
"couldn't get user pages (rc=%zd)"
" iter type %d"
" iov_offset %zd count %zd\n",
result, iov_iter_type(&direct_iov),
direct_iov.iov_offset,
direct_iov.count);
"Couldn't get user pages (rc=%zd) iter type %d iov_offset %zd count %zd\n",
result, iov_iter_type(&direct_iov),
direct_iov.iov_offset,
direct_iov.count);
dump_stack();
rc = result;
@ -3706,6 +3705,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
rdata->tailsz = PAGE_SIZE;
}
rdata->server = server;
rdata->cfile = cifsFileInfo_get(open_file);
rdata->nr_pages = npages;
rdata->offset = offset;
@ -4018,7 +4018,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
unsigned int xid;
char *cur_offset;
struct cifsFileInfo *open_file;
struct cifs_io_parms io_parms;
struct cifs_io_parms io_parms = {0};
int buf_type = CIFS_NO_BUFFER;
__u32 pid;
@ -4035,7 +4035,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
}
open_file = file->private_data;
tcon = tlink_tcon(open_file->tlink);
server = tcon->ses->server;
server = cifs_pick_channel(tcon->ses);
if (!server->ops->sync_read) {
free_xid(xid);
@ -4074,6 +4074,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
io_parms.tcon = tcon;
io_parms.offset = *offset;
io_parms.length = current_read_size;
io_parms.server = server;
rc = server->ops->sync_read(xid, &open_file->fid, &io_parms,
&bytes_read, &cur_offset,
&buf_type);
@ -4376,7 +4377,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
pid = current->tgid;
rc = 0;
server = tlink_tcon(open_file->tlink)->ses->server;
server = cifs_pick_channel(tlink_tcon(open_file->tlink)->ses);
cifs_dbg(FYI, "%s: file=%p mapping=%p num_pages=%u\n",
__func__, file, mapping, num_pages);
@ -4447,6 +4448,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
}
rdata->cfile = cifsFileInfo_get(open_file);
rdata->server = server;
rdata->mapping = mapping;
rdata->offset = offset;
rdata->bytes = bytes;
@ -4828,7 +4830,7 @@ static int cifs_swap_activate(struct swap_info_struct *sis,
}
*span = sis->pages;
printk_once(KERN_WARNING "Swap support over SMB3 is experimental\n");
pr_warn_once("Swap support over SMB3 is experimental\n");
/*
* TODO: consider adding ACL (or documenting how) to prevent other

View file

@ -448,7 +448,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
struct cifs_tcon *tcon;
struct cifs_fid fid;
struct cifs_open_parms oparms;
struct cifs_io_parms io_parms;
struct cifs_io_parms io_parms = {0};
char buf[24];
unsigned int bytes_read;
char *pbuf;
@ -1156,7 +1156,7 @@ struct inode *cifs_root_iget(struct super_block *sb)
/* some servers mistakenly claim POSIX support */
if (rc != -EOPNOTSUPP)
goto iget_no_retry;
cifs_dbg(VFS, "server does not support POSIX extensions");
cifs_dbg(VFS, "server does not support POSIX extensions\n");
tcon->unix_ext = false;
}
@ -1419,6 +1419,11 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
xid = get_xid();
if (tcon->nodelete) {
rc = -EACCES;
goto unlink_out;
}
/* Unlink can be called from rename so we can not take the
* sb->s_vfs_rename_mutex here */
full_path = build_path_from_dentry(dentry);
@ -1747,6 +1752,12 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
goto rmdir_exit;
}
if (tcon->nodelete) {
rc = -EACCES;
cifs_put_tlink(tlink);
goto rmdir_exit;
}
rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb);
cifs_put_tlink(tlink);
@ -2000,7 +2011,7 @@ cifs_invalidate_mapping(struct inode *inode)
if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
rc = invalidate_inode_pages2(inode->i_mapping);
if (rc)
cifs_dbg(VFS, "%s: could not invalidate inode %p\n",
cifs_dbg(VFS, "%s: Could not invalidate inode %p\n",
__func__, inode);
}

View file

@ -308,7 +308,7 @@ cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
int oplock = 0;
struct cifs_fid fid;
struct cifs_open_parms oparms;
struct cifs_io_parms io_parms;
struct cifs_io_parms io_parms = {0};
int buf_type = CIFS_NO_BUFFER;
FILE_ALL_INFO file_info;
@ -352,7 +352,7 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
int oplock = 0;
struct cifs_fid fid;
struct cifs_open_parms oparms;
struct cifs_io_parms io_parms;
struct cifs_io_parms io_parms = {0};
oparms.tcon = tcon;
oparms.cifs_sb = cifs_sb;
@ -389,7 +389,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
int rc;
struct cifs_fid fid;
struct cifs_open_parms oparms;
struct cifs_io_parms io_parms;
struct cifs_io_parms io_parms = {0};
int buf_type = CIFS_NO_BUFFER;
__le16 *utf16_path;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
@ -450,7 +450,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
int rc;
struct cifs_fid fid;
struct cifs_open_parms oparms;
struct cifs_io_parms io_parms;
struct cifs_io_parms io_parms = {0};
__le16 *utf16_path;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
struct kvec iov[2];

View file

@ -32,6 +32,9 @@
#include "cifs_unicode.h"
#include "smb2pdu.h"
#include "cifsfs.h"
#ifdef CONFIG_CIFS_DFS_UPCALL
#include "dns_resolve.h"
#endif
extern mempool_t *cifs_sm_req_poolp;
extern mempool_t *cifs_req_poolp;
@ -421,7 +424,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
if (data_offset >
len - sizeof(struct file_notify_information)) {
cifs_dbg(FYI, "invalid data_offset %u\n",
cifs_dbg(FYI, "Invalid data_offset %u\n",
data_offset);
return true;
}
@ -449,7 +452,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
large dirty files cached on the client */
if ((NT_STATUS_INVALID_HANDLE) ==
le32_to_cpu(pSMB->hdr.Status.CifsError)) {
cifs_dbg(FYI, "invalid handle on oplock break\n");
cifs_dbg(FYI, "Invalid handle on oplock break\n");
return true;
} else if (ERRbadfid ==
le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
@ -530,9 +533,9 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
cifs_sb->mnt_cifs_serverino_autodisabled = true;
cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s.\n",
cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s\n",
tcon ? tcon->treeName : "new server");
cifs_dbg(VFS, "The server doesn't seem to support them properly or the files might be on different servers (DFS).\n");
cifs_dbg(VFS, "The server doesn't seem to support them properly or the files might be on different servers (DFS)\n");
cifs_dbg(VFS, "Hardlinks will not be recognized on this mount. Consider mounting with the \"noserverino\" option to silence this message.\n");
}
@ -874,7 +877,7 @@ setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw)
while (count && npages < max_pages) {
rc = iov_iter_get_pages(iter, pages, count, max_pages, &start);
if (rc < 0) {
cifs_dbg(VFS, "couldn't get user pages (rc=%zd)\n", rc);
cifs_dbg(VFS, "Couldn't get user pages (rc=%zd)\n", rc);
break;
}
@ -933,7 +936,7 @@ cifs_alloc_hash(const char *name,
*shash = crypto_alloc_shash(name, 0, 0);
if (IS_ERR(*shash)) {
cifs_dbg(VFS, "could not allocate crypto %s\n", name);
cifs_dbg(VFS, "Could not allocate crypto %s\n", name);
rc = PTR_ERR(*shash);
*shash = NULL;
*sdesc = NULL;
@ -1083,6 +1086,51 @@ void cifs_put_tcp_super(struct super_block *sb)
}
#ifdef CONFIG_CIFS_DFS_UPCALL
int match_target_ip(struct TCP_Server_Info *server,
const char *share, size_t share_len,
bool *result)
{
int rc;
char *target, *tip = NULL;
struct sockaddr tipaddr;
*result = false;
target = kzalloc(share_len + 3, GFP_KERNEL);
if (!target) {
rc = -ENOMEM;
goto out;
}
scnprintf(target, share_len + 3, "\\\\%.*s", (int)share_len, share);
cifs_dbg(FYI, "%s: target name: %s\n", __func__, target + 2);
rc = dns_resolve_server_name_to_ip(target, &tip);
if (rc < 0)
goto out;
cifs_dbg(FYI, "%s: target ip: %s\n", __func__, tip);
if (!cifs_convert_address(&tipaddr, tip, strlen(tip))) {
cifs_dbg(VFS, "%s: failed to convert target ip address\n",
__func__);
rc = -EINVAL;
goto out;
}
*result = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr,
&tipaddr);
cifs_dbg(FYI, "%s: ip addresses match: %u\n", __func__, *result);
rc = 0;
out:
kfree(target);
kfree(tip);
return rc;
}
static void tcon_super_cb(struct super_block *sb, void *arg)
{
struct super_cb_data *sd = arg;

View file

@ -957,15 +957,15 @@ struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
sec = 2 * st->TwoSeconds;
min = st->Minutes;
if ((sec > 59) || (min > 59))
cifs_dbg(VFS, "illegal time min %d sec %lld\n", min, sec);
cifs_dbg(VFS, "Invalid time min %d sec %lld\n", min, sec);
sec += (min * 60);
sec += 60 * 60 * st->Hours;
if (st->Hours > 24)
cifs_dbg(VFS, "illegal hours %d\n", st->Hours);
cifs_dbg(VFS, "Invalid hours %d\n", st->Hours);
day = sd->Day;
month = sd->Month;
if (day < 1 || day > 31 || month < 1 || month > 12) {
cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, day);
cifs_dbg(VFS, "Invalid date, month %d day: %d\n", month, day);
day = clamp(day, 1, 31);
month = clamp(month, 1, 12);
}

View file

@ -53,7 +53,7 @@ static void dump_cifs_file_struct(struct file *file, char *label)
return;
}
if (cf->invalidHandle)
cifs_dbg(FYI, "invalid handle\n");
cifs_dbg(FYI, "Invalid handle\n");
if (cf->srch_inf.endOfSearch)
cifs_dbg(FYI, "end of search\n");
if (cf->srch_inf.emptyDir)
@ -246,7 +246,7 @@ cifs_posix_to_fattr(struct cifs_fattr *fattr, struct smb2_posix_info *info,
*/
fattr->cf_mode = le32_to_cpu(info->Mode) & ~S_IFMT;
cifs_dbg(FYI, "posix fattr: dev %d, reparse %d, mode %o",
cifs_dbg(FYI, "posix fattr: dev %d, reparse %d, mode %o\n",
le32_to_cpu(info->DeviceId),
le32_to_cpu(info->ReparseTag),
le32_to_cpu(info->Mode));
@ -478,7 +478,7 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
u32 next_offset = le32_to_cpu(pDirInfo->NextEntryOffset);
if (old_entry + next_offset < old_entry) {
cifs_dbg(VFS, "invalid offset %u\n", next_offset);
cifs_dbg(VFS, "Invalid offset %u\n", next_offset);
return NULL;
}
new_entry = old_entry + next_offset;
@ -515,7 +515,7 @@ static void cifs_fill_dirent_posix(struct cifs_dirent *de,
/* payload should have already been checked at this point */
if (posix_info_parse(info, NULL, &parsed) < 0) {
cifs_dbg(VFS, "invalid POSIX info payload");
cifs_dbg(VFS, "Invalid POSIX info payload\n");
return;
}
@ -968,7 +968,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx)
} else if (current_entry != NULL) {
cifs_dbg(FYI, "entry %lld found\n", ctx->pos);
} else {
cifs_dbg(FYI, "could not find entry\n");
cifs_dbg(FYI, "Could not find entry\n");
goto rddir2_exit;
}
cifs_dbg(FYI, "loop through %d times filling dir for net buf %p\n",

View file

@ -122,7 +122,7 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
tries++;
if (tries > 3*ses->chan_max) {
cifs_dbg(FYI, "too many attempt at opening channels (%d channels left to open)\n",
cifs_dbg(FYI, "too many channel open attempts (%d channels left to open)\n",
left);
break;
}
@ -150,6 +150,22 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
return ses->chan_count - old_chan_count;
}
/*
* If server is a channel of ses, return the corresponding enclosing
* cifs_chan otherwise return NULL.
*/
struct cifs_chan *
cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server)
{
int i;
for (i = 0; i < ses->chan_count; i++) {
if (ses->chans[i].server == server)
return &ses->chans[i];
}
return NULL;
}
int
cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
{
@ -162,12 +178,14 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
int rc;
unsigned int xid = get_xid();
cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ",
ses, iface->speed, iface->rdma_capable ? "yes" : "no");
if (iface->sockaddr.ss_family == AF_INET)
cifs_dbg(FYI, "ip:%pI4)\n", &ipv4->sin_addr);
cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI4)\n",
ses, iface->speed, iface->rdma_capable ? "yes" : "no",
&ipv4->sin_addr);
else
cifs_dbg(FYI, "ip:%pI6)\n", &ipv6->sin6_addr);
cifs_dbg(FYI, "adding channel to ses %p (speed:%zu bps rdma:%s ip:%pI4)\n",
ses, iface->speed, iface->rdma_capable ? "yes" : "no",
&ipv6->sin6_addr);
/*
* Setup a smb_vol with mostly the same info as the existing
@ -198,7 +216,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
vol.UNC = unc;
vol.prepath = "";
/* Re-use same version as master connection */
/* Reuse same version as master connection */
vol.vals = ses->server->vals;
vol.ops = ses->server->ops;
@ -229,7 +247,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
mutex_lock(&ses->session_mutex);
chan = &ses->chans[ses->chan_count];
chan = ses->binding_chan = &ses->chans[ses->chan_count];
chan->server = cifs_get_tcp_session(&vol);
if (IS_ERR(chan->server)) {
rc = PTR_ERR(chan->server);
@ -261,7 +279,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
goto out;
/* success, put it on the list
* XXX: sharing ses between 2 tcp server is not possible, the
* XXX: sharing ses between 2 tcp servers is not possible, the
* way "internal" linked lists works in linux makes element
* only able to belong to one list
*
@ -274,6 +292,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
atomic_set(&ses->chan_seq, 0);
out:
ses->binding = false;
ses->binding_chan = NULL;
mutex_unlock(&ses->session_mutex);
if (rc && chan->server)
@ -569,15 +588,15 @@ int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
if (tioffset > blob_len || tioffset + tilen > blob_len) {
cifs_dbg(VFS, "tioffset + tilen too high %u + %u",
tioffset, tilen);
cifs_dbg(VFS, "tioffset + tilen too high %u + %u\n",
tioffset, tilen);
return -EINVAL;
}
if (tilen) {
ses->auth_key.response = kmemdup(bcc_ptr + tioffset, tilen,
GFP_KERNEL);
if (!ses->auth_key.response) {
cifs_dbg(VFS, "Challenge target info alloc failure");
cifs_dbg(VFS, "Challenge target info alloc failure\n");
return -ENOMEM;
}
ses->auth_key.len = tilen;
@ -970,7 +989,7 @@ sess_auth_lanman(struct sess_data *sess_data)
/* Calculate hash with password and copy into bcc_ptr.
* Encryption Key (stored as in cryptkey) gets used if the
* security mode bit in Negottiate Protocol response states
* security mode bit in Negotiate Protocol response states
* to use challenge/response method (i.e. Password bit is 1).
*/
rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
@ -1303,9 +1322,8 @@ sess_auth_kerberos(struct sess_data *sess_data)
* sending us a response in an expected form
*/
if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
cifs_dbg(VFS,
"incorrect version of cifs.upcall (expected %d but got %d)",
CIFS_SPNEGO_UPCALL_VERSION, msg->version);
cifs_dbg(VFS, "incorrect version of cifs.upcall (expected %d but got %d)\n",
CIFS_SPNEGO_UPCALL_VERSION, msg->version);
rc = -EKEYREJECTED;
goto out_put_spnego_key;
}
@ -1313,8 +1331,8 @@ sess_auth_kerberos(struct sess_data *sess_data)
ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len,
GFP_KERNEL);
if (!ses->auth_key.response) {
cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory",
msg->sesskey_len);
cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n",
msg->sesskey_len);
rc = -ENOMEM;
goto out_put_spnego_key;
}
@ -1657,8 +1675,7 @@ static int select_sec(struct cifs_ses *ses, struct sess_data *sess_data)
type = cifs_select_sectype(ses->server, ses->sectype);
cifs_dbg(FYI, "sess setup type %d\n", type);
if (type == Unspecified) {
cifs_dbg(VFS,
"Unable to select appropriate authentication method!");
cifs_dbg(VFS, "Unable to select appropriate authentication method!\n");
return -EINVAL;
}

View file

@ -247,7 +247,7 @@ check2ndT2(char *buf)
/* check for plausible wct, bcc and t2 data and parm sizes */
/* check for parm and data offset going beyond end of smb */
if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
cifs_dbg(FYI, "invalid transact2 word count\n");
cifs_dbg(FYI, "Invalid transact2 word count\n");
return -EINVAL;
}

View file

@ -47,6 +47,18 @@ free_set_inf_compound(struct smb_rqst *rqst)
}
struct cop_vars {
struct cifs_open_parms oparms;
struct kvec rsp_iov[3];
struct smb_rqst rqst[3];
struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
struct kvec qi_iov[1];
struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
struct kvec close_iov[1];
struct smb2_file_rename_info rename_info;
struct smb2_file_link_info link_info;
};
static int
smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb, const char *full_path,
@ -54,35 +66,36 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
__u32 create_options, umode_t mode, void *ptr, int command,
struct cifsFileInfo *cfile)
{
struct cop_vars *vars = NULL;
struct kvec *rsp_iov;
struct smb_rqst *rqst;
int rc;
__le16 *utf16_path = NULL;
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
struct cifs_open_parms oparms;
struct cifs_fid fid;
struct cifs_ses *ses = tcon->ses;
struct TCP_Server_Info *server;
int num_rqst = 0;
struct smb_rqst rqst[3];
int resp_buftype[3];
struct kvec rsp_iov[3];
struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
struct kvec qi_iov[1];
struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
struct kvec close_iov[1];
struct smb2_query_info_rsp *qi_rsp = NULL;
int flags = 0;
__u8 delete_pending[8] = {1, 0, 0, 0, 0, 0, 0, 0};
unsigned int size[2];
void *data[2];
struct smb2_file_rename_info rename_info;
struct smb2_file_link_info link_info;
int len;
vars = kzalloc(sizeof(*vars), GFP_ATOMIC);
if (vars == NULL)
return -ENOMEM;
rqst = &vars->rqst[0];
rsp_iov = &vars->rsp_iov[0];
server = cifs_pick_channel(ses);
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));
/* We already have a handle so we can skip the open */
if (cfile)
@ -95,19 +108,18 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
goto finished;
}
memset(&oparms, 0, sizeof(struct cifs_open_parms));
oparms.tcon = tcon;
oparms.desired_access = desired_access;
oparms.disposition = create_disposition;
oparms.create_options = cifs_create_options(cifs_sb, create_options);
oparms.fid = &fid;
oparms.reconnect = false;
oparms.mode = mode;
vars->oparms.tcon = tcon;
vars->oparms.desired_access = desired_access;
vars->oparms.disposition = create_disposition;
vars->oparms.create_options = cifs_create_options(cifs_sb, create_options);
vars->oparms.fid = &fid;
vars->oparms.reconnect = false;
vars->oparms.mode = mode;
memset(&open_iov, 0, sizeof(open_iov));
rqst[num_rqst].rq_iov = open_iov;
rqst[num_rqst].rq_iov = &vars->open_iov[0];
rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE;
rc = SMB2_open_init(tcon, &rqst[num_rqst], &oplock, &oparms,
rc = SMB2_open_init(tcon, server,
&rqst[num_rqst], &oplock, &vars->oparms,
utf16_path);
kfree(utf16_path);
if (rc)
@ -121,12 +133,12 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
/* Operation */
switch (command) {
case SMB2_OP_QUERY_INFO:
memset(&qi_iov, 0, sizeof(qi_iov));
rqst[num_rqst].rq_iov = qi_iov;
rqst[num_rqst].rq_iov = &vars->qi_iov[0];
rqst[num_rqst].rq_nvec = 1;
if (cfile)
rc = SMB2_query_info_init(tcon, &rqst[num_rqst],
rc = SMB2_query_info_init(tcon, server,
&rqst[num_rqst],
cfile->fid.persistent_fid,
cfile->fid.volatile_fid,
FILE_ALL_INFORMATION,
@ -134,10 +146,11 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
sizeof(struct smb2_file_all_info) +
PATH_MAX * 2, 0, NULL);
else {
rc = SMB2_query_info_init(tcon, &rqst[num_rqst],
rc = SMB2_query_info_init(tcon, server,
&rqst[num_rqst],
COMPOUND_FID,
COMPOUND_FID,
FILE_ALL_INFORMATION,
FILE_ALL_INFORMATION,
SMB2_O_INFO_FILE, 0,
sizeof(struct smb2_file_all_info) +
PATH_MAX * 2, 0, NULL);
@ -164,14 +177,14 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
trace_smb3_mkdir_enter(xid, ses->Suid, tcon->tid, full_path);
break;
case SMB2_OP_RMDIR:
memset(&si_iov, 0, sizeof(si_iov));
rqst[num_rqst].rq_iov = si_iov;
rqst[num_rqst].rq_iov = &vars->si_iov[0];
rqst[num_rqst].rq_nvec = 1;
size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */
data[0] = &delete_pending[0];
rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
rc = SMB2_set_info_init(tcon, server,
&rqst[num_rqst], COMPOUND_FID,
COMPOUND_FID, current->tgid,
FILE_DISPOSITION_INFORMATION,
SMB2_O_INFO_FILE, 0, data, size);
@ -182,14 +195,14 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path);
break;
case SMB2_OP_SET_EOF:
memset(&si_iov, 0, sizeof(si_iov));
rqst[num_rqst].rq_iov = si_iov;
rqst[num_rqst].rq_iov = &vars->si_iov[0];
rqst[num_rqst].rq_nvec = 1;
size[0] = 8; /* sizeof __le64 */
data[0] = ptr;
rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
rc = SMB2_set_info_init(tcon, server,
&rqst[num_rqst], COMPOUND_FID,
COMPOUND_FID, current->tgid,
FILE_END_OF_FILE_INFORMATION,
SMB2_O_INFO_FILE, 0, data, size);
@ -200,8 +213,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path);
break;
case SMB2_OP_SET_INFO:
memset(&si_iov, 0, sizeof(si_iov));
rqst[num_rqst].rq_iov = si_iov;
rqst[num_rqst].rq_iov = &vars->si_iov[0];
rqst[num_rqst].rq_nvec = 1;
@ -209,13 +221,15 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
data[0] = ptr;
if (cfile)
rc = SMB2_set_info_init(tcon, &rqst[num_rqst],
rc = SMB2_set_info_init(tcon, server,
&rqst[num_rqst],
cfile->fid.persistent_fid,
cfile->fid.volatile_fid, current->tgid,
FILE_BASIC_INFORMATION,
SMB2_O_INFO_FILE, 0, data, size);
else {
rc = SMB2_set_info_init(tcon, &rqst[num_rqst],
rc = SMB2_set_info_init(tcon, server,
&rqst[num_rqst],
COMPOUND_FID,
COMPOUND_FID, current->tgid,
FILE_BASIC_INFORMATION,
@ -233,30 +247,31 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
full_path);
break;
case SMB2_OP_RENAME:
memset(&si_iov, 0, sizeof(si_iov));
rqst[num_rqst].rq_iov = si_iov;
rqst[num_rqst].rq_iov = &vars->si_iov[0];
rqst[num_rqst].rq_nvec = 2;
len = (2 * UniStrnlen((wchar_t *)ptr, PATH_MAX));
rename_info.ReplaceIfExists = 1;
rename_info.RootDirectory = 0;
rename_info.FileNameLength = cpu_to_le32(len);
vars->rename_info.ReplaceIfExists = 1;
vars->rename_info.RootDirectory = 0;
vars->rename_info.FileNameLength = cpu_to_le32(len);
size[0] = sizeof(struct smb2_file_rename_info);
data[0] = &rename_info;
data[0] = &vars->rename_info;
size[1] = len + 2 /* null */;
data[1] = (__le16 *)ptr;
if (cfile)
rc = SMB2_set_info_init(tcon, &rqst[num_rqst],
rc = SMB2_set_info_init(tcon, server,
&rqst[num_rqst],
cfile->fid.persistent_fid,
cfile->fid.volatile_fid,
current->tgid, FILE_RENAME_INFORMATION,
SMB2_O_INFO_FILE, 0, data, size);
else {
rc = SMB2_set_info_init(tcon, &rqst[num_rqst],
rc = SMB2_set_info_init(tcon, server,
&rqst[num_rqst],
COMPOUND_FID, COMPOUND_FID,
current->tgid, FILE_RENAME_INFORMATION,
SMB2_O_INFO_FILE, 0, data, size);
@ -271,23 +286,23 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path);
break;
case SMB2_OP_HARDLINK:
memset(&si_iov, 0, sizeof(si_iov));
rqst[num_rqst].rq_iov = si_iov;
rqst[num_rqst].rq_iov = &vars->si_iov[0];
rqst[num_rqst].rq_nvec = 2;
len = (2 * UniStrnlen((wchar_t *)ptr, PATH_MAX));
link_info.ReplaceIfExists = 0;
link_info.RootDirectory = 0;
link_info.FileNameLength = cpu_to_le32(len);
vars->link_info.ReplaceIfExists = 0;
vars->link_info.RootDirectory = 0;
vars->link_info.FileNameLength = cpu_to_le32(len);
size[0] = sizeof(struct smb2_file_link_info);
data[0] = &link_info;
data[0] = &vars->link_info;
size[1] = len + 2 /* null */;
data[1] = (__le16 *)ptr;
rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
rc = SMB2_set_info_init(tcon, server,
&rqst[num_rqst], COMPOUND_FID,
COMPOUND_FID, current->tgid,
FILE_LINK_INFORMATION,
SMB2_O_INFO_FILE, 0, data, size);
@ -308,10 +323,10 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
if (cfile)
goto after_close;
/* Close */
memset(&close_iov, 0, sizeof(close_iov));
rqst[num_rqst].rq_iov = close_iov;
rqst[num_rqst].rq_iov = &vars->close_iov[0];
rqst[num_rqst].rq_nvec = 1;
rc = SMB2_close_init(tcon, &rqst[num_rqst], COMPOUND_FID,
rc = SMB2_close_init(tcon, server,
&rqst[num_rqst], COMPOUND_FID,
COMPOUND_FID, false);
smb2_set_related(&rqst[num_rqst]);
if (rc)
@ -322,11 +337,13 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
if (cfile) {
cifsFileInfo_put(cfile);
cfile = NULL;
rc = compound_send_recv(xid, ses, flags, num_rqst - 2,
rc = compound_send_recv(xid, ses, server,
flags, num_rqst - 2,
&rqst[1], &resp_buftype[1],
&rsp_iov[1]);
} else
rc = compound_send_recv(xid, ses, flags, num_rqst,
rc = compound_send_recv(xid, ses, server,
flags, num_rqst,
rqst, resp_buftype,
rsp_iov);
@ -336,8 +353,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
SMB2_open_free(&rqst[0]);
if (rc == -EREMCHG) {
printk_once(KERN_WARNING "server share %s deleted\n",
tcon->treeName);
pr_warn_once("server share %s deleted\n", tcon->treeName);
tcon->need_reconnect = true;
}
@ -420,6 +436,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
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);
return rc;
}

View file

@ -110,14 +110,14 @@ static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len,
/* Make sure that negotiate contexts start after gss security blob */
nc_offset = le32_to_cpu(pneg_rsp->NegotiateContextOffset);
if (nc_offset < non_ctxlen) {
printk_once(KERN_WARNING "invalid negotiate context offset\n");
pr_warn_once("Invalid negotiate context offset\n");
return 0;
}
size_of_pad_before_neg_ctxts = nc_offset - non_ctxlen;
/* Verify that at least minimal negotiate contexts fit within frame */
if (len < nc_offset + (neg_count * sizeof(struct smb2_neg_context))) {
printk_once(KERN_WARNING "negotiate context goes beyond end\n");
pr_warn_once("negotiate context goes beyond end\n");
return 0;
}
@ -190,14 +190,14 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
return 1;
if (shdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
cifs_dbg(VFS, "Illegal structure size %u\n",
cifs_dbg(VFS, "Invalid structure size %u\n",
le16_to_cpu(shdr->StructureSize));
return 1;
}
command = le16_to_cpu(shdr->Command);
if (command >= NUMBER_OF_SMB2_COMMANDS) {
cifs_dbg(VFS, "Illegal SMB2 command %d\n", command);
cifs_dbg(VFS, "Invalid SMB2 command %d\n", command);
return 1;
}
@ -205,7 +205,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
if (command != SMB2_OPLOCK_BREAK_HE && (shdr->Status == 0 ||
pdu->StructureSize2 != SMB2_ERROR_STRUCTURE_SIZE2)) {
/* error packets have 9 byte structure size */
cifs_dbg(VFS, "Illegal response size %u for command %d\n",
cifs_dbg(VFS, "Invalid response size %u for command %d\n",
le16_to_cpu(pdu->StructureSize2), command);
return 1;
} else if (command == SMB2_OPLOCK_BREAK_HE
@ -213,7 +213,7 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr)
&& (le16_to_cpu(pdu->StructureSize2) != 44)
&& (le16_to_cpu(pdu->StructureSize2) != 36)) {
/* special case for SMB2.1 lease break message */
cifs_dbg(VFS, "Illegal response size %d for oplock break\n",
cifs_dbg(VFS, "Invalid response size %d for oplock break\n",
le16_to_cpu(pdu->StructureSize2));
return 1;
}
@ -864,14 +864,14 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec)
d = server->secmech.sdescsha512;
rc = crypto_shash_init(&d->shash);
if (rc) {
cifs_dbg(VFS, "%s: could not init sha512 shash\n", __func__);
cifs_dbg(VFS, "%s: Could not init sha512 shash\n", __func__);
return rc;
}
rc = crypto_shash_update(&d->shash, ses->preauth_sha_hash,
SMB2_PREAUTH_HASH_SIZE);
if (rc) {
cifs_dbg(VFS, "%s: could not update sha512 shash\n", __func__);
cifs_dbg(VFS, "%s: Could not update sha512 shash\n", __func__);
return rc;
}
@ -879,7 +879,7 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec)
rc = crypto_shash_update(&d->shash,
iov[i].iov_base, iov[i].iov_len);
if (rc) {
cifs_dbg(VFS, "%s: could not update sha512 shash\n",
cifs_dbg(VFS, "%s: Could not update sha512 shash\n",
__func__);
return rc;
}
@ -887,7 +887,7 @@ smb311_update_preauth_hash(struct cifs_ses *ses, struct kvec *iov, int nvec)
rc = crypto_shash_final(&d->shash, ses->preauth_sha_hash);
if (rc) {
cifs_dbg(VFS, "%s: could not finalize sha512 shash\n",
cifs_dbg(VFS, "%s: Could not finalize sha512 shash\n",
__func__);
return rc;
}

View file

@ -80,7 +80,7 @@ smb2_add_credits(struct TCP_Server_Info *server,
if (*val > 65000) {
*val = 65000; /* Don't get near 64K credits, avoid srv bugs */
printk_once(KERN_WARNING "server overflowed SMB3 credits\n");
pr_warn_once("server overflowed SMB3 credits\n");
}
server->in_flight--;
if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
@ -709,7 +709,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
oparms.fid = pfid;
oparms.reconnect = false;
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, &utf16_path);
rc = SMB2_open_init(tcon, server,
&rqst[0], &oplock, &oparms, &utf16_path);
if (rc)
goto oshr_free;
smb2_set_next_command(tcon, &rqst[0]);
@ -718,7 +719,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
rqst[1].rq_iov = qi_iov;
rqst[1].rq_nvec = 1;
rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID,
rc = SMB2_query_info_init(tcon, server,
&rqst[1], COMPOUND_FID,
COMPOUND_FID, FILE_ALL_INFORMATION,
SMB2_O_INFO_FILE, 0,
sizeof(struct smb2_file_all_info) +
@ -728,7 +730,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
smb2_set_related(&rqst[1]);
rc = compound_send_recv(xid, ses, flags, 2, rqst,
rc = compound_send_recv(xid, ses, server,
flags, 2, rqst,
resp_buftype, rsp_iov);
mutex_lock(&tcon->crfid.fid_mutex);
@ -768,8 +771,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
if (rc) {
if (rc == -EREMCHG) {
tcon->need_reconnect = true;
printk_once(KERN_WARNING "server share %s deleted\n",
tcon->treeName);
pr_warn_once("server share %s deleted\n",
tcon->treeName);
}
goto oshr_exit;
}
@ -1103,6 +1106,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb)
{
struct cifs_ses *ses = tcon->ses;
struct TCP_Server_Info *server = cifs_pick_channel(ses);
__le16 *utf16_path = NULL;
int ea_name_len = strlen(ea_name);
int flags = 0;
@ -1191,7 +1195,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
oparms.fid = &fid;
oparms.reconnect = false;
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path);
rc = SMB2_open_init(tcon, server,
&rqst[0], &oplock, &oparms, utf16_path);
if (rc)
goto sea_exit;
smb2_set_next_command(tcon, &rqst[0]);
@ -1217,7 +1222,8 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
size[0] = len;
data[0] = ea;
rc = SMB2_set_info_init(tcon, &rqst[1], COMPOUND_FID,
rc = SMB2_set_info_init(tcon, server,
&rqst[1], COMPOUND_FID,
COMPOUND_FID, current->tgid,
FILE_FULL_EA_INFORMATION,
SMB2_O_INFO_FILE, 0, data, size);
@ -1229,10 +1235,12 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
memset(&close_iov, 0, sizeof(close_iov));
rqst[2].rq_iov = close_iov;
rqst[2].rq_nvec = 1;
rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
rc = SMB2_close_init(tcon, server,
&rqst[2], COMPOUND_FID, COMPOUND_FID, false);
smb2_set_related(&rqst[2]);
rc = compound_send_recv(xid, ses, flags, 3, rqst,
rc = compound_send_recv(xid, ses, server,
flags, 3, rqst,
resp_buftype, rsp_iov);
/* no need to bump num_remote_opens because handle immediately closed */
@ -1453,6 +1461,16 @@ SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon,
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,
@ -1460,7 +1478,11 @@ smb2_ioctl_query_info(const unsigned int xid,
__le16 *path, int is_dir,
unsigned long p)
{
struct iqi_vars *vars;
struct smb_rqst *rqst;
struct kvec *rsp_iov;
struct cifs_ses *ses = tcon->ses;
struct TCP_Server_Info *server = cifs_pick_channel(ses);
char __user *arg = (char __user *)p;
struct smb_query_info qi;
struct smb_query_info __user *pqi;
@ -1469,45 +1491,47 @@ smb2_ioctl_query_info(const unsigned int xid,
struct smb2_query_info_rsp *qi_rsp = NULL;
struct smb2_ioctl_rsp *io_rsp = NULL;
void *buffer = NULL;
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 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];
unsigned int size[2];
void *data[2];
int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR;
memset(rqst, 0, sizeof(rqst));
vars = kzalloc(sizeof(*vars), GFP_ATOMIC);
if (vars == NULL)
return -ENOMEM;
rqst = &vars->rqst[0];
rsp_iov = &vars->rsp_iov[0];
resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
memset(rsp_iov, 0, sizeof(rsp_iov));
if (copy_from_user(&qi, arg, sizeof(struct smb_query_info)))
return -EFAULT;
goto e_fault;
if (qi.output_buffer_length > 1024)
if (qi.output_buffer_length > 1024) {
kfree(vars);
return -EINVAL;
}
if (!ses || !(ses->server))
if (!ses || !server) {
kfree(vars);
return -EIO;
}
if (smb3_encryption_required(tcon))
flags |= CIFS_TRANSFORM_REQ;
buffer = memdup_user(arg + sizeof(struct smb_query_info),
qi.output_buffer_length);
if (IS_ERR(buffer))
if (IS_ERR(buffer)) {
kfree(vars);
return PTR_ERR(buffer);
}
/* Open */
memset(&open_iov, 0, sizeof(open_iov));
rqst[0].rq_iov = open_iov;
rqst[0].rq_iov = &vars->open_iov[0];
rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
memset(&oparms, 0, sizeof(oparms));
@ -1538,7 +1562,8 @@ smb2_ioctl_query_info(const unsigned int xid,
oparms.desired_access = FILE_READ_ATTRIBUTES | READ_CONTROL;
}
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, path);
rc = SMB2_open_init(tcon, server,
&rqst[0], &oplock, &oparms, path);
if (rc)
goto iqinf_exit;
smb2_set_next_command(tcon, &rqst[0]);
@ -1549,11 +1574,11 @@ smb2_ioctl_query_info(const unsigned int xid,
if (!capable(CAP_SYS_ADMIN))
rc = -EPERM;
else {
memset(&io_iov, 0, sizeof(io_iov));
rqst[1].rq_iov = io_iov;
rqst[1].rq_iov = &vars->io_iov[0];
rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
rc = SMB2_ioctl_init(tcon, &rqst[1],
rc = SMB2_ioctl_init(tcon, server,
&rqst[1],
COMPOUND_FID, COMPOUND_FID,
qi.info_type, true, buffer,
qi.output_buffer_length,
@ -1566,31 +1591,32 @@ smb2_ioctl_query_info(const unsigned int xid,
if (!capable(CAP_SYS_ADMIN))
rc = -EPERM;
else {
memset(&si_iov, 0, sizeof(si_iov));
rqst[1].rq_iov = si_iov;
rqst[1].rq_iov = &vars->si_iov[0];
rqst[1].rq_nvec = 1;
size[0] = 8;
data[0] = buffer;
rc = SMB2_set_info_init(tcon, &rqst[1],
rc = SMB2_set_info_init(tcon, server,
&rqst[1],
COMPOUND_FID, COMPOUND_FID,
current->tgid,
FILE_END_OF_FILE_INFORMATION,
SMB2_O_INFO_FILE, 0, data, size);
}
} else if (qi.flags == PASSTHRU_QUERY_INFO) {
memset(&qi_iov, 0, sizeof(qi_iov));
rqst[1].rq_iov = qi_iov;
rqst[1].rq_iov = &vars->qi_iov[0];
rqst[1].rq_nvec = 1;
rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID,
rc = SMB2_query_info_init(tcon, server,
&rqst[1], COMPOUND_FID,
COMPOUND_FID, qi.file_info_class,
qi.info_type, qi.additional_information,
qi.input_buffer_length,
qi.output_buffer_length, buffer);
} else { /* unknown flags */
cifs_tcon_dbg(VFS, "invalid passthru query flags: 0x%x\n", qi.flags);
cifs_tcon_dbg(VFS, "Invalid passthru query flags: 0x%x\n",
qi.flags);
rc = -EINVAL;
}
@ -1600,16 +1626,17 @@ smb2_ioctl_query_info(const unsigned int xid,
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[0];
rqst[2].rq_nvec = 1;
rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
rc = SMB2_close_init(tcon, server,
&rqst[2], COMPOUND_FID, COMPOUND_FID, false);
if (rc)
goto iqinf_exit;
smb2_set_related(&rqst[2]);
rc = compound_send_recv(xid, ses, flags, 3, rqst,
rc = compound_send_recv(xid, ses, server,
flags, 3, rqst,
resp_buftype, rsp_iov);
if (rc)
goto iqinf_exit;
@ -1650,6 +1677,7 @@ smb2_ioctl_query_info(const unsigned int xid,
}
iqinf_exit:
kfree(vars);
kfree(buffer);
SMB2_open_free(&rqst[0]);
if (qi.flags & PASSTHRU_FSCTL)
@ -1720,7 +1748,7 @@ smb2_copychunk_range(const unsigned int xid,
if (rc == 0) {
if (ret_data_len !=
sizeof(struct copychunk_ioctl_rsp)) {
cifs_tcon_dbg(VFS, "invalid cchunk response size\n");
cifs_tcon_dbg(VFS, "Invalid cchunk response size\n");
rc = -EIO;
goto cchunk_out;
}
@ -1734,12 +1762,12 @@ smb2_copychunk_range(const unsigned int xid,
*/
if (le32_to_cpu(retbuf->TotalBytesWritten) >
le32_to_cpu(pcchunk->Length)) {
cifs_tcon_dbg(VFS, "invalid copy chunk response\n");
cifs_tcon_dbg(VFS, "Invalid copy chunk response\n");
rc = -EIO;
goto cchunk_out;
}
if (le32_to_cpu(retbuf->ChunksWritten) != 1) {
cifs_tcon_dbg(VFS, "invalid num chunks written\n");
cifs_tcon_dbg(VFS, "Invalid num chunks written\n");
rc = -EIO;
goto cchunk_out;
}
@ -2160,6 +2188,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_open_parms oparms;
struct smb2_query_directory_rsp *qd_rsp = NULL;
struct smb2_create_rsp *op_rsp = NULL;
struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
if (!utf16_path)
@ -2184,7 +2213,8 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
oparms.fid = fid;
oparms.reconnect = false;
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path);
rc = SMB2_open_init(tcon, server,
&rqst[0], &oplock, &oparms, utf16_path);
if (rc)
goto qdf_free;
smb2_set_next_command(tcon, &rqst[0]);
@ -2197,7 +2227,8 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
rqst[1].rq_iov = qd_iov;
rqst[1].rq_nvec = SMB2_QUERY_DIRECTORY_IOV_SIZE;
rc = SMB2_query_directory_init(xid, tcon, &rqst[1],
rc = SMB2_query_directory_init(xid, tcon, server,
&rqst[1],
COMPOUND_FID, COMPOUND_FID,
0, srch_inf->info_level);
if (rc)
@ -2205,7 +2236,8 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
smb2_set_related(&rqst[1]);
rc = compound_send_recv(xid, tcon->ses, flags, 2, rqst,
rc = compound_send_recv(xid, tcon->ses, server,
flags, 2, rqst,
resp_buftype, rsp_iov);
/* If the open failed there is nothing to do */
@ -2410,6 +2442,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb)
{
struct cifs_ses *ses = tcon->ses;
struct TCP_Server_Info *server = cifs_pick_channel(ses);
int flags = 0;
struct smb_rqst rqst[3];
int resp_buftype[3];
@ -2440,7 +2473,8 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
oparms.fid = &fid;
oparms.reconnect = false;
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path);
rc = SMB2_open_init(tcon, server,
&rqst[0], &oplock, &oparms, utf16_path);
if (rc)
goto qic_exit;
smb2_set_next_command(tcon, &rqst[0]);
@ -2449,7 +2483,8 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
rqst[1].rq_iov = qi_iov;
rqst[1].rq_nvec = 1;
rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID, COMPOUND_FID,
rc = SMB2_query_info_init(tcon, server,
&rqst[1], COMPOUND_FID, COMPOUND_FID,
class, type, 0,
output_len, 0,
NULL);
@ -2462,19 +2497,21 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
rqst[2].rq_iov = close_iov;
rqst[2].rq_nvec = 1;
rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
rc = SMB2_close_init(tcon, server,
&rqst[2], COMPOUND_FID, COMPOUND_FID, false);
if (rc)
goto qic_exit;
smb2_set_related(&rqst[2]);
rc = compound_send_recv(xid, ses, flags, 3, rqst,
rc = compound_send_recv(xid, ses, server,
flags, 3, rqst,
resp_buftype, rsp_iov);
if (rc) {
free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
if (rc == -EREMCHG) {
tcon->need_reconnect = true;
printk_once(KERN_WARNING "server share %s deleted\n",
tcon->treeName);
pr_warn_once("server share %s deleted\n",
tcon->treeName);
}
goto qic_exit;
}
@ -2754,15 +2791,15 @@ parse_reparse_point(struct reparse_data_buffer *buf,
struct cifs_sb_info *cifs_sb)
{
if (plen < sizeof(struct reparse_data_buffer)) {
cifs_dbg(VFS, "reparse buffer is too small. Must be "
"at least 8 bytes but was %d\n", plen);
cifs_dbg(VFS, "reparse buffer is too small. Must be at least 8 bytes but was %d\n",
plen);
return -EIO;
}
if (plen < le16_to_cpu(buf->ReparseDataLength) +
sizeof(struct reparse_data_buffer)) {
cifs_dbg(VFS, "srv returned invalid reparse buf "
"length: %d\n", plen);
cifs_dbg(VFS, "srv returned invalid reparse buf length: %d\n",
plen);
return -EIO;
}
@ -2777,8 +2814,8 @@ parse_reparse_point(struct reparse_data_buffer *buf,
(struct reparse_symlink_data_buffer *)buf,
plen, target_path, cifs_sb);
default:
cifs_dbg(VFS, "srv returned unknown symlink buffer "
"tag:0x%08x\n", le32_to_cpu(buf->ReparseTag));
cifs_dbg(VFS, "srv returned unknown symlink buffer tag:0x%08x\n",
le32_to_cpu(buf->ReparseTag));
return -EOPNOTSUPP;
}
}
@ -2799,6 +2836,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
struct kvec err_iov = {NULL, 0};
struct smb2_err_rsp *err_buf = NULL;
struct smb2_symlink_err_rsp *symlink;
struct TCP_Server_Info *server = cifs_pick_channel(tcon->ses);
unsigned int sub_len;
unsigned int sub_offset;
unsigned int print_len;
@ -2844,7 +2882,8 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
oparms.fid = &fid;
oparms.reconnect = false;
rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, utf16_path);
rc = SMB2_open_init(tcon, server,
&rqst[0], &oplock, &oparms, utf16_path);
if (rc)
goto querty_exit;
smb2_set_next_command(tcon, &rqst[0]);
@ -2855,7 +2894,8 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
rqst[1].rq_iov = io_iov;
rqst[1].rq_nvec = SMB2_IOCTL_IOV_SIZE;
rc = SMB2_ioctl_init(tcon, &rqst[1], fid.persistent_fid,
rc = SMB2_ioctl_init(tcon, server,
&rqst[1], fid.persistent_fid,
fid.volatile_fid, FSCTL_GET_REPARSE_POINT,
true /* is_fctl */, NULL, 0,
CIFSMaxBufSize -
@ -2873,13 +2913,15 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
rqst[2].rq_iov = close_iov;
rqst[2].rq_nvec = 1;
rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID, false);
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, flags, 3, rqst,
rc = compound_send_recv(xid, tcon->ses, server,
flags, 3, rqst,
resp_buftype, rsp_iov);
create_rsp = rsp_iov[0].iov_base;
@ -4573,7 +4615,7 @@ smb2_make_node(unsigned int xid, struct inode *inode,
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
int rc = -EPERM;
FILE_ALL_INFO *buf = NULL;
struct cifs_io_parms io_parms;
struct cifs_io_parms io_parms = {0};
__u32 oplock = 0;
struct cifs_fid fid;
struct cifs_open_parms oparms;

File diff suppressed because it is too large Load diff

View file

@ -143,8 +143,17 @@ struct smb2_transform_hdr {
__u64 SessionId;
} __packed;
/* See MS-SMB2 2.2.42 */
struct smb2_compression_transform_hdr {
__le32 ProtocolId; /* 0xFC 'S' 'M' 'B' */
__le32 OriginalCompressedSegmentSize;
__le16 CompressionAlgorithm;
__le16 Flags;
__le16 Length; /* if chained it is length, else offset */
} __packed;
/* See MS-SMB2 2.2.42.1 */
struct compression_playload_header {
struct compression_payload_header {
__le16 AlgorithmId;
__le16 Reserved;
__le32 Length;
@ -333,7 +342,7 @@ struct smb2_encryption_neg_context {
#define SMB3_COMPRESS_LZ77 cpu_to_le16(0x0002)
#define SMB3_COMPRESS_LZ77_HUFF cpu_to_le16(0x0003)
/* Pattern scanning algorithm See MS-SMB2 3.1.4.4.1 */
#define SMB3_COMPRESS_PATTERN cpu_to_le16(0x0004)
#define SMB3_COMPRESS_PATTERN cpu_to_le16(0x0004) /* Pattern_V1 */
/* Compression Flags */
#define SMB2_COMPRESSION_CAPABILITIES_FLAG_NONE cpu_to_le32(0x00000000)

View file

@ -143,7 +143,9 @@ extern int SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms,
struct smb2_file_all_info *buf,
struct create_posix_rsp *posix,
struct kvec *err_iov, int *resp_buftype);
extern int SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
extern int SMB2_open_init(struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
struct smb_rqst *rqst,
__u8 *oplock, struct cifs_open_parms *oparms,
__le16 *path);
extern void SMB2_open_free(struct smb_rqst *rqst);
@ -151,7 +153,9 @@ extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, u32 opcode,
bool is_fsctl, char *in_data, u32 indatalen, u32 maxoutlen,
char **out_data, u32 *plen /* returned data len */);
extern int SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
extern int SMB2_ioctl_init(struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid, u32 opcode,
bool is_fsctl, char *in_data, u32 indatalen,
__u32 max_response_size);
@ -165,19 +169,25 @@ extern int __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
struct smb2_file_network_open_info *pbuf);
extern int SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_file_id, u64 volatile_file_id);
extern int SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid, bool query_attrs);
extern int SMB2_close_init(struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid,
bool query_attrs);
extern void SMB2_close_free(struct smb_rqst *rqst);
extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_file_id, u64 volatile_file_id);
extern int SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst,
struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
u64 persistent_file_id, u64 volatile_file_id);
extern void SMB2_flush_free(struct smb_rqst *rqst);
extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_file_id, u64 volatile_file_id,
struct smb2_file_all_info *data);
extern int SMB2_query_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
extern int SMB2_query_info_init(struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid,
u8 info_class, u8 info_type,
u32 additional_info, size_t output_len,
@ -201,6 +211,7 @@ extern int 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);
extern int SMB2_query_directory_init(unsigned int xid, struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid,
int index, int info_level);
@ -208,7 +219,9 @@ extern void SMB2_query_directory_free(struct smb_rqst *rqst);
extern int SMB2_set_eof(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid, u32 pid,
__le64 *eof);
extern int SMB2_set_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst,
extern int SMB2_set_info_init(struct cifs_tcon *tcon,
struct TCP_Server_Info *server,
struct smb_rqst *rqst,
u64 persistent_fid, u64 volatile_fid, u32 pid,
u8 info_class, u8 info_type, u32 additional_info,
void **data, unsigned int *size);

View file

@ -294,15 +294,12 @@ static void send_done(struct ib_cq *cq, struct ib_wc *wc)
static void dump_smbd_negotiate_resp(struct smbd_negotiate_resp *resp)
{
log_rdma_event(INFO, "resp message min_version %u max_version %u "
"negotiated_version %u credits_requested %u "
"credits_granted %u status %u max_readwrite_size %u "
"preferred_send_size %u max_receive_size %u "
"max_fragmented_size %u\n",
resp->min_version, resp->max_version, resp->negotiated_version,
resp->credits_requested, resp->credits_granted, resp->status,
resp->max_readwrite_size, resp->preferred_send_size,
resp->max_receive_size, resp->max_fragmented_size);
log_rdma_event(INFO, "resp message min_version %u max_version %u negotiated_version %u credits_requested %u credits_granted %u status %u max_readwrite_size %u preferred_send_size %u max_receive_size %u max_fragmented_size %u\n",
resp->min_version, resp->max_version,
resp->negotiated_version, resp->credits_requested,
resp->credits_granted, resp->status,
resp->max_readwrite_size, resp->preferred_send_size,
resp->max_receive_size, resp->max_fragmented_size);
}
/*
@ -450,10 +447,9 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
struct smbd_connection *info = response->info;
int data_length = 0;
log_rdma_recv(INFO, "response=%p type=%d wc status=%d wc opcode %d "
"byte_len=%d pkey_index=%x\n",
response, response->type, wc->status, wc->opcode,
wc->byte_len, wc->pkey_index);
log_rdma_recv(INFO, "response=%p type=%d wc status=%d wc opcode %d byte_len=%d pkey_index=%x\n",
response, response->type, wc->status, wc->opcode,
wc->byte_len, wc->pkey_index);
if (wc->status != IB_WC_SUCCESS || wc->opcode != IB_WC_RECV) {
log_rdma_recv(INFO, "wc->status=%d opcode=%d\n",
@ -519,12 +515,11 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc)
wake_up_interruptible(&info->wait_send_queue);
}
log_incoming(INFO, "data flags %d data_offset %d "
"data_length %d remaining_data_length %d\n",
le16_to_cpu(data_transfer->flags),
le32_to_cpu(data_transfer->data_offset),
le32_to_cpu(data_transfer->data_length),
le32_to_cpu(data_transfer->remaining_data_length));
log_incoming(INFO, "data flags %d data_offset %d data_length %d remaining_data_length %d\n",
le16_to_cpu(data_transfer->flags),
le32_to_cpu(data_transfer->data_offset),
le32_to_cpu(data_transfer->data_length),
le32_to_cpu(data_transfer->remaining_data_length));
/* Send a KEEP_ALIVE response right away if requested */
info->keep_alive_requested = KEEP_ALIVE_NONE;
@ -632,14 +627,10 @@ static int smbd_ia_open(
}
if (!frwr_is_supported(&info->id->device->attrs)) {
log_rdma_event(ERR,
"Fast Registration Work Requests "
"(FRWR) is not supported\n");
log_rdma_event(ERR,
"Device capability flags = %llx "
"max_fast_reg_page_list_len = %u\n",
info->id->device->attrs.device_cap_flags,
info->id->device->attrs.max_fast_reg_page_list_len);
log_rdma_event(ERR, "Fast Registration Work Requests (FRWR) is not supported\n");
log_rdma_event(ERR, "Device capability flags = %llx max_fast_reg_page_list_len = %u\n",
info->id->device->attrs.device_cap_flags,
info->id->device->attrs.max_fast_reg_page_list_len);
rc = -EPROTONOSUPPORT;
goto out2;
}
@ -898,13 +889,12 @@ static int smbd_post_send_sgl(struct smbd_connection *info,
packet->remaining_data_length = cpu_to_le32(remaining_data_length);
packet->padding = 0;
log_outgoing(INFO, "credits_requested=%d credits_granted=%d "
"data_offset=%d data_length=%d remaining_data_length=%d\n",
le16_to_cpu(packet->credits_requested),
le16_to_cpu(packet->credits_granted),
le32_to_cpu(packet->data_offset),
le32_to_cpu(packet->data_length),
le32_to_cpu(packet->remaining_data_length));
log_outgoing(INFO, "credits_requested=%d credits_granted=%d data_offset=%d data_length=%d remaining_data_length=%d\n",
le16_to_cpu(packet->credits_requested),
le16_to_cpu(packet->credits_granted),
le32_to_cpu(packet->data_offset),
le32_to_cpu(packet->data_length),
le32_to_cpu(packet->remaining_data_length));
/* Map the packet to DMA */
header_length = sizeof(struct smbd_data_transfer);
@ -1078,11 +1068,9 @@ static int smbd_negotiate(struct smbd_connection *info)
response->type = SMBD_NEGOTIATE_RESP;
rc = smbd_post_recv(info, response);
log_rdma_event(INFO,
"smbd_post_recv rc=%d iov.addr=%llx iov.length=%x "
"iov.lkey=%x\n",
rc, response->sge.addr,
response->sge.length, response->sge.lkey);
log_rdma_event(INFO, "smbd_post_recv rc=%d iov.addr=%llx iov.length=%x iov.lkey=%x\n",
rc, response->sge.addr,
response->sge.length, response->sge.lkey);
if (rc)
return rc;
@ -1540,25 +1528,19 @@ static struct smbd_connection *_smbd_get_connection(
if (smbd_send_credit_target > info->id->device->attrs.max_cqe ||
smbd_send_credit_target > info->id->device->attrs.max_qp_wr) {
log_rdma_event(ERR,
"consider lowering send_credit_target = %d. "
"Possible CQE overrun, device "
"reporting max_cpe %d max_qp_wr %d\n",
smbd_send_credit_target,
info->id->device->attrs.max_cqe,
info->id->device->attrs.max_qp_wr);
log_rdma_event(ERR, "consider lowering send_credit_target = %d. Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n",
smbd_send_credit_target,
info->id->device->attrs.max_cqe,
info->id->device->attrs.max_qp_wr);
goto config_failed;
}
if (smbd_receive_credit_max > info->id->device->attrs.max_cqe ||
smbd_receive_credit_max > info->id->device->attrs.max_qp_wr) {
log_rdma_event(ERR,
"consider lowering receive_credit_max = %d. "
"Possible CQE overrun, device "
"reporting max_cpe %d max_qp_wr %d\n",
smbd_receive_credit_max,
info->id->device->attrs.max_cqe,
info->id->device->attrs.max_qp_wr);
log_rdma_event(ERR, "consider lowering receive_credit_max = %d. Possible CQE overrun, device reporting max_cpe %d max_qp_wr %d\n",
smbd_receive_credit_max,
info->id->device->attrs.max_cqe,
info->id->device->attrs.max_qp_wr);
goto config_failed;
}
@ -1865,11 +1847,9 @@ static int smbd_recv_buf(struct smbd_connection *info, char *buf,
to_read -= to_copy;
data_read += to_copy;
log_read(INFO, "_get_first_reassembly memcpy %d bytes "
"data_transfer_length-offset=%d after that "
"to_read=%d data_read=%d offset=%d\n",
to_copy, data_length - offset,
to_read, data_read, offset);
log_read(INFO, "_get_first_reassembly memcpy %d bytes data_transfer_length-offset=%d after that to_read=%d data_read=%d offset=%d\n",
to_copy, data_length - offset,
to_read, data_read, offset);
}
spin_lock_irq(&info->reassembly_queue_lock);
@ -1878,10 +1858,9 @@ static int smbd_recv_buf(struct smbd_connection *info, char *buf,
spin_unlock_irq(&info->reassembly_queue_lock);
info->first_entry_offset = offset;
log_read(INFO, "returning to thread data_read=%d "
"reassembly_data_length=%d first_entry_offset=%d\n",
data_read, info->reassembly_data_length,
info->first_entry_offset);
log_read(INFO, "returning to thread data_read=%d reassembly_data_length=%d first_entry_offset=%d\n",
data_read, info->reassembly_data_length,
info->first_entry_offset);
read_rfc1002_done:
return data_read;
}
@ -1952,7 +1931,7 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
if (iov_iter_rw(&msg->msg_iter) == WRITE) {
/* It's a bug in upper layer to get there */
cifs_dbg(VFS, "CIFS: invalid msg iter dir %u\n",
cifs_dbg(VFS, "Invalid msg iter dir %u\n",
iov_iter_rw(&msg->msg_iter));
rc = -EINVAL;
goto out;
@ -1974,7 +1953,7 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)
default:
/* It's a bug in upper layer to get there */
cifs_dbg(VFS, "CIFS: invalid msg type %d\n",
cifs_dbg(VFS, "Invalid msg type %d\n",
iov_iter_type(&msg->msg_iter));
rc = -EINVAL;
}
@ -2043,10 +2022,9 @@ int smbd_send(struct TCP_Server_Info *server,
dump_smb(iov[i].iov_base, iov[i].iov_len);
log_write(INFO, "rqst_idx=%d nvec=%d rqst->rq_npages=%d rq_pagesz=%d "
"rq_tailsz=%d buflen=%lu\n",
rqst_idx, rqst->rq_nvec, rqst->rq_npages, rqst->rq_pagesz,
rqst->rq_tailsz, smb_rqst_len(server, rqst));
log_write(INFO, "rqst_idx=%d nvec=%d rqst->rq_npages=%d rq_pagesz=%d rq_tailsz=%d buflen=%lu\n",
rqst_idx, rqst->rq_nvec, rqst->rq_npages, rqst->rq_pagesz,
rqst->rq_tailsz, smb_rqst_len(server, rqst));
start = i = 0;
buflen = 0;
@ -2056,11 +2034,9 @@ int smbd_send(struct TCP_Server_Info *server,
if (i > start) {
remaining_data_length -=
(buflen-iov[i].iov_len);
log_write(INFO, "sending iov[] from start=%d "
"i=%d nvecs=%d "
"remaining_data_length=%d\n",
start, i, i-start,
remaining_data_length);
log_write(INFO, "sending iov[] from start=%d i=%d nvecs=%d remaining_data_length=%d\n",
start, i, i - start,
remaining_data_length);
rc = smbd_post_send_data(
info, &iov[start], i-start,
remaining_data_length);
@ -2069,10 +2045,9 @@ int smbd_send(struct TCP_Server_Info *server,
} else {
/* iov[start] is too big, break it */
nvecs = (buflen+max_iov_size-1)/max_iov_size;
log_write(INFO, "iov[%d] iov_base=%p buflen=%d"
" break to %d vectors\n",
start, iov[start].iov_base,
buflen, nvecs);
log_write(INFO, "iov[%d] iov_base=%p buflen=%d break to %d vectors\n",
start, iov[start].iov_base,
buflen, nvecs);
for (j = 0; j < nvecs; j++) {
vec.iov_base =
(char *)iov[start].iov_base +
@ -2084,11 +2059,9 @@ int smbd_send(struct TCP_Server_Info *server,
max_iov_size*(nvecs-1);
remaining_data_length -= vec.iov_len;
log_write(INFO,
"sending vec j=%d iov_base=%p"
" iov_len=%zu "
"remaining_data_length=%d\n",
j, vec.iov_base, vec.iov_len,
remaining_data_length);
"sending vec j=%d iov_base=%p iov_len=%zu remaining_data_length=%d\n",
j, vec.iov_base, vec.iov_len,
remaining_data_length);
rc = smbd_post_send_data(
info, &vec, 1,
remaining_data_length);
@ -2106,11 +2079,9 @@ int smbd_send(struct TCP_Server_Info *server,
if (i == rqst->rq_nvec) {
/* send out all remaining vecs */
remaining_data_length -= buflen;
log_write(INFO,
"sending iov[] from start=%d i=%d "
"nvecs=%d remaining_data_length=%d\n",
start, i, i-start,
remaining_data_length);
log_write(INFO, "sending iov[] from start=%d i=%d nvecs=%d remaining_data_length=%d\n",
start, i, i - start,
remaining_data_length);
rc = smbd_post_send_data(info, &iov[start],
i-start, remaining_data_length);
if (rc)
@ -2134,10 +2105,9 @@ int smbd_send(struct TCP_Server_Info *server,
if (j == nvecs-1)
size = buflen - j*max_iov_size;
remaining_data_length -= size;
log_write(INFO, "sending pages i=%d offset=%d size=%d"
" remaining_data_length=%d\n",
i, j*max_iov_size+offset, size,
remaining_data_length);
log_write(INFO, "sending pages i=%d offset=%d size=%d remaining_data_length=%d\n",
i, j * max_iov_size + offset, size,
remaining_data_length);
rc = smbd_post_send_page(
info, rqst->rq_pages[i],
j*max_iov_size + offset,
@ -2211,11 +2181,9 @@ static void smbd_mr_recovery_work(struct work_struct *work)
info->pd, info->mr_type,
info->max_frmr_depth);
if (IS_ERR(smbdirect_mr->mr)) {
log_rdma_mr(ERR,
"ib_alloc_mr failed mr_type=%x "
"max_frmr_depth=%x\n",
info->mr_type,
info->max_frmr_depth);
log_rdma_mr(ERR, "ib_alloc_mr failed mr_type=%x max_frmr_depth=%x\n",
info->mr_type,
info->max_frmr_depth);
smbd_disconnect_rdma_connection(info);
continue;
}
@ -2278,9 +2246,8 @@ static int allocate_mr_list(struct smbd_connection *info)
smbdirect_mr->mr = ib_alloc_mr(info->pd, info->mr_type,
info->max_frmr_depth);
if (IS_ERR(smbdirect_mr->mr)) {
log_rdma_mr(ERR, "ib_alloc_mr failed mr_type=%x "
"max_frmr_depth=%x\n",
info->mr_type, info->max_frmr_depth);
log_rdma_mr(ERR, "ib_alloc_mr failed mr_type=%x max_frmr_depth=%x\n",
info->mr_type, info->max_frmr_depth);
goto out;
}
smbdirect_mr->sgl = kcalloc(

View file

@ -112,7 +112,7 @@ static void _cifs_mid_q_entry_release(struct kref *refcount)
#ifdef CONFIG_CIFS_STATS2
now = jiffies;
if (now < midEntry->when_alloc)
cifs_server_dbg(VFS, "invalid mid allocation time\n");
cifs_server_dbg(VFS, "Invalid mid allocation time\n");
roundtrip_time = now - midEntry->when_alloc;
if (smb_cmd < NUMBER_OF_SMB2_COMMANDS) {
@ -151,12 +151,12 @@ static void _cifs_mid_q_entry_release(struct kref *refcount)
trace_smb3_slow_rsp(smb_cmd, midEntry->mid, midEntry->pid,
midEntry->when_sent, midEntry->when_received);
if (cifsFYI & CIFS_TIMER) {
pr_debug(" CIFS slow rsp: cmd %d mid %llu",
midEntry->command, midEntry->mid);
cifs_info(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
now - midEntry->when_alloc,
now - midEntry->when_sent,
now - midEntry->when_received);
pr_debug("slow rsp: cmd %d mid %llu",
midEntry->command, midEntry->mid);
cifs_info("A: 0x%lx S: 0x%lx R: 0x%lx\n",
now - midEntry->when_alloc,
now - midEntry->when_sent,
now - midEntry->when_received);
}
}
#endif
@ -473,8 +473,7 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
return -ENOMEM;
if (!server->ops->init_transform_rq) {
cifs_server_dbg(VFS, "Encryption requested but transform "
"callback is missing\n");
cifs_server_dbg(VFS, "Encryption requested but transform callback is missing\n");
return -EIO;
}
@ -989,8 +988,35 @@ cifs_cancelled_callback(struct mid_q_entry *mid)
DeleteMidQEntry(mid);
}
/*
* Return a channel (master if none) of @ses that can be used to send
* regular requests.
*
* If we are currently binding a new channel (negprot/sess.setup),
* return the new incomplete channel.
*/
struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses)
{
uint index = 0;
if (!ses)
return NULL;
if (!ses->binding) {
/* round robin */
if (ses->chan_count > 1) {
index = (uint)atomic_inc_return(&ses->chan_seq);
index %= ses->chan_count;
}
return ses->chans[index].server;
} else {
return cifs_ses_server(ses);
}
}
int
compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
struct TCP_Server_Info *server,
const int flags, const int num_rqst, struct smb_rqst *rqst,
int *resp_buf_type, struct kvec *resp_iov)
{
@ -1002,30 +1028,17 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
};
unsigned int instance;
char *buf;
struct TCP_Server_Info *server;
optype = flags & CIFS_OP_MASK;
for (i = 0; i < num_rqst; i++)
resp_buf_type[i] = CIFS_NO_BUFFER; /* no response buf yet */
if ((ses == NULL) || (ses->server == NULL)) {
if (!ses || !ses->server || !server) {
cifs_dbg(VFS, "Null session\n");
return -EIO;
}
if (!ses->binding) {
uint index = 0;
if (ses->chan_count > 1) {
index = (uint)atomic_inc_return(&ses->chan_seq);
index %= ses->chan_count;
}
server = ses->chans[index].server;
} else {
server = cifs_ses_server(ses);
}
if (server->tcpStatus == CifsExiting)
return -ENOENT;
@ -1220,11 +1233,12 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses,
int
cifs_send_recv(const unsigned int xid, struct cifs_ses *ses,
struct TCP_Server_Info *server,
struct smb_rqst *rqst, int *resp_buf_type, const int flags,
struct kvec *resp_iov)
{
return compound_send_recv(xid, ses, flags, 1, rqst, resp_buf_type,
resp_iov);
return compound_send_recv(xid, ses, server, flags, 1,
rqst, resp_buf_type, resp_iov);
}
int
@ -1259,7 +1273,8 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
rqst.rq_iov = new_iov;
rqst.rq_nvec = n_vec + 1;
rc = cifs_send_recv(xid, ses, &rqst, resp_buf_type, flags, resp_iov);
rc = cifs_send_recv(xid, ses, ses->server,
&rqst, resp_buf_type, flags, resp_iov);
if (n_vec + 1 > CIFS_MAX_IOV_SIZE)
kfree(new_iov);
return rc;
@ -1296,8 +1311,8 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
use ses->maxReq */
if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
cifs_server_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
len);
cifs_server_dbg(VFS, "Invalid length, greater than maximum frame, %d\n",
len);
return -EIO;
}
@ -1437,8 +1452,8 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
use ses->maxReq */
if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
cifs_tcon_dbg(VFS, "Illegal length, greater than maximum frame, %d\n",
len);
cifs_tcon_dbg(VFS, "Invalid length, greater than maximum frame, %d\n",
len);
return -EIO;
}