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

+203 -7
+4 -4
fs/smb/client/cifsfs.c
··· 1894 1894 WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); 1895 1895 if (!serverclose_wq) { 1896 1896 rc = -ENOMEM; 1897 - goto out_destroy_serverclose_wq; 1897 + goto out_destroy_deferredclose_wq; 1898 1898 } 1899 1899 1900 1900 rc = cifs_init_inodecache(); 1901 1901 if (rc) 1902 - goto out_destroy_deferredclose_wq; 1902 + goto out_destroy_serverclose_wq; 1903 1903 1904 1904 rc = cifs_init_netfs(); 1905 1905 if (rc) ··· 1967 1967 cifs_destroy_netfs(); 1968 1968 out_destroy_inodecache: 1969 1969 cifs_destroy_inodecache(); 1970 + out_destroy_serverclose_wq: 1971 + destroy_workqueue(serverclose_wq); 1970 1972 out_destroy_deferredclose_wq: 1971 1973 destroy_workqueue(deferredclose_wq); 1972 1974 out_destroy_cifsoplockd_wq: ··· 1979 1977 destroy_workqueue(decrypt_wq); 1980 1978 out_destroy_cifsiod_wq: 1981 1979 destroy_workqueue(cifsiod_wq); 1982 - out_destroy_serverclose_wq: 1983 - destroy_workqueue(serverclose_wq); 1984 1980 out_clean_proc: 1985 1981 cifs_proc_clean(); 1986 1982 return rc;
+23 -1
fs/smb/client/connect.c
··· 2614 2614 cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions\n"); 2615 2615 rc = -EOPNOTSUPP; 2616 2616 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; 2617 2624 } else { 2618 2625 cifs_dbg(VFS, 2619 2626 "Check vers= mount option. SMB3.11 disabled but required for POSIX extensions\n"); ··· 3693 3686 } 3694 3687 #endif 3695 3688 3689 + #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 3696 3690 /* 3697 3691 * Issue a TREE_CONNECT request. 3698 3692 */ ··· 3815 3807 else 3816 3808 tcon->Flags = 0; 3817 3809 cifs_dbg(FYI, "Tcon flags: 0x%x\n", tcon->Flags); 3818 - } 3819 3810 3811 + /* 3812 + * reset_cifs_unix_caps calls QFSInfo which requires 3813 + * need_reconnect to be false, but we would not need to call 3814 + * reset_caps if this were not a reconnect case so must check 3815 + * need_reconnect flag here. The caller will also clear 3816 + * need_reconnect when tcon was successful but needed to be 3817 + * cleared earlier in the case of unix extensions reconnect 3818 + */ 3819 + if (tcon->need_reconnect && tcon->unix_ext) { 3820 + cifs_dbg(FYI, "resetting caps for %s\n", tcon->tree_name); 3821 + tcon->need_reconnect = false; 3822 + reset_cifs_unix_caps(xid, tcon, NULL, NULL); 3823 + } 3824 + } 3820 3825 cifs_buf_release(smb_buffer); 3821 3826 return rc; 3822 3827 } 3828 + #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ 3823 3829 3824 3830 static void delayed_free(struct rcu_head *p) 3825 3831 {
+19 -1
fs/smb/client/smb2ops.c
··· 1812 1812 1813 1813 tcon = tlink_tcon(trgtfile->tlink); 1814 1814 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 + 1815 1819 while (len > 0) { 1816 1820 pcchunk->SourceOffset = cpu_to_le64(src_off); 1817 1821 pcchunk->TargetOffset = cpu_to_le64(dest_off); ··· 1867 1863 le32_to_cpu(retbuf->ChunksWritten), 1868 1864 le32_to_cpu(retbuf->ChunkBytesWritten), 1869 1865 bytes_written); 1866 + trace_smb3_copychunk_done(xid, srcfile->fid.volatile_fid, 1867 + trgtfile->fid.volatile_fid, tcon->tid, 1868 + tcon->ses->Suid, src_off, dest_off, len); 1870 1869 } else if (rc == -EINVAL) { 1871 1870 if (ret_data_len != sizeof(struct copychunk_ioctl_rsp)) 1872 1871 goto cchunk_out; ··· 2053 2046 dup_ext_buf.ByteCount = cpu_to_le64(len); 2054 2047 cifs_dbg(FYI, "Duplicate extents: src off %lld dst off %lld len %lld\n", 2055 2048 src_off, dest_off, len); 2056 - 2049 + trace_smb3_clone_enter(xid, srcfile->fid.volatile_fid, 2050 + trgtfile->fid.volatile_fid, tcon->tid, 2051 + tcon->ses->Suid, src_off, dest_off, len); 2057 2052 inode = d_inode(trgtfile->dentry); 2058 2053 if (inode->i_size < dest_off + len) { 2059 2054 rc = smb2_set_file_size(xid, tcon, trgtfile, dest_off + len, false); ··· 2084 2075 cifs_dbg(FYI, "Non-zero response length in duplicate extents\n"); 2085 2076 2086 2077 duplicate_extents_out: 2078 + if (rc) 2079 + trace_smb3_clone_err(xid, srcfile->fid.volatile_fid, 2080 + trgtfile->fid.volatile_fid, 2081 + tcon->tid, tcon->ses->Suid, src_off, 2082 + dest_off, len, rc); 2083 + else 2084 + trace_smb3_clone_done(xid, srcfile->fid.volatile_fid, 2085 + trgtfile->fid.volatile_fid, tcon->tid, 2086 + tcon->ses->Suid, src_off, dest_off, len); 2087 2087 return rc; 2088 2088 } 2089 2089
+7 -1
fs/smb/client/smb2pdu.c
··· 1562 1562 cifs_small_buf_release(sess_data->iov[0].iov_base); 1563 1563 if (rc == 0) 1564 1564 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); 1566 1571 sess_data->ses->expired_pwd = true; 1572 + } 1567 1573 1568 1574 memcpy(&sess_data->iov[0], &rsp_iov, sizeof(struct kvec)); 1569 1575
+150
fs/smb/client/trace.h
··· 206 206 DEFINE_SMB3_OTHER_ERR_EVENT(zero_err); 207 207 DEFINE_SMB3_OTHER_ERR_EVENT(falloc_err); 208 208 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 + 209 319 210 320 /* For logging successful read or write */ 211 321 DECLARE_EVENT_CLASS(smb3_rw_done_class, ··· 1280 1170 TP_ARGS(hostname, conn_id, addr, rc)) 1281 1171 1282 1172 DEFINE_SMB3_CONNECT_ERR_EVENT(connect_err); 1173 + 1174 + DECLARE_EVENT_CLASS(smb3_sess_setup_err_class, 1175 + TP_PROTO(char *hostname, char *username, __u64 conn_id, 1176 + const struct __kernel_sockaddr_storage *dst_addr, int rc), 1177 + TP_ARGS(hostname, username, conn_id, dst_addr, rc), 1178 + TP_STRUCT__entry( 1179 + __string(hostname, hostname) 1180 + __string(username, username) 1181 + __field(__u64, conn_id) 1182 + __array(__u8, dst_addr, sizeof(struct sockaddr_storage)) 1183 + __field(int, rc) 1184 + ), 1185 + TP_fast_assign( 1186 + struct sockaddr_storage *pss = NULL; 1187 + 1188 + __entry->conn_id = conn_id; 1189 + __entry->rc = rc; 1190 + pss = (struct sockaddr_storage *)__entry->dst_addr; 1191 + *pss = *dst_addr; 1192 + __assign_str(hostname); 1193 + __assign_str(username); 1194 + ), 1195 + TP_printk("rc=%d user=%s conn_id=0x%llx server=%s addr=%pISpsfc", 1196 + __entry->rc, 1197 + __get_str(username), 1198 + __entry->conn_id, 1199 + __get_str(hostname), 1200 + __entry->dst_addr) 1201 + ) 1202 + 1203 + #define DEFINE_SMB3_SES_SETUP_ERR_EVENT(name) \ 1204 + DEFINE_EVENT(smb3_sess_setup_err_class, smb3_##name, \ 1205 + TP_PROTO(char *hostname, \ 1206 + char *username, \ 1207 + __u64 conn_id, \ 1208 + const struct __kernel_sockaddr_storage *addr, \ 1209 + int rc), \ 1210 + TP_ARGS(hostname, username, conn_id, addr, rc)) 1211 + 1212 + DEFINE_SMB3_SES_SETUP_ERR_EVENT(key_expired); 1283 1213 1284 1214 DECLARE_EVENT_CLASS(smb3_reconnect_class, 1285 1215 TP_PROTO(__u64 currmid,