Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
19static struct proc_dir_entry *ksmbd_proc_fs;
20struct ksmbd_counters ksmbd_counters;
21
22struct 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
30struct ksmbd_const_smb2_process_req {
31 unsigned int const_value;
32 const char *name;
33};
34
35static 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
57static 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
86void 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
101void 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
109void 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;
132err_out:
133 ksmbd_proc_cleanup();
134}