Skip to content

Commit 5437f30

Browse files
committed
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
2 parents 6342649 + b6f6a7a commit 5437f30

File tree

5 files changed

+203
-7
lines changed

5 files changed

+203
-7
lines changed

fs/smb/client/cifsfs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1894,12 +1894,12 @@ init_cifs(void)
18941894
WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
18951895
if (!serverclose_wq) {
18961896
rc = -ENOMEM;
1897-
goto out_destroy_serverclose_wq;
1897+
goto out_destroy_deferredclose_wq;
18981898
}
18991899

19001900
rc = cifs_init_inodecache();
19011901
if (rc)
1902-
goto out_destroy_deferredclose_wq;
1902+
goto out_destroy_serverclose_wq;
19031903

19041904
rc = cifs_init_netfs();
19051905
if (rc)
@@ -1967,6 +1967,8 @@ init_cifs(void)
19671967
cifs_destroy_netfs();
19681968
out_destroy_inodecache:
19691969
cifs_destroy_inodecache();
1970+
out_destroy_serverclose_wq:
1971+
destroy_workqueue(serverclose_wq);
19701972
out_destroy_deferredclose_wq:
19711973
destroy_workqueue(deferredclose_wq);
19721974
out_destroy_cifsoplockd_wq:
@@ -1977,8 +1979,6 @@ init_cifs(void)
19771979
destroy_workqueue(decrypt_wq);
19781980
out_destroy_cifsiod_wq:
19791981
destroy_workqueue(cifsiod_wq);
1980-
out_destroy_serverclose_wq:
1981-
destroy_workqueue(serverclose_wq);
19821982
out_clean_proc:
19831983
cifs_proc_clean();
19841984
return rc;

fs/smb/client/connect.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2614,6 +2614,13 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
26142614
cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions\n");
26152615
rc = -EOPNOTSUPP;
26162616
goto out_fail;
2617+
} else if (ses->server->vals->protocol_id == SMB10_PROT_ID)
2618+
if (cap_unix(ses))
2619+
cifs_dbg(FYI, "Unix Extensions requested on SMB1 mount\n");
2620+
else {
2621+
cifs_dbg(VFS, "SMB1 Unix Extensions not supported by server\n");
2622+
rc = -EOPNOTSUPP;
2623+
goto out_fail;
26172624
} else {
26182625
cifs_dbg(VFS,
26192626
"Check vers= mount option. SMB3.11 disabled but required for POSIX extensions\n");
@@ -3686,6 +3693,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
36863693
}
36873694
#endif
36883695

3696+
#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
36893697
/*
36903698
* Issue a TREE_CONNECT request.
36913699
*/
@@ -3807,11 +3815,25 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
38073815
else
38083816
tcon->Flags = 0;
38093817
cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags);
3810-
}
38113818

3819+
/*
3820+
* reset_cifs_unix_caps calls QFSInfo which requires
3821+
* need_reconnect to be false, but we would not need to call
3822+
* reset_caps if this were not a reconnect case so must check
3823+
* need_reconnect flag here. The caller will also clear
3824+
* need_reconnect when tcon was successful but needed to be
3825+
* cleared earlier in the case of unix extensions reconnect
3826+
*/
3827+
if (tcon->need_reconnect && tcon->unix_ext) {
3828+
cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name);
3829+
tcon->need_reconnect = false;
3830+
reset_cifs_unix_caps(xid, tcon, NULL, NULL);
3831+
}
3832+
}
38123833
cifs_buf_release(smb_buffer);
38133834
return rc;
38143835
}
3836+
#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
38153837

