cifs_debug.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * fs/cifs_debug.c
  4. *
  5. * Copyright (C) International Business Machines Corp., 2000,2005
  6. *
  7. * Modified by Steve French (sfrench@us.ibm.com)
  8. */
  9. #include <linux/fs.h>
  10. #include <linux/string.h>
  11. #include <linux/ctype.h>
  12. #include <linux/module.h>
  13. #include <linux/proc_fs.h>
  14. #include <linux/uaccess.h>
  15. #include "cifspdu.h"
  16. #include "cifsglob.h"
  17. #include "cifsproto.h"
  18. #include "cifs_debug.h"
  19. #include "cifsfs.h"
  20. #ifdef CONFIG_CIFS_DFS_UPCALL
  21. #include "dfs_cache.h"
  22. #endif
  23. #ifdef CONFIG_CIFS_SMB_DIRECT
  24. #include "smbdirect.h"
  25. #endif
  26. void
  27. cifs_dump_mem(char *label, void *data, int length)
  28. {
  29. pr_debug("%s: dump of %d bytes of data at 0x%p\n", label, length, data);
  30. print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 4,
  31. data, length, true);
  32. }
  33. void cifs_dump_detail(void *buf, struct TCP_Server_Info *server)
  34. {
  35. #ifdef CONFIG_CIFS_DEBUG2
  36. struct smb_hdr *smb = (struct smb_hdr *)buf;
  37. cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d\n",
  38. smb->Command, smb->Status.CifsError,
  39. smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
  40. cifs_dbg(VFS, "smb buf %p len %u\n", smb,
  41. server->ops->calc_smb_size(smb, server));
  42. #endif /* CONFIG_CIFS_DEBUG2 */
  43. }
  44. void cifs_dump_mids(struct TCP_Server_Info *server)
  45. {
  46. #ifdef CONFIG_CIFS_DEBUG2
  47. struct list_head *tmp;
  48. struct mid_q_entry *mid_entry;
  49. if (server == NULL)
  50. return;
  51. cifs_dbg(VFS, "Dump pending requests:\n");
  52. spin_lock(&GlobalMid_Lock);
  53. list_for_each(tmp, &server->pending_mid_q) {
  54. mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
  55. cifs_dbg(VFS, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu\n",
  56. mid_entry->mid_state,
  57. le16_to_cpu(mid_entry->command),
  58. mid_entry->pid,
  59. mid_entry->callback_data,
  60. mid_entry->mid);
  61. #ifdef CONFIG_CIFS_STATS2
  62. cifs_dbg(VFS, "IsLarge: %d buf: %p time rcv: %ld now: %ld\n",
  63. mid_entry->large_buf,
  64. mid_entry->resp_buf,
  65. mid_entry->when_received,
  66. jiffies);
  67. #endif /* STATS2 */
  68. cifs_dbg(VFS, "IsMult: %d IsEnd: %d\n",
  69. mid_entry->multiRsp, mid_entry->multiEnd);
  70. if (mid_entry->resp_buf) {
  71. cifs_dump_detail(mid_entry->resp_buf, server);
  72. cifs_dump_mem("existing buf: ",
  73. mid_entry->resp_buf, 62);
  74. }
  75. }
  76. spin_unlock(&GlobalMid_Lock);
  77. #endif /* CONFIG_CIFS_DEBUG2 */
  78. }
  79. #ifdef CONFIG_PROC_FS
  80. static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
  81. {
  82. __u32 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
  83. seq_printf(m, "%s Mounts: %d ", tcon->treeName, tcon->tc_count);
  84. if (tcon->nativeFileSystem)
  85. seq_printf(m, "Type: %s ", tcon->nativeFileSystem);
  86. seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x\n\tPathComponentMax: %d Status: %d",
  87. le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
  88. le32_to_cpu(tcon->fsAttrInfo.Attributes),
  89. le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
  90. tcon->tidStatus);
  91. if (dev_type == FILE_DEVICE_DISK)
  92. seq_puts(m, " type: DISK ");
  93. else if (dev_type == FILE_DEVICE_CD_ROM)
  94. seq_puts(m, " type: CDROM ");
  95. else
  96. seq_printf(m, " type: %d ", dev_type);
  97. seq_printf(m, "Serial Number: 0x%x", tcon->vol_serial_number);
  98. if ((tcon->seal) ||
  99. (tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) ||
  100. (tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA))
  101. seq_printf(m, " Encrypted");
  102. if (tcon->nocase)
  103. seq_printf(m, " nocase");
  104. if (tcon->unix_ext)
  105. seq_printf(m, " POSIX Extensions");
  106. if (tcon->ses->server->ops->dump_share_caps)
  107. tcon->ses->server->ops->dump_share_caps(m, tcon);
  108. if (tcon->need_reconnect)
  109. seq_puts(m, "\tDISCONNECTED ");
  110. seq_putc(m, '\n');
  111. }
  112. static void
  113. cifs_dump_channel(struct seq_file *m, int i, struct cifs_chan *chan)
  114. {
  115. struct TCP_Server_Info *server = chan->server;
  116. seq_printf(m, "\t\tChannel %d Number of credits: %d Dialect 0x%x "
  117. "TCP status: %d Instance: %d Local Users To Server: %d "
  118. "SecMode: 0x%x Req On Wire: %d In Send: %d "
  119. "In MaxReq Wait: %d\n",
  120. i+1,
  121. server->credits,
  122. server->dialect,
  123. server->tcpStatus,
  124. server->reconnect_instance,
  125. server->srv_count,
  126. server->sec_mode,
  127. in_flight(server),
  128. atomic_read(&server->in_send),
  129. atomic_read(&server->num_waiters));
  130. }
  131. static void
  132. cifs_dump_iface(struct seq_file *m, struct cifs_server_iface *iface)
  133. {
  134. struct sockaddr_in *ipv4 = (struct sockaddr_in *)&iface->sockaddr;
  135. struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&iface->sockaddr;
  136. seq_printf(m, "\tSpeed: %zu bps\n", iface->speed);
  137. seq_puts(m, "\t\tCapabilities: ");
  138. if (iface->rdma_capable)
  139. seq_puts(m, "rdma ");
  140. if (iface->rss_capable)
  141. seq_puts(m, "rss ");
  142. seq_putc(m, '\n');
  143. if (iface->sockaddr.ss_family == AF_INET)
  144. seq_printf(m, "\t\tIPv4: %pI4\n", &ipv4->sin_addr);
  145. else if (iface->sockaddr.ss_family == AF_INET6)
  146. seq_printf(m, "\t\tIPv6: %pI6\n", &ipv6->sin6_addr);
  147. }
  148. static int cifs_debug_files_proc_show(struct seq_file *m, void *v)
  149. {
  150. struct list_head *stmp, *tmp, *tmp1, *tmp2;
  151. struct TCP_Server_Info *server;
  152. struct cifs_ses *ses;
  153. struct cifs_tcon *tcon;
  154. struct cifsFileInfo *cfile;
  155. seq_puts(m, "# Version:1\n");
  156. seq_puts(m, "# Format:\n");
  157. seq_puts(m, "# <tree id> <persistent fid> <flags> <count> <pid> <uid>");
  158. #ifdef CONFIG_CIFS_DEBUG2
  159. seq_printf(m, " <filename> <mid>\n");
  160. #else
  161. seq_printf(m, " <filename>\n");
  162. #endif /* CIFS_DEBUG2 */
  163. spin_lock(&cifs_tcp_ses_lock);
  164. list_for_each(stmp, &cifs_tcp_ses_list) {
  165. server = list_entry(stmp, struct TCP_Server_Info,
  166. tcp_ses_list);
  167. list_for_each(tmp, &server->smb_ses_list) {
  168. ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
  169. list_for_each(tmp1, &ses->tcon_list) {
  170. tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
  171. spin_lock(&tcon->open_file_lock);
  172. list_for_each(tmp2, &tcon->openFileList) {
  173. cfile = list_entry(tmp2, struct cifsFileInfo,
  174. tlist);
  175. seq_printf(m,
  176. "0x%x 0x%llx 0x%x %d %d %d %s",
  177. tcon->tid,
  178. cfile->fid.persistent_fid,
  179. cfile->f_flags,
  180. cfile->count,
  181. cfile->pid,
  182. from_kuid(&init_user_ns, cfile->uid),
  183. cfile->dentry->d_name.name);
  184. #ifdef CONFIG_CIFS_DEBUG2
  185. seq_printf(m, " 0x%llx\n", cfile->fid.mid);
  186. #else
  187. seq_printf(m, "\n");
  188. #endif /* CIFS_DEBUG2 */
  189. }
  190. spin_unlock(&tcon->open_file_lock);
  191. }
  192. }
  193. }
  194. spin_unlock(&cifs_tcp_ses_lock);
  195. seq_putc(m, '\n');
  196. return 0;
  197. }
  198. static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
  199. {
  200. struct list_head *tmp1, *tmp2, *tmp3;
  201. struct mid_q_entry *mid_entry;
  202. struct TCP_Server_Info *server;
  203. struct cifs_ses *ses;
  204. struct cifs_tcon *tcon;
  205. int i, j;
  206. seq_puts(m,
  207. "Display Internal CIFS Data Structures for Debugging\n"
  208. "---------------------------------------------------\n");
  209. seq_printf(m, "CIFS Version %s\n", CIFS_VERSION);
  210. seq_printf(m, "Features:");
  211. #ifdef CONFIG_CIFS_DFS_UPCALL
  212. seq_printf(m, " DFS");
  213. #endif
  214. #ifdef CONFIG_CIFS_FSCACHE
  215. seq_printf(m, ",FSCACHE");
  216. #endif
  217. #ifdef CONFIG_CIFS_SMB_DIRECT
  218. seq_printf(m, ",SMB_DIRECT");
  219. #endif
  220. #ifdef CONFIG_CIFS_STATS2
  221. seq_printf(m, ",STATS2");
  222. #else
  223. seq_printf(m, ",STATS");
  224. #endif
  225. #ifdef CONFIG_CIFS_DEBUG2
  226. seq_printf(m, ",DEBUG2");
  227. #elif defined(CONFIG_CIFS_DEBUG)
  228. seq_printf(m, ",DEBUG");
  229. #endif
  230. #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
  231. seq_printf(m, ",ALLOW_INSECURE_LEGACY");
  232. #endif
  233. #ifdef CONFIG_CIFS_WEAK_PW_HASH
  234. seq_printf(m, ",WEAK_PW_HASH");
  235. #endif
  236. #ifdef CONFIG_CIFS_POSIX
  237. seq_printf(m, ",CIFS_POSIX");
  238. #endif
  239. #ifdef CONFIG_CIFS_UPCALL
  240. seq_printf(m, ",UPCALL(SPNEGO)");
  241. #endif
  242. #ifdef CONFIG_CIFS_XATTR
  243. seq_printf(m, ",XATTR");
  244. #endif
  245. seq_printf(m, ",ACL");
  246. seq_putc(m, '\n');
  247. seq_printf(m, "CIFSMaxBufSize: %d\n", CIFSMaxBufSize);
  248. seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
  249. seq_printf(m, "Servers:");
  250. i = 0;
  251. spin_lock(&cifs_tcp_ses_lock);
  252. list_for_each(tmp1, &cifs_tcp_ses_list) {
  253. server = list_entry(tmp1, struct TCP_Server_Info,
  254. tcp_ses_list);
  255. #ifdef CONFIG_CIFS_SMB_DIRECT
  256. if (!server->rdma)
  257. goto skip_rdma;
  258. if (!server->smbd_conn) {
  259. seq_printf(m, "\nSMBDirect transport not available");
  260. goto skip_rdma;
  261. }
  262. seq_printf(m, "\nSMBDirect (in hex) protocol version: %x "
  263. "transport status: %x",
  264. server->smbd_conn->protocol,
  265. server->smbd_conn->transport_status);
  266. seq_printf(m, "\nConn receive_credit_max: %x "
  267. "send_credit_target: %x max_send_size: %x",
  268. server->smbd_conn->receive_credit_max,
  269. server->smbd_conn->send_credit_target,
  270. server->smbd_conn->max_send_size);
  271. seq_printf(m, "\nConn max_fragmented_recv_size: %x "
  272. "max_fragmented_send_size: %x max_receive_size:%x",
  273. server->smbd_conn->max_fragmented_recv_size,
  274. server->smbd_conn->max_fragmented_send_size,
  275. server->smbd_conn->max_receive_size);
  276. seq_printf(m, "\nConn keep_alive_interval: %x "
  277. "max_readwrite_size: %x rdma_readwrite_threshold: %x",
  278. server->smbd_conn->keep_alive_interval,
  279. server->smbd_conn->max_readwrite_size,
  280. server->smbd_conn->rdma_readwrite_threshold);
  281. seq_printf(m, "\nDebug count_get_receive_buffer: %x "
  282. "count_put_receive_buffer: %x count_send_empty: %x",
  283. server->smbd_conn->count_get_receive_buffer,
  284. server->smbd_conn->count_put_receive_buffer,
  285. server->smbd_conn->count_send_empty);
  286. seq_printf(m, "\nRead Queue count_reassembly_queue: %x "
  287. "count_enqueue_reassembly_queue: %x "
  288. "count_dequeue_reassembly_queue: %x "
  289. "fragment_reassembly_remaining: %x "
  290. "reassembly_data_length: %x "
  291. "reassembly_queue_length: %x",
  292. server->smbd_conn->count_reassembly_queue,
  293. server->smbd_conn->count_enqueue_reassembly_queue,
  294. server->smbd_conn->count_dequeue_reassembly_queue,
  295. server->smbd_conn->fragment_reassembly_remaining,
  296. server->smbd_conn->reassembly_data_length,
  297. server->smbd_conn->reassembly_queue_length);
  298. seq_printf(m, "\nCurrent Credits send_credits: %x "
  299. "receive_credits: %x receive_credit_target: %x",
  300. atomic_read(&server->smbd_conn->send_credits),
  301. atomic_read(&server->smbd_conn->receive_credits),
  302. server->smbd_conn->receive_credit_target);
  303. seq_printf(m, "\nPending send_pending: %x ",
  304. atomic_read(&server->smbd_conn->send_pending));
  305. seq_printf(m, "\nReceive buffers count_receive_queue: %x "
  306. "count_empty_packet_queue: %x",
  307. server->smbd_conn->count_receive_queue,
  308. server->smbd_conn->count_empty_packet_queue);
  309. seq_printf(m, "\nMR responder_resources: %x "
  310. "max_frmr_depth: %x mr_type: %x",
  311. server->smbd_conn->responder_resources,
  312. server->smbd_conn->max_frmr_depth,
  313. server->smbd_conn->mr_type);
  314. seq_printf(m, "\nMR mr_ready_count: %x mr_used_count: %x",
  315. atomic_read(&server->smbd_conn->mr_ready_count),
  316. atomic_read(&server->smbd_conn->mr_used_count));
  317. skip_rdma:
  318. #endif
  319. seq_printf(m, "\nNumber of credits: %d Dialect 0x%x",
  320. server->credits, server->dialect);
  321. if (server->compress_algorithm == SMB3_COMPRESS_LZNT1)
  322. seq_printf(m, " COMPRESS_LZNT1");
  323. else if (server->compress_algorithm == SMB3_COMPRESS_LZ77)
  324. seq_printf(m, " COMPRESS_LZ77");
  325. else if (server->compress_algorithm == SMB3_COMPRESS_LZ77_HUFF)
  326. seq_printf(m, " COMPRESS_LZ77_HUFF");
  327. if (server->sign)
  328. seq_printf(m, " signed");
  329. if (server->posix_ext_supported)
  330. seq_printf(m, " posix");
  331. i++;
  332. list_for_each(tmp2, &server->smb_ses_list) {
  333. ses = list_entry(tmp2, struct cifs_ses,
  334. smb_ses_list);
  335. if ((ses->serverDomain == NULL) ||
  336. (ses->serverOS == NULL) ||
  337. (ses->serverNOS == NULL)) {
  338. seq_printf(m, "\n%d) Name: %s Uses: %d Capability: 0x%x\tSession Status: %d ",
  339. i, ses->serverName, ses->ses_count,
  340. ses->capabilities, ses->status);
  341. if (ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST)
  342. seq_printf(m, "Guest\t");
  343. else if (ses->session_flags & SMB2_SESSION_FLAG_IS_NULL)
  344. seq_printf(m, "Anonymous\t");
  345. } else {
  346. seq_printf(m,
  347. "\n%d) Name: %s Domain: %s Uses: %d OS:"
  348. " %s\n\tNOS: %s\tCapability: 0x%x\n\tSMB"
  349. " session status: %d ",
  350. i, ses->serverName, ses->serverDomain,
  351. ses->ses_count, ses->serverOS, ses->serverNOS,
  352. ses->capabilities, ses->status);
  353. }
  354. seq_printf(m,"Security type: %s\n",
  355. get_security_type_str(server->ops->select_sectype(server, ses->sectype)));
  356. if (server->rdma)
  357. seq_printf(m, "RDMA\n\t");
  358. seq_printf(m, "TCP status: %d Instance: %d\n\tLocal Users To "
  359. "Server: %d SecMode: 0x%x Req On Wire: %d",
  360. server->tcpStatus,
  361. server->reconnect_instance,
  362. server->srv_count,
  363. server->sec_mode, in_flight(server));
  364. seq_printf(m, " In Send: %d In MaxReq Wait: %d",
  365. atomic_read(&server->in_send),
  366. atomic_read(&server->num_waiters));
  367. /* dump session id helpful for use with network trace */
  368. seq_printf(m, " SessionId: 0x%llx", ses->Suid);
  369. if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
  370. seq_puts(m, " encrypted");
  371. if (ses->sign)
  372. seq_puts(m, " signed");
  373. seq_printf(m, "\n\tUser: %d Cred User: %d",
  374. from_kuid(&init_user_ns, ses->linux_uid),
  375. from_kuid(&init_user_ns, ses->cred_uid));
  376. if (ses->chan_count > 1) {
  377. seq_printf(m, "\n\n\tExtra Channels: %zu\n",
  378. ses->chan_count-1);
  379. for (j = 1; j < ses->chan_count; j++)
  380. cifs_dump_channel(m, j, &ses->chans[j]);
  381. }
  382. seq_puts(m, "\n\n\tShares:");
  383. j = 0;
  384. seq_printf(m, "\n\t%d) IPC: ", j);
  385. if (ses->tcon_ipc)
  386. cifs_debug_tcon(m, ses->tcon_ipc);
  387. else
  388. seq_puts(m, "none\n");
  389. list_for_each(tmp3, &ses->tcon_list) {
  390. tcon = list_entry(tmp3, struct cifs_tcon,
  391. tcon_list);
  392. ++j;
  393. seq_printf(m, "\n\t%d) ", j);
  394. cifs_debug_tcon(m, tcon);
  395. }
  396. seq_puts(m, "\n\tMIDs:\n");
  397. spin_lock(&GlobalMid_Lock);
  398. list_for_each(tmp3, &server->pending_mid_q) {
  399. mid_entry = list_entry(tmp3, struct mid_q_entry,
  400. qhead);
  401. seq_printf(m, "\tState: %d com: %d pid:"
  402. " %d cbdata: %p mid %llu\n",
  403. mid_entry->mid_state,
  404. le16_to_cpu(mid_entry->command),
  405. mid_entry->pid,
  406. mid_entry->callback_data,
  407. mid_entry->mid);
  408. }
  409. spin_unlock(&GlobalMid_Lock);
  410. spin_lock(&ses->iface_lock);
  411. if (ses->iface_count)
  412. seq_printf(m, "\n\tServer interfaces: %zu\n",
  413. ses->iface_count);
  414. for (j = 0; j < ses->iface_count; j++) {
  415. struct cifs_server_iface *iface;
  416. iface = &ses->iface_list[j];
  417. seq_printf(m, "\t%d)", j);
  418. cifs_dump_iface(m, iface);
  419. if (is_ses_using_iface(ses, iface))
  420. seq_puts(m, "\t\t[CONNECTED]\n");
  421. }
  422. spin_unlock(&ses->iface_lock);
  423. }
  424. }
  425. spin_unlock(&cifs_tcp_ses_lock);
  426. seq_putc(m, '\n');
  427. /* BB add code to dump additional info such as TCP session info now */
  428. return 0;
  429. }
  430. static ssize_t cifs_stats_proc_write(struct file *file,
  431. const char __user *buffer, size_t count, loff_t *ppos)
  432. {
  433. bool bv;
  434. int rc;
  435. struct list_head *tmp1, *tmp2, *tmp3;
  436. struct TCP_Server_Info *server;
  437. struct cifs_ses *ses;
  438. struct cifs_tcon *tcon;
  439. rc = kstrtobool_from_user(buffer, count, &bv);
  440. if (rc == 0) {
  441. #ifdef CONFIG_CIFS_STATS2
  442. int i;
  443. atomic_set(&totBufAllocCount, 0);
  444. atomic_set(&totSmBufAllocCount, 0);
  445. #endif /* CONFIG_CIFS_STATS2 */
  446. atomic_set(&tcpSesReconnectCount, 0);
  447. atomic_set(&tconInfoReconnectCount, 0);
  448. spin_lock(&GlobalMid_Lock);
  449. GlobalMaxActiveXid = 0;
  450. GlobalCurrentXid = 0;
  451. spin_unlock(&GlobalMid_Lock);
  452. spin_lock(&cifs_tcp_ses_lock);
  453. list_for_each(tmp1, &cifs_tcp_ses_list) {
  454. server = list_entry(tmp1, struct TCP_Server_Info,
  455. tcp_ses_list);
  456. server->max_in_flight = 0;
  457. #ifdef CONFIG_CIFS_STATS2
  458. for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
  459. atomic_set(&server->num_cmds[i], 0);
  460. atomic_set(&server->smb2slowcmd[i], 0);
  461. server->time_per_cmd[i] = 0;
  462. server->slowest_cmd[i] = 0;
  463. server->fastest_cmd[0] = 0;
  464. }
  465. #endif /* CONFIG_CIFS_STATS2 */
  466. list_for_each(tmp2, &server->smb_ses_list) {
  467. ses = list_entry(tmp2, struct cifs_ses,
  468. smb_ses_list);
  469. list_for_each(tmp3, &ses->tcon_list) {
  470. tcon = list_entry(tmp3,
  471. struct cifs_tcon,
  472. tcon_list);
  473. atomic_set(&tcon->num_smbs_sent, 0);
  474. spin_lock(&tcon->stat_lock);
  475. tcon->bytes_read = 0;
  476. tcon->bytes_written = 0;
  477. spin_unlock(&tcon->stat_lock);
  478. if (server->ops->clear_stats)
  479. server->ops->clear_stats(tcon);
  480. }
  481. }
  482. }
  483. spin_unlock(&cifs_tcp_ses_lock);
  484. } else {
  485. return rc;
  486. }
  487. return count;
  488. }
  489. static int cifs_stats_proc_show(struct seq_file *m, void *v)
  490. {
  491. int i;
  492. #ifdef CONFIG_CIFS_STATS2
  493. int j;
  494. #endif /* STATS2 */
  495. struct list_head *tmp1, *tmp2, *tmp3;
  496. struct TCP_Server_Info *server;
  497. struct cifs_ses *ses;
  498. struct cifs_tcon *tcon;
  499. seq_printf(m, "Resources in use\nCIFS Session: %d\n",
  500. sesInfoAllocCount.counter);
  501. seq_printf(m, "Share (unique mount targets): %d\n",
  502. tconInfoAllocCount.counter);
  503. seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n",
  504. bufAllocCount.counter,
  505. cifs_min_rcv + tcpSesAllocCount.counter);
  506. seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n",
  507. smBufAllocCount.counter, cifs_min_small);
  508. #ifdef CONFIG_CIFS_STATS2
  509. seq_printf(m, "Total Large %d Small %d Allocations\n",
  510. atomic_read(&totBufAllocCount),
  511. atomic_read(&totSmBufAllocCount));
  512. #endif /* CONFIG_CIFS_STATS2 */
  513. seq_printf(m, "Operations (MIDs): %d\n", atomic_read(&midCount));
  514. seq_printf(m,
  515. "\n%d session %d share reconnects\n",
  516. tcpSesReconnectCount.counter, tconInfoReconnectCount.counter);
  517. seq_printf(m,
  518. "Total vfs operations: %d maximum at one time: %d\n",
  519. GlobalCurrentXid, GlobalMaxActiveXid);
  520. i = 0;
  521. spin_lock(&cifs_tcp_ses_lock);
  522. list_for_each(tmp1, &cifs_tcp_ses_list) {
  523. server = list_entry(tmp1, struct TCP_Server_Info,
  524. tcp_ses_list);
  525. seq_printf(m, "\nMax requests in flight: %d", server->max_in_flight);
  526. #ifdef CONFIG_CIFS_STATS2
  527. seq_puts(m, "\nTotal time spent processing by command. Time ");
  528. seq_printf(m, "units are jiffies (%d per second)\n", HZ);
  529. seq_puts(m, " SMB3 CMD\tNumber\tTotal Time\tFastest\tSlowest\n");
  530. seq_puts(m, " --------\t------\t----------\t-------\t-------\n");
  531. for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++)
  532. seq_printf(m, " %d\t\t%d\t%llu\t\t%u\t%u\n", j,
  533. atomic_read(&server->num_cmds[j]),
  534. server->time_per_cmd[j],
  535. server->fastest_cmd[j],
  536. server->slowest_cmd[j]);
  537. for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++)
  538. if (atomic_read(&server->smb2slowcmd[j]))
  539. seq_printf(m, " %d slow responses from %s for command %d\n",
  540. atomic_read(&server->smb2slowcmd[j]),
  541. server->hostname, j);
  542. #endif /* STATS2 */
  543. list_for_each(tmp2, &server->smb_ses_list) {
  544. ses = list_entry(tmp2, struct cifs_ses,
  545. smb_ses_list);
  546. list_for_each(tmp3, &ses->tcon_list) {
  547. tcon = list_entry(tmp3,
  548. struct cifs_tcon,
  549. tcon_list);
  550. i++;
  551. seq_printf(m, "\n%d) %s", i, tcon->treeName);
  552. if (tcon->need_reconnect)
  553. seq_puts(m, "\tDISCONNECTED ");
  554. seq_printf(m, "\nSMBs: %d",
  555. atomic_read(&tcon->num_smbs_sent));
  556. if (server->ops->print_stats)
  557. server->ops->print_stats(m, tcon);
  558. }
  559. }
  560. }
  561. spin_unlock(&cifs_tcp_ses_lock);
  562. seq_putc(m, '\n');
  563. return 0;
  564. }
  565. static int cifs_stats_proc_open(struct inode *inode, struct file *file)
  566. {
  567. return single_open(file, cifs_stats_proc_show, NULL);
  568. }
  569. static const struct proc_ops cifs_stats_proc_ops = {
  570. .proc_open = cifs_stats_proc_open,
  571. .proc_read = seq_read,
  572. .proc_lseek = seq_lseek,
  573. .proc_release = single_release,
  574. .proc_write = cifs_stats_proc_write,
  575. };
  576. #ifdef CONFIG_CIFS_SMB_DIRECT
  577. #define PROC_FILE_DEFINE(name) \
  578. static ssize_t name##_write(struct file *file, const char __user *buffer, \
  579. size_t count, loff_t *ppos) \
  580. { \
  581. int rc; \
  582. rc = kstrtoint_from_user(buffer, count, 10, & name); \
  583. if (rc) \
  584. return rc; \
  585. return count; \
  586. } \
  587. static int name##_proc_show(struct seq_file *m, void *v) \
  588. { \
  589. seq_printf(m, "%d\n", name ); \
  590. return 0; \
  591. } \
  592. static int name##_open(struct inode *inode, struct file *file) \
  593. { \
  594. return single_open(file, name##_proc_show, NULL); \
  595. } \
  596. \
  597. static const struct proc_ops cifs_##name##_proc_fops = { \
  598. .proc_open = name##_open, \
  599. .proc_read = seq_read, \
  600. .proc_lseek = seq_lseek, \
  601. .proc_release = single_release, \
  602. .proc_write = name##_write, \
  603. }
  604. PROC_FILE_DEFINE(rdma_readwrite_threshold);
  605. PROC_FILE_DEFINE(smbd_max_frmr_depth);
  606. PROC_FILE_DEFINE(smbd_keep_alive_interval);
  607. PROC_FILE_DEFINE(smbd_max_receive_size);
  608. PROC_FILE_DEFINE(smbd_max_fragmented_recv_size);
  609. PROC_FILE_DEFINE(smbd_max_send_size);
  610. PROC_FILE_DEFINE(smbd_send_credit_target);
  611. PROC_FILE_DEFINE(smbd_receive_credit_max);
  612. #endif
  613. static struct proc_dir_entry *proc_fs_cifs;
  614. static const struct proc_ops cifsFYI_proc_ops;
  615. static const struct proc_ops cifs_lookup_cache_proc_ops;
  616. static const struct proc_ops traceSMB_proc_ops;
  617. static const struct proc_ops cifs_security_flags_proc_ops;
  618. static const struct proc_ops cifs_linux_ext_proc_ops;
  619. void
  620. cifs_proc_init(void)
  621. {
  622. proc_fs_cifs = proc_mkdir("fs/cifs", NULL);
  623. if (proc_fs_cifs == NULL)
  624. return;
  625. proc_create_single("DebugData", 0, proc_fs_cifs,
  626. cifs_debug_data_proc_show);
  627. proc_create_single("open_files", 0400, proc_fs_cifs,
  628. cifs_debug_files_proc_show);
  629. proc_create("Stats", 0644, proc_fs_cifs, &cifs_stats_proc_ops);
  630. proc_create("cifsFYI", 0644, proc_fs_cifs, &cifsFYI_proc_ops);
  631. proc_create("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_ops);
  632. proc_create("LinuxExtensionsEnabled", 0644, proc_fs_cifs,
  633. &cifs_linux_ext_proc_ops);
  634. proc_create("SecurityFlags", 0644, proc_fs_cifs,
  635. &cifs_security_flags_proc_ops);
  636. proc_create("LookupCacheEnabled", 0644, proc_fs_cifs,
  637. &cifs_lookup_cache_proc_ops);
  638. #ifdef CONFIG_CIFS_DFS_UPCALL
  639. proc_create("dfscache", 0644, proc_fs_cifs, &dfscache_proc_ops);
  640. #endif
  641. #ifdef CONFIG_CIFS_SMB_DIRECT
  642. proc_create("rdma_readwrite_threshold", 0644, proc_fs_cifs,
  643. &cifs_rdma_readwrite_threshold_proc_fops);
  644. proc_create("smbd_max_frmr_depth", 0644, proc_fs_cifs,
  645. &cifs_smbd_max_frmr_depth_proc_fops);
  646. proc_create("smbd_keep_alive_interval", 0644, proc_fs_cifs,
  647. &cifs_smbd_keep_alive_interval_proc_fops);
  648. proc_create("smbd_max_receive_size", 0644, proc_fs_cifs,
  649. &cifs_smbd_max_receive_size_proc_fops);
  650. proc_create("smbd_max_fragmented_recv_size", 0644, proc_fs_cifs,
  651. &cifs_smbd_max_fragmented_recv_size_proc_fops);
  652. proc_create("smbd_max_send_size", 0644, proc_fs_cifs,
  653. &cifs_smbd_max_send_size_proc_fops);
  654. proc_create("smbd_send_credit_target", 0644, proc_fs_cifs,
  655. &cifs_smbd_send_credit_target_proc_fops);
  656. proc_create("smbd_receive_credit_max", 0644, proc_fs_cifs,
  657. &cifs_smbd_receive_credit_max_proc_fops);
  658. #endif
  659. }
  660. void
  661. cifs_proc_clean(void)
  662. {
  663. if (proc_fs_cifs == NULL)
  664. return;
  665. remove_proc_entry("DebugData", proc_fs_cifs);
  666. remove_proc_entry("open_files", proc_fs_cifs);
  667. remove_proc_entry("cifsFYI", proc_fs_cifs);
  668. remove_proc_entry("traceSMB", proc_fs_cifs);
  669. remove_proc_entry("Stats", proc_fs_cifs);
  670. remove_proc_entry("SecurityFlags", proc_fs_cifs);
  671. remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
  672. remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
  673. #ifdef CONFIG_CIFS_DFS_UPCALL
  674. remove_proc_entry("dfscache", proc_fs_cifs);
  675. #endif
  676. #ifdef CONFIG_CIFS_SMB_DIRECT
  677. remove_proc_entry("rdma_readwrite_threshold", proc_fs_cifs);
  678. remove_proc_entry("smbd_max_frmr_depth", proc_fs_cifs);
  679. remove_proc_entry("smbd_keep_alive_interval", proc_fs_cifs);
  680. remove_proc_entry("smbd_max_receive_size", proc_fs_cifs);
  681. remove_proc_entry("smbd_max_fragmented_recv_size", proc_fs_cifs);
  682. remove_proc_entry("smbd_max_send_size", proc_fs_cifs);
  683. remove_proc_entry("smbd_send_credit_target", proc_fs_cifs);
  684. remove_proc_entry("smbd_receive_credit_max", proc_fs_cifs);
  685. #endif
  686. remove_proc_entry("fs/cifs", NULL);
  687. }
  688. static int cifsFYI_proc_show(struct seq_file *m, void *v)
  689. {
  690. seq_printf(m, "%d\n", cifsFYI);
  691. return 0;
  692. }
  693. static int cifsFYI_proc_open(struct inode *inode, struct file *file)
  694. {
  695. return single_open(file, cifsFYI_proc_show, NULL);
  696. }
  697. static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
  698. size_t count, loff_t *ppos)
  699. {
  700. char c[2] = { '\0' };
  701. bool bv;
  702. int rc;
  703. rc = get_user(c[0], buffer);
  704. if (rc)
  705. return rc;
  706. if (strtobool(c, &bv) == 0)
  707. cifsFYI = bv;
  708. else if ((c[0] > '1') && (c[0] <= '9'))
  709. cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for meanings */
  710. else
  711. return -EINVAL;
  712. return count;
  713. }
  714. static const struct proc_ops cifsFYI_proc_ops = {
  715. .proc_open = cifsFYI_proc_open,
  716. .proc_read = seq_read,
  717. .proc_lseek = seq_lseek,
  718. .proc_release = single_release,
  719. .proc_write = cifsFYI_proc_write,
  720. };
  721. static int cifs_linux_ext_proc_show(struct seq_file *m, void *v)
  722. {
  723. seq_printf(m, "%d\n", linuxExtEnabled);
  724. return 0;
  725. }
  726. static int cifs_linux_ext_proc_open(struct inode *inode, struct file *file)
  727. {
  728. return single_open(file, cifs_linux_ext_proc_show, NULL);
  729. }
  730. static ssize_t cifs_linux_ext_proc_write(struct file *file,
  731. const char __user *buffer, size_t count, loff_t *ppos)
  732. {
  733. int rc;
  734. rc = kstrtobool_from_user(buffer, count, &linuxExtEnabled);
  735. if (rc)
  736. return rc;
  737. return count;
  738. }
  739. static const struct proc_ops cifs_linux_ext_proc_ops = {
  740. .proc_open = cifs_linux_ext_proc_open,
  741. .proc_read = seq_read,
  742. .proc_lseek = seq_lseek,
  743. .proc_release = single_release,
  744. .proc_write = cifs_linux_ext_proc_write,
  745. };
  746. static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v)
  747. {
  748. seq_printf(m, "%d\n", lookupCacheEnabled);
  749. return 0;
  750. }
  751. static int cifs_lookup_cache_proc_open(struct inode *inode, struct file *file)
  752. {
  753. return single_open(file, cifs_lookup_cache_proc_show, NULL);
  754. }
  755. static ssize_t cifs_lookup_cache_proc_write(struct file *file,
  756. const char __user *buffer, size_t count, loff_t *ppos)
  757. {
  758. int rc;
  759. rc = kstrtobool_from_user(buffer, count, &lookupCacheEnabled);
  760. if (rc)
  761. return rc;
  762. return count;
  763. }
  764. static const struct proc_ops cifs_lookup_cache_proc_ops = {
  765. .proc_open = cifs_lookup_cache_proc_open,
  766. .proc_read = seq_read,
  767. .proc_lseek = seq_lseek,
  768. .proc_release = single_release,
  769. .proc_write = cifs_lookup_cache_proc_write,
  770. };
  771. static int traceSMB_proc_show(struct seq_file *m, void *v)
  772. {
  773. seq_printf(m, "%d\n", traceSMB);
  774. return 0;
  775. }
  776. static int traceSMB_proc_open(struct inode *inode, struct file *file)
  777. {
  778. return single_open(file, traceSMB_proc_show, NULL);
  779. }
  780. static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer,
  781. size_t count, loff_t *ppos)
  782. {
  783. int rc;
  784. rc = kstrtobool_from_user(buffer, count, &traceSMB);
  785. if (rc)
  786. return rc;
  787. return count;
  788. }
  789. static const struct proc_ops traceSMB_proc_ops = {
  790. .proc_open = traceSMB_proc_open,
  791. .proc_read = seq_read,
  792. .proc_lseek = seq_lseek,
  793. .proc_release = single_release,
  794. .proc_write = traceSMB_proc_write,
  795. };
  796. static int cifs_security_flags_proc_show(struct seq_file *m, void *v)
  797. {
  798. seq_printf(m, "0x%x\n", global_secflags);
  799. return 0;
  800. }
  801. static int cifs_security_flags_proc_open(struct inode *inode, struct file *file)
  802. {
  803. return single_open(file, cifs_security_flags_proc_show, NULL);
  804. }
  805. /*
  806. * Ensure that if someone sets a MUST flag, that we disable all other MAY
  807. * flags except for the ones corresponding to the given MUST flag. If there are
  808. * multiple MUST flags, then try to prefer more secure ones.
  809. */
  810. static void
  811. cifs_security_flags_handle_must_flags(unsigned int *flags)
  812. {
  813. unsigned int signflags = *flags & CIFSSEC_MUST_SIGN;
  814. if ((*flags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
  815. *flags = CIFSSEC_MUST_KRB5;
  816. else if ((*flags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
  817. *flags = CIFSSEC_MUST_NTLMSSP;
  818. else if ((*flags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
  819. *flags = CIFSSEC_MUST_NTLMV2;
  820. else if ((*flags & CIFSSEC_MUST_NTLM) == CIFSSEC_MUST_NTLM)
  821. *flags = CIFSSEC_MUST_NTLM;
  822. else if (CIFSSEC_MUST_LANMAN &&
  823. (*flags & CIFSSEC_MUST_LANMAN) == CIFSSEC_MUST_LANMAN)
  824. *flags = CIFSSEC_MUST_LANMAN;
  825. else if (CIFSSEC_MUST_PLNTXT &&
  826. (*flags & CIFSSEC_MUST_PLNTXT) == CIFSSEC_MUST_PLNTXT)
  827. *flags = CIFSSEC_MUST_PLNTXT;
  828. *flags |= signflags;
  829. }
  830. static ssize_t cifs_security_flags_proc_write(struct file *file,
  831. const char __user *buffer, size_t count, loff_t *ppos)
  832. {
  833. int rc;
  834. unsigned int flags;
  835. char flags_string[12];
  836. bool bv;
  837. if ((count < 1) || (count > 11))
  838. return -EINVAL;
  839. memset(flags_string, 0, 12);
  840. if (copy_from_user(flags_string, buffer, count))
  841. return -EFAULT;
  842. if (count < 3) {
  843. /* single char or single char followed by null */
  844. if (strtobool(flags_string, &bv) == 0) {
  845. global_secflags = bv ? CIFSSEC_MAX : CIFSSEC_DEF;
  846. return count;
  847. } else if (!isdigit(flags_string[0])) {
  848. cifs_dbg(VFS, "Invalid SecurityFlags: %s\n",
  849. flags_string);
  850. return -EINVAL;
  851. }
  852. }
  853. /* else we have a number */
  854. rc = kstrtouint(flags_string, 0, &flags);
  855. if (rc) {
  856. cifs_dbg(VFS, "Invalid SecurityFlags: %s\n",
  857. flags_string);
  858. return rc;
  859. }
  860. cifs_dbg(FYI, "sec flags 0x%x\n", flags);
  861. if (flags == 0) {
  862. cifs_dbg(VFS, "Invalid SecurityFlags: %s\n", flags_string);
  863. return -EINVAL;
  864. }
  865. if (flags & ~CIFSSEC_MASK) {
  866. cifs_dbg(VFS, "Unsupported security flags: 0x%x\n",
  867. flags & ~CIFSSEC_MASK);
  868. return -EINVAL;
  869. }
  870. cifs_security_flags_handle_must_flags(&flags);
  871. /* flags look ok - update the global security flags for cifs module */
  872. global_secflags = flags;
  873. if (global_secflags & CIFSSEC_MUST_SIGN) {
  874. /* requiring signing implies signing is allowed */
  875. global_secflags |= CIFSSEC_MAY_SIGN;
  876. cifs_dbg(FYI, "packet signing now required\n");
  877. } else if ((global_secflags & CIFSSEC_MAY_SIGN) == 0) {
  878. cifs_dbg(FYI, "packet signing disabled\n");
  879. }
  880. /* BB should we turn on MAY flags for other MUST options? */
  881. return count;
  882. }
  883. static const struct proc_ops cifs_security_flags_proc_ops = {
  884. .proc_open = cifs_security_flags_proc_open,
  885. .proc_read = seq_read,
  886. .proc_lseek = seq_lseek,
  887. .proc_release = single_release,
  888. .proc_write = cifs_security_flags_proc_write,
  889. };
  890. #else
  891. inline void cifs_proc_init(void)
  892. {
  893. }
  894. inline void cifs_proc_clean(void)
  895. {
  896. }
  897. #endif /* PROC_FS */