six smb3 client fixes
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAmalhJwACgkQiiy9cAdy T1GbRgv+NPJ07ZtG7D4EosxCHiBETQS9oezS1Ulbv78YdEBHfP/9T+pYcCh+3qZC Sa2HQlB1y3lLZNrhYQrVtyECtVcsdeUloXf6IIczBMAtCeS7FZ0+U8B07+9vJHGz 9p0paXOkRbOQ2JtYevsRN41Q0HxjvWqHSet/Y2tM8cj0M3yjCPHvJCFv3OC9ZUTV AyZZdYFoDFIYmW75459wq/80IADXhkSIsH/8IStTpshVhJbVdyGpr8FTrtW7G0m7 prYKEzXtgdvzM1CVlfR9boyf5HqUDvcHuV0ZBFjBOx7A3kXiShdRh7PFmDaY1vqX o3qgmmjTntX9aRR3zL9GYuayGD8XsXFPotWbuGniKLraX5WJNXe3o8OKybXgivoY OEXnkmlyp4GcggmWZpPCqq7J5J+YcLQImCKXxfQI7HjToI9cy7aNZ6qh9g0LIQBm 9totZcp5AMGk9Sbdf+MUeJ3cx8+3o26kc8a5MCV6fCPt/x7XNKG33ZRd5lne6rxr WX4neGG4 =nzTc -----END PGP SIGNATURE----- Merge tag '6.11-rc-smb-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6 Pull more smb client updates from Steve French: - fix for potential null pointer use in init cifs - additional dynamic trace points to improve debugging of some common scenarios - two SMB1 fixes (one addressing reconnect with POSIX extensions, one a mount parsing error) * tag '6.11-rc-smb-client-fixes-part2' of git://git.samba.org/sfrench/cifs-2.6: smb3: add dynamic trace point for session setup key expired failures smb3: add four dynamic tracepoints for copy_file_range and reflink smb3: add dynamic tracepoint for reflink errors cifs: mount with "unix" mount option for SMB1 incorrectly handled cifs: fix reconnect with SMB1 UNIX Extensions cifs: fix potential null pointer use in destroy_workqueue in init_cifs error path
This commit is contained in:
commit
5437f30d34
@ -1894,12 +1894,12 @@ init_cifs(void)
|
||||
WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
|
||||
if (!serverclose_wq) {
|
||||
rc = -ENOMEM;
|
||||
goto out_destroy_serverclose_wq;
|
||||
goto out_destroy_deferredclose_wq;
|
||||
}
|
||||
|
||||
rc = cifs_init_inodecache();
|
||||
if (rc)
|
||||
goto out_destroy_deferredclose_wq;
|
||||
goto out_destroy_serverclose_wq;
|
||||
|
||||
rc = cifs_init_netfs();
|
||||
if (rc)
|
||||
@ -1967,6 +1967,8 @@ out_destroy_netfs:
|
||||
cifs_destroy_netfs();
|
||||
out_destroy_inodecache:
|
||||
cifs_destroy_inodecache();
|
||||
out_destroy_serverclose_wq:
|
||||
destroy_workqueue(serverclose_wq);
|
||||
out_destroy_deferredclose_wq:
|
||||
destroy_workqueue(deferredclose_wq);
|
||||
out_destroy_cifsoplockd_wq:
|
||||
@ -1977,8 +1979,6 @@ out_destroy_decrypt_wq:
|
||||
destroy_workqueue(decrypt_wq);
|
||||
out_destroy_cifsiod_wq:
|
||||
destroy_workqueue(cifsiod_wq);
|
||||
out_destroy_serverclose_wq:
|
||||
destroy_workqueue(serverclose_wq);
|
||||
out_clean_proc:
|
||||
cifs_proc_clean();
|
||||
return rc;
|
||||
|
@ -2614,6 +2614,13 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
|
||||
cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions\n");
|
||||
rc = -EOPNOTSUPP;
|
||||
goto out_fail;
|
||||
} else if (ses->server->vals->protocol_id == SMB10_PROT_ID)
|
||||
if (cap_unix(ses))
|
||||
cifs_dbg(FYI, "Unix Extensions requested on SMB1 mount\n");
|
||||
else {
|
||||
cifs_dbg(VFS, "SMB1 Unix Extensions not supported by server\n");
|
||||
rc = -EOPNOTSUPP;
|
||||
goto out_fail;
|
||||
} else {
|
||||
cifs_dbg(VFS,
|
||||
"Check vers= mount option. SMB3.11 disabled but required for POSIX extensions\n");
|
||||
@ -3686,6 +3693,7 @@ error:
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
|
||||
/*
|
||||
* Issue a TREE_CONNECT request.
|
||||
*/
|
||||
@ -3807,11 +3815,25 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
|
||||
else
|
||||
tcon->Flags = 0;
|
||||
cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* reset_cifs_unix_caps calls QFSInfo which requires
|
||||
* need_reconnect to be false, but we would not need to call
|
||||
* reset_caps if this were not a reconnect case so must check
|
||||
* need_reconnect flag here. The caller will also clear
|
||||
* need_reconnect when tcon was successful but needed to be
|
||||
* cleared earlier in the case of unix extensions reconnect
|
||||
*/
|
||||
if (tcon->need_reconnect && tcon->unix_ext) {
|
||||
cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name);
|
||||
tcon->need_reconnect = false;
|
||||
reset_cifs_unix_caps(xid, tcon, NULL, NULL);
|
||||
}
|
||||
}
|
||||
cifs_buf_release(smb_buffer);
|
||||
return rc;
|
||||
}
|
||||
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
|
||||
|
||||
static void delayed_free(struct rcu_head *p)
|
||||
{
|
||||
|
@ -1812,6 +1812,10 @@ smb2_copychunk_range(const unsigned int xid,
|
||||
|
||||
tcon = tlink_tcon(trgtfile->tlink);
|
||||
|
||||
trace_smb3_copychunk_enter(xid, srcfile->fid.volatile_fid,
|
||||
trgtfile->fid.volatile_fid, tcon->tid,
|
||||
tcon->ses->Suid, src_off, dest_off, len);
|
||||
|
||||
while (len > 0) {
|
||||
pcchunk->SourceOffset = cpu_to_le64(src_off);
|
||||
pcchunk->TargetOffset = cpu_to_le64(dest_off);
|
||||
@ -1863,6 +1867,9 @@ smb2_copychunk_range(const unsigned int xid,
|
||||
le32_to_cpu(retbuf->ChunksWritten),
|
||||
le32_to_cpu(retbuf->ChunkBytesWritten),
|
||||
bytes_written);
|
||||
trace_smb3_copychunk_done(xid, srcfile->fid.volatile_fid,
|
||||
trgtfile->fid.volatile_fid, tcon->tid,
|
||||
tcon->ses->Suid, src_off, dest_off, len);
|
||||
} else if (rc == -EINVAL) {
|
||||
if (ret_data_len != sizeof(struct copychunk_ioctl_rsp))
|
||||
goto cchunk_out;
|
||||
@ -2046,7 +2053,9 @@ smb2_duplicate_extents(const unsigned int xid,
|
||||
dup_ext_buf.ByteCount = cpu_to_le64(len);
|
||||
cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n",
|
||||
src_off, dest_off, len);
|
||||
|
||||
trace_smb3_clone_enter(xid, srcfile->fid.volatile_fid,
|
||||
trgtfile->fid.volatile_fid, tcon->tid,
|
||||
tcon->ses->Suid, src_off, dest_off, len);
|
||||
inode = d_inode(trgtfile->dentry);
|
||||
if (inode->i_size < dest_off + len) {
|
||||
rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
|
||||
@ -2075,6 +2084,15 @@ smb2_duplicate_extents(const unsigned int xid,
|
||||
cifs_dbg(FYI, "Non-zero response length in duplicate extents\n");
|
||||
|
||||
duplicate_extents_out:
|
||||
if (rc)
|
||||
trace_smb3_clone_err(xid, srcfile->fid.volatile_fid,
|
||||
trgtfile->fid.volatile_fid,
|
||||
tcon->tid, tcon->ses->Suid, src_off,
|
||||
dest_off, len, rc);
|
||||
else
|
||||
trace_smb3_clone_done(xid, srcfile->fid.volatile_fid,
|
||||
trgtfile->fid.volatile_fid, tcon->tid,
|
||||
tcon->ses->Suid, src_off, dest_off, len);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1562,8 +1562,14 @@ SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data)
|
||||
cifs_small_buf_release(sess_data->iov[0].iov_base);
|
||||
if (rc == 0)
|
||||
sess_data->ses->expired_pwd = false;
|
||||
else if ((rc == -EACCES) || (rc == -EKEYEXPIRED) || (rc == -EKEYREVOKED))
|
||||
else if ((rc == -EACCES) || (rc == -EKEYEXPIRED) || (rc == -EKEYREVOKED)) {
|
||||
if (sess_data->ses->expired_pwd == false)
|
||||
trace_smb3_key_expired(sess_data->server->hostname,
|
||||
sess_data->ses->user_name,
|
||||
sess_data->server->conn_id,
|
||||
&sess_data->server->dstaddr, rc);
|
||||
sess_data->ses->expired_pwd = true;
|
||||
}
|
||||
|
||||
memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec));
|
||||
|
||||
|
@ -206,6 +206,116 @@ DEFINE_SMB3_OTHER_ERR_EVENT(query_dir_err);
|
||||
DEFINE_SMB3_OTHER_ERR_EVENT(zero_err);
|
||||
DEFINE_SMB3_OTHER_ERR_EVENT(falloc_err);
|
||||
|
||||
/*
|
||||
* For logging errors in reflink and copy_range ops e.g. smb2_copychunk_range
|
||||
* and smb2_duplicate_extents
|
||||
*/
|
||||
DECLARE_EVENT_CLASS(smb3_copy_range_err_class,
|
||||
TP_PROTO(unsigned int xid,
|
||||
__u64 src_fid,
|
||||
__u64 target_fid,
|
||||
__u32 tid,
|
||||
__u64 sesid,
|
||||
__u64 src_offset,
|
||||
__u64 target_offset,
|
||||
__u32 len,
|
||||
int rc),
|
||||
TP_ARGS(xid, src_fid, target_fid, tid, sesid, src_offset, target_offset, len, rc),
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, xid)
|
||||
__field(__u64, src_fid)
|
||||
__field(__u64, target_fid)
|
||||
__field(__u32, tid)
|
||||
__field(__u64, sesid)
|
||||
__field(__u64, src_offset)
|
||||
__field(__u64, target_offset)
|
||||
__field(__u32, len)
|
||||
__field(int, rc)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->xid = xid;
|
||||
__entry->src_fid = src_fid;
|
||||
__entry->target_fid = target_fid;
|
||||
__entry->tid = tid;
|
||||
__entry->sesid = sesid;
|
||||
__entry->src_offset = src_offset;
|
||||
__entry->target_offset = target_offset;
|
||||
__entry->len = len;
|
||||
__entry->rc = rc;
|
||||
),
|
||||
TP_printk("\txid=%u sid=0x%llx tid=0x%x source fid=0x%llx source offset=0x%llx target fid=0x%llx target offset=0x%llx len=0x%x rc=%d",
|
||||
__entry->xid, __entry->sesid, __entry->tid, __entry->target_fid,
|
||||
__entry->src_offset, __entry->target_fid, __entry->target_offset, __entry->len, __entry->rc)
|
||||
)
|
||||
|
||||
#define DEFINE_SMB3_COPY_RANGE_ERR_EVENT(name) \
|
||||
DEFINE_EVENT(smb3_copy_range_err_class, smb3_##name, \
|
||||
TP_PROTO(unsigned int xid, \
|
||||
__u64 src_fid, \
|
||||
__u64 target_fid, \
|
||||
__u32 tid, \
|
||||
__u64 sesid, \
|
||||
__u64 src_offset, \
|
||||
__u64 target_offset, \
|
||||
__u32 len, \
|
||||
int rc), \
|
||||
TP_ARGS(xid, src_fid, target_fid, tid, sesid, src_offset, target_offset, len, rc))
|
||||
|
||||
DEFINE_SMB3_COPY_RANGE_ERR_EVENT(clone_err);
|
||||
/* TODO: Add SMB3_COPY_RANGE_ERR_EVENT(copychunk_err) */
|
||||
|
||||
DECLARE_EVENT_CLASS(smb3_copy_range_done_class,
|
||||
TP_PROTO(unsigned int xid,
|
||||
__u64 src_fid,
|
||||
__u64 target_fid,
|
||||
__u32 tid,
|
||||
__u64 sesid,
|
||||
__u64 src_offset,
|
||||
__u64 target_offset,
|
||||
__u32 len),
|
||||
TP_ARGS(xid, src_fid, target_fid, tid, sesid, src_offset, target_offset, len),
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned int, xid)
|
||||
__field(__u64, src_fid)
|
||||
__field(__u64, target_fid)
|
||||
__field(__u32, tid)
|
||||
__field(__u64, sesid)
|
||||
__field(__u64, src_offset)
|
||||
__field(__u64, target_offset)
|
||||
__field(__u32, len)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->xid = xid;
|
||||
__entry->src_fid = src_fid;
|
||||
__entry->target_fid = target_fid;
|
||||
__entry->tid = tid;
|
||||
__entry->sesid = sesid;
|
||||
__entry->src_offset = src_offset;
|
||||
__entry->target_offset = target_offset;
|
||||
__entry->len = len;
|
||||
),
|
||||
TP_printk("\txid=%u sid=0x%llx tid=0x%x source fid=0x%llx source offset=0x%llx target fid=0x%llx target offset=0x%llx len=0x%x",
|
||||
__entry->xid, __entry->sesid, __entry->tid, __entry->target_fid,
|
||||
__entry->src_offset, __entry->target_fid, __entry->target_offset, __entry->len)
|
||||
)
|
||||
|
||||
#define DEFINE_SMB3_COPY_RANGE_DONE_EVENT(name) \
|
||||
DEFINE_EVENT(smb3_copy_range_done_class, smb3_##name, \
|
||||
TP_PROTO(unsigned int xid, \
|
||||
__u64 src_fid, \
|
||||
__u64 target_fid, \
|
||||
__u32 tid, \
|
||||
__u64 sesid, \
|
||||
__u64 src_offset, \
|
||||
__u64 target_offset, \
|
||||
__u32 len), \
|
||||
TP_ARGS(xid, src_fid, target_fid, tid, sesid, src_offset, target_offset, len))
|
||||
|
||||
DEFINE_SMB3_COPY_RANGE_DONE_EVENT(copychunk_enter);
|
||||
DEFINE_SMB3_COPY_RANGE_DONE_EVENT(clone_enter);
|
||||
DEFINE_SMB3_COPY_RANGE_DONE_EVENT(copychunk_done);
|
||||
DEFINE_SMB3_COPY_RANGE_DONE_EVENT(clone_done);
|
||||
|
||||
|
||||
/* For logging successful read or write */
|
||||
DECLARE_EVENT_CLASS(smb3_rw_done_class,
|
||||
@ -1171,6 +1281,46 @@ DEFINE_EVENT(smb3_connect_err_class, smb3_##name, \
|
||||
|
||||
DEFINE_SMB3_CONNECT_ERR_EVENT(connect_err);
|
||||
|
||||
DECLARE_EVENT_CLASS(smb3_sess_setup_err_class,
|
||||
TP_PROTO(char *hostname, char *username, __u64 conn_id,
|
||||
const struct __kernel_sockaddr_storage *dst_addr, int rc),
|
||||
TP_ARGS(hostname, username, conn_id, dst_addr, rc),
|
||||
TP_STRUCT__entry(
|
||||
__string(hostname, hostname)
|
||||
__string(username, username)
|
||||
__field(__u64, conn_id)
|
||||
__array(__u8, dst_addr, sizeof(struct sockaddr_storage))
|
||||
__field(int, rc)
|
||||
),
|
||||
TP_fast_assign(
|
||||
struct sockaddr_storage *pss = NULL;
|
||||
|
||||
__entry->conn_id = conn_id;
|
||||
__entry->rc = rc;
|
||||
pss = (struct sockaddr_storage *)__entry->dst_addr;
|
||||
*pss = *dst_addr;
|
||||
__assign_str(hostname);
|
||||
__assign_str(username);
|
||||
),
|
||||
TP_printk("rc=%d user=%s conn_id=0x%llx server=%s addr=%pISpsfc",
|
||||
__entry->rc,
|
||||
__get_str(username),
|
||||
__entry->conn_id,
|
||||
__get_str(hostname),
|
||||
__entry->dst_addr)
|
||||
)
|
||||
|
||||
#define DEFINE_SMB3_SES_SETUP_ERR_EVENT(name) \
|
||||
DEFINE_EVENT(smb3_sess_setup_err_class, smb3_##name, \
|
||||
TP_PROTO(char *hostname, \
|
||||
char *username, \
|
||||
__u64 conn_id, \
|
||||
const struct __kernel_sockaddr_storage *addr, \
|
||||
int rc), \
|
||||
TP_ARGS(hostname, username, conn_id, addr, rc))
|
||||
|
||||
DEFINE_SMB3_SES_SETUP_ERR_EVENT(key_expired);
|
||||
|
||||
DECLARE_EVENT_CLASS(smb3_reconnect_class,
|
||||
TP_PROTO(__u64 currmid,
|
||||
__u64 conn_id,
|
||||
|
Loading…
Reference in New Issue
Block a user