38163838
static void delayed_free(struct rcu_head *p)
38173839
{

fs/smb/client/smb2ops.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1812,6 +1812,10 @@ smb2_copychunk_range(const unsigned int xid,
18121812

18131813
tcon = tlink_tcon(trgtfile->tlink);
18141814

1815+
trace_smb3_copychunk_enter(xid, srcfile->fid.volatile_fid,
1816+
trgtfile->fid.volatile_fid, tcon->tid,
1817+
tcon->ses->Suid, src_off, dest_off, len);
1818+
18151819
while (len > 0) {
18161820
pcchunk->SourceOffset = cpu_to_le64(src_off);
18171821
pcchunk->TargetOffset = cpu_to_le64(dest_off);
@@ -1863,6 +1867,9 @@ smb2_copychunk_range(const unsigned int xid,
18631867
le32_to_cpu(retbuf->ChunksWritten),
18641868
le32_to_cpu(retbuf->ChunkBytesWritten),
18651869
bytes_written);
1870+
trace_smb3_copychunk_done(xid, srcfile->fid.volatile_fid,
1871+
trgtfile->fid.volatile_fid, tcon->tid,
1872+
tcon->ses->Suid, src_off, dest_off, len);
18661873
} else if (rc == -EINVAL) {
18671874
if (ret_data_len != sizeof(struct copychunk_ioctl_rsp))
18681875
goto cchunk_out;
@@ -2046,7 +2053,9 @@ smb2_duplicate_extents(const unsigned int xid,
20462053
dup_ext_buf.ByteCount = cpu_to_le64(len);
20472054
cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n",
20482055
src_off, dest_off, len);
2049-
2056+
trace_smb3_clone_enter(xid, srcfile->fid.volatile_fid,
2057+
trgtfile->fid.volatile_fid, tcon->tid,
2058+
tcon->ses->Suid, src_off, dest_off, len);
20502059
inode = d_inode(trgtfile->dentry);
20512060
if (inode->i_size < dest_off + len) {
20522061
rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false);
@@ -2075,6 +2084,15 @@ smb2_duplicate_extents(const unsigned int xid,
20752084
cifs_dbg(FYI, "Non-zero response length in duplicate extents\n");
20762085

20772086
duplicate_extents_out:
2087+
if (rc)
2088+
trace_smb3_clone_err(xid, srcfile->fid.volatile_fid,
2089+
trgtfile->fid.volatile_fid,
2090+
tcon->tid, tcon->ses->Suid, src_off,
2091+
dest_off, len, rc);
2092+
else
2093+
trace_smb3_clone_done(xid, srcfile->fid.volatile_fid,
2094+
trgtfile->fid.volatile_fid, tcon->tid,
2095+
tcon->ses->Suid, src_off, dest_off, len);
20782096
return rc;
20792097
}
20802098

fs/smb/client/smb2pdu.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1562,8 +1562,14 @@ SMB2_sess_sendreceive(struct SMB2_sess_data *sess_data)
15621562
cifs_small_buf_release(sess_data->iov[0].iov_base);
15631563
if (rc == 0)
15641564
sess_data->ses->expired_pwd = false;
1565-
else if ((rc == -EACCES) || (rc == -EKEYEXPIRED) || (rc == -EKEYREVOKED))
1565+
else if ((rc == -EACCES) || (rc == -EKEYEXPIRED) || (rc == -EKEYREVOKED)) {
1566+
if (sess_data->ses->expired_pwd == false)
1567+
trace_smb3_key_expired(sess_data->server->hostname,
1568+
sess_data->ses->user_name,
1569+
sess_data->server->conn_id,
1570+
&sess_data->server->dstaddr, rc);
15661571
sess_data->ses->expired_pwd = true;
1572+
}
15671573

15681574
memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec));
15691575

fs/smb/client/trace.h

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,116 @@ DEFINE_SMB3_OTHER_ERR_EVENT(query_dir_err);
206206
DEFINE_SMB3_OTHER_ERR_EVENT(zero_err);
207207
DEFINE_SMB3_OTHER_ERR_EVENT(falloc_err);
208208

209+
/*
210+
* For logging errors in reflink and copy_range ops e.g. smb2_copychunk_range
211+
* and smb2_duplicate_extents
212+
*/
213+
DECLARE_EVENT_CLASS(smb3_copy_range_err_class,
214+
TP_PROTO(unsigned int xid,
215+
__u64 src_fid,
216+
__u64 target_fid,
217+
__u32 tid,
218+
__u64 sesid,
219+
__u64 src_offset,
220+
__u64 target_offset,
221+
__u32 len,
222+
int rc),
223+
TP_ARGS(xid, src_fid, target_fid, tid, sesid, src_offset, target_offset, len, rc),
224+
TP_STRUCT__entry(
225+
__field(unsigned int, xid)
226+
__field(__u64, src_fid)
227+
__field(__u64, target_fid)
228+
__field(__u32, tid)
229+
__field(__u64, sesid)
230+
__field(__u64, src_offset)
231+
__field(__u64, target_offset)
232+
__field(__u32, len)
233+
__field(int, rc)
234+
),
235+
TP_fast_assign(
236+
__entry->xid = xid;
237+
__entry->src_fid = src_fid;
238+
__entry->target_fid = target_fid;
239+
__entry->tid = tid;
240+
__entry->sesid = sesid;
241+
__entry->src_offset = src_offset;
242+
__entry->target_offset = target_offset;
243+
__entry->len = len;
244+
__entry->rc = rc;
245+
),
246+
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",
247+
__entry->xid, __entry->sesid, __entry->tid, __entry->target_fid,
248+
__entry->src_offset, __entry->target_fid, __entry->target_offset, __entry->len, __entry->rc)
249+
)
250+
251+
#define DEFINE_SMB3_COPY_RANGE_ERR_EVENT(name) \
252+
DEFINE_EVENT(smb3_copy_range_err_class, smb3_##name, \
253+
TP_PROTO(unsigned int xid, \
254+
__u64 src_fid, \
255+
__u64 target_fid, \
256+
__u32 tid, \
257+
__u64 sesid, \
258+
__u64 src_offset, \
259+
__u64 target_offset, \
260+
__u32 len, \
261+
int rc), \
262+
TP_ARGS(xid, src_fid, target_fid, tid, sesid, src_offset, target_offset, len, rc))
263+
264+
DEFINE_SMB3_COPY_RANGE_ERR_EVENT(clone_err);
265+
/* TODO: Add SMB3_COPY_RANGE_ERR_EVENT(copychunk_err) */
266+
267+
DECLARE_EVENT_CLASS(smb3_copy_range_done_class,
268+
TP_PROTO(unsigned int xid,
269+
__u64 src_fid,
270+
__u64 target_fid,
271+
__u32 tid,
272+
__u64 sesid,
273+
__u64 src_offset,
274+
__u64 target_offset,
275+
__u32 len),
276+
TP_ARGS(xid, src_fid, target_fid, tid, sesid, src_offset, target_offset, len),
277+
TP_STRUCT__entry(
278+
__field(unsigned int, xid)
279+
__field(__u64, src_fid)
280+
__field(__u64, target_fid)
281+
__field(__u32, tid)
282+
__field(__u64, sesid)
283+
__field(__u64, src_offset)
284+
__field(__u64, target_offset)
285+
__field(__u32, len)
286+
),
287+
TP_fast_assign(
288+
__entry->xid = xid;
289+
__entry->src_fid = src_fid;
290+
__entry->target_fid = target_fid;
291+
__entry->tid = tid;
292+
__entry->sesid = sesid;
293+
__entry->src_offset = src_offset;
294+
__entry->target_offset = target_offset;
295+
__entry->len = len;
296+
),
297+
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",
298+
__entry->xid, __entry->sesid, __entry->tid, __entry->target_fid,
299+
__entry->src_offset, __entry->target_fid, __entry->target_offset, __entry->len)
300+
)
301+
302+
#define DEFINE_SMB3_COPY_RANGE_DONE_EVENT(name) \
303+
DEFINE_EVENT(smb3_copy_range_done_class, smb3_##name, \
304+
TP_PROTO(unsigned int xid, \
305+
__u64 src_fid, \
306+
__u64 target_fid, \
307+
__u32 tid, \
308+
__u64 sesid, \
309+
__u64 src_offset, \
310+
__u64 target_offset, \
311+
__u32 len), \
312+
TP_ARGS(xid, src_fid, target_fid, tid, sesid, src_offset, target_offset, len))
313+
314+
DEFINE_SMB3_COPY_RANGE_DONE_EVENT(copychunk_enter);
315+
DEFINE_SMB3_COPY_RANGE_DONE_EVENT(clone_enter);
316+
DEFINE_SMB3_COPY_RANGE_DONE_EVENT(copychunk_done);
317+
DEFINE_SMB3_COPY_RANGE_DONE_EVENT(clone_done);
318+
209319

