1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2025, LG Electronics. 4 * Author(s): Hyunchul Lee <hyc.lee@gmail.com> 5 * Copyright (C) 2025, Samsung Electronics. 6 * Author(s): Vedansh Bhardwaj <v.bhardwaj@samsung.com> 7 */ 8 9 #include <linux/module.h> 10 #include <linux/proc_fs.h> 11 #include <linux/seq_file.h> 12 13 #include "misc.h" 14 #include "server.h" 15 #include "stats.h" 16 #include "smb_common.h" 17 #include "smb2pdu.h" 18 19 static struct proc_dir_entry *ksmbd_proc_fs; 20 struct ksmbd_counters ksmbd_counters; 21 22 struct proc_dir_entry *ksmbd_proc_create(const char *name, 23 int (*show)(struct seq_file *m, void *v), 24 void *v) 25 { 26 return proc_create_single_data(name, 0400, ksmbd_proc_fs, 27 show, v); 28 } 29 30 struct ksmbd_const_smb2_process_req { 31 unsigned int const_value; 32 const char *name; 33 }; 34 35 static const struct ksmbd_const_smb2_process_req smb2_process_req[KSMBD_COUNTER_MAX_REQS] = { 36 {le16_to_cpu(SMB2_NEGOTIATE), "SMB2_NEGOTIATE"}, 37 {le16_to_cpu(SMB2_SESSION_SETUP), "SMB2_SESSION_SETUP"}, 38 {le16_to_cpu(SMB2_LOGOFF), "SMB2_LOGOFF"}, 39 {le16_to_cpu(SMB2_TREE_CONNECT), "SMB2_TREE_CONNECT"}, 40 {le16_to_cpu(SMB2_TREE_DISCONNECT), "SMB2_TREE_DISCONNECT"}, 41 {le16_to_cpu(SMB2_CREATE), "SMB2_CREATE"}, 42 {le16_to_cpu(SMB2_CLOSE), "SMB2_CLOSE"}, 43 {le16_to_cpu(SMB2_FLUSH), "SMB2_FLUSH"}, 44 {le16_to_cpu(SMB2_READ), "SMB2_READ"}, 45 {le16_to_cpu(SMB2_WRITE), "SMB2_WRITE"}, 46 {le16_to_cpu(SMB2_LOCK), "SMB2_LOCK"}, 47 {le16_to_cpu(SMB2_IOCTL), "SMB2_IOCTL"}, 48 {le16_to_cpu(SMB2_CANCEL), "SMB2_CANCEL"}, 49 {le16_to_cpu(SMB2_ECHO), "SMB2_ECHO"}, 50 {le16_to_cpu(SMB2_QUERY_DIRECTORY), "SMB2_QUERY_DIRECTORY"}, 51 {le16_to_cpu(SMB2_CHANGE_NOTIFY), "SMB2_CHANGE_NOTIFY"}, 52 {le16_to_cpu(SMB2_QUERY_INFO), "SMB2_QUERY_INFO"}, 53 {le16_to_cpu(SMB2_SET_INFO), "SMB2_SET_INFO"}, 54 {le16_to_cpu(SMB2_OPLOCK_BREAK), "SMB2_OPLOCK_BREAK"}, 55 }; 56 57 static int proc_show_ksmbd_stats(struct seq_file *m, void *v) 58 { 59 int i; 60 61 seq_puts(m, "Server\n"); 62 seq_printf(m, "name: %s\n", ksmbd_server_string()); 63 seq_printf(m, "netbios: %s\n", ksmbd_netbios_name()); 64 seq_printf(m, "work group: %s\n", ksmbd_work_group()); 65 seq_printf(m, "min protocol: %s\n", ksmbd_get_protocol_string(server_conf.min_protocol)); 66 seq_printf(m, "max protocol: %s\n", ksmbd_get_protocol_string(server_conf.max_protocol)); 67 seq_printf(m, "flags: 0x%08x\n", server_conf.flags); 68 seq_printf(m, "share_fake_fscaps: 0x%08x\n", 69 server_conf.share_fake_fscaps); 70 seq_printf(m, "sessions: %lld\n", 71 ksmbd_counter_sum(KSMBD_COUNTER_SESSIONS)); 72 seq_printf(m, "tree connects: %lld\n", 73 ksmbd_counter_sum(KSMBD_COUNTER_TREE_CONNS)); 74 seq_printf(m, "read bytes: %lld\n", 75 ksmbd_counter_sum(KSMBD_COUNTER_READ_BYTES)); 76 seq_printf(m, "written bytes: %lld\n", 77 ksmbd_counter_sum(KSMBD_COUNTER_WRITE_BYTES)); 78 79 seq_puts(m, "\nSMB2\n"); 80 for (i = 0; i < KSMBD_COUNTER_MAX_REQS; i++) 81 seq_printf(m, "%-20s:\t%lld\n", smb2_process_req[i].name, 82 ksmbd_counter_sum(KSMBD_COUNTER_FIRST_REQ + i)); 83 return 0; 84 } 85 86 void ksmbd_proc_cleanup(void) 87 { 88 int i; 89 90 if (!ksmbd_proc_fs) 91 return; 92 93 proc_remove(ksmbd_proc_fs); 94 95 for (i = 0; i < ARRAY_SIZE(ksmbd_counters.counters); i++) 96 percpu_counter_destroy(&ksmbd_counters.counters[i]); 97 98 ksmbd_proc_fs = NULL; 99 } 100 101 void ksmbd_proc_reset(void) 102 { 103 int i; 104 105 for (i = 0; i < ARRAY_SIZE(ksmbd_counters.counters); i++) 106 percpu_counter_set(&ksmbd_counters.counters[i], 0); 107 } 108 109 void ksmbd_proc_init(void) 110 { 111 int i; 112 int retval; 113 114 ksmbd_proc_fs = proc_mkdir("fs/ksmbd", NULL); 115 if (!ksmbd_proc_fs) 116 return; 117 118 if (!proc_mkdir_mode("sessions", 0400, ksmbd_proc_fs)) 119 goto err_out; 120 121 for (i = 0; i < ARRAY_SIZE(ksmbd_counters.counters); i++) { 122 retval = percpu_counter_init(&ksmbd_counters.counters[i], 0, GFP_KERNEL); 123 if (retval) 124 goto err_out; 125 } 126 127 if (!ksmbd_proc_create("server", proc_show_ksmbd_stats, NULL)) 128 goto err_out; 129 130 ksmbd_proc_reset(); 131 return; 132 err_out: 133 ksmbd_proc_cleanup(); 134 } 135