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