210320
/* For logging successful read or write */
211321
DECLARE_EVENT_CLASS(smb3_rw_done_class,
@@ -1171,6 +1281,46 @@ DEFINE_EVENT(smb3_connect_err_class, smb3_##name, \
11711281

11721282
DEFINE_SMB3_CONNECT_ERR_EVENT(connect_err);
11731283

1284+
DECLARE_EVENT_CLASS(smb3_sess_setup_err_class,
1285+
TP_PROTO(char *hostname, char *username, __u64 conn_id,
1286+
const struct __kernel_sockaddr_storage *dst_addr, int rc),
1287+
TP_ARGS(hostname, username, conn_id, dst_addr, rc),
1288+
TP_STRUCT__entry(
1289+
__string(hostname, hostname)
1290+
__string(username, username)
1291+
__field(__u64, conn_id)
1292+
__array(__u8, dst_addr, sizeof(struct sockaddr_storage))
1293+
__field(int, rc)
1294+
),
1295+
TP_fast_assign(
1296+
struct sockaddr_storage *pss = NULL;
1297+
1298+
__entry->conn_id = conn_id;
1299+
__entry->rc = rc;
1300+
pss = (struct sockaddr_storage *)__entry->dst_addr;
1301+
*pss = *dst_addr;
1302+
__assign_str(hostname);
1303+
__assign_str(username);
1304+
),
1305+
TP_printk("rc=%d user=%s conn_id=0x%llx server=%s addr=%pISpsfc",
1306+
__entry->rc,
1307+
__get_str(username),
1308+
__entry->conn_id,
1309+
__get_str(hostname),
1310+
__entry->dst_addr)
1311+
)
1312+
1313+
#define DEFINE_SMB3_SES_SETUP_ERR_EVENT(name) \
1314+
DEFINE_EVENT(smb3_sess_setup_err_class, smb3_##name, \
1315+
TP_PROTO(char *hostname, \
1316+
char *username, \
1317+
__u64 conn_id, \
1318+
const struct __kernel_sockaddr_storage *addr, \
1319+
int rc), \
1320+
TP_ARGS(hostname, username, conn_id, addr, rc))
1321+
1322+
DEFINE_SMB3_SES_SETUP_ERR_EVENT(key_expired);
1323+
11741324
DECLARE_EVENT_CLASS(smb3_reconnect_class,
11751325
TP_PROTO(__u64 currmid,
11761326
__u64 conn_id,

0 commit comments

Comments
 (0)