Commit b38f99c1 authored by Bahubali B Gumaji's avatar Bahubali B Gumaji Committed by Steve French
Browse files

ksmbd: add procfs interface for runtime monitoring and statistics



This patch introduces a /proc filesystem interface to ksmbd, providing
visibility into the internal state of the SMB server. This allows
administrators and developers to monitor active connections, user
sessions, and opened files in real-time without relying on external
tools or heavy debugging.

Key changes include:
 - Connection Monitoring (/proc/fs/ksmbd/clients): Displays a list of
   active network connections, including client IP addresses, SMB dialects,
   credits, and last active timestamps.

 - Session Management (/proc/fs/ksmbd/sessions/): Adds a global sessions
   file to list all authenticated users and their session IDs.

 - Creates individual session entries (e.g., /proc/fs/ksmbd/sessions/<id>)
   detailing capabilities (DFS, Multi-channel, etc.), signing/encryption
   algorithms, and connected tree shares.

 - File Tracking (/proc/fs/ksmbd/files): Shows all currently opened files
   across the server, including tree IDs, process IDs (PID), access modes
   (daccess/saccess), and oplock/lease states.

 - Statistics & Counters: Implements internal counters for global server
   metrics, such as the number of tree connections, total sessions, and
   processed read/write bytes.

Signed-off-by: default avatarHyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: default avatarBahubali B Gumaji <bahubali.bg@samsung.com>
Signed-off-by: default avatarSang-Soo Lee <constant.lee@samsung.com>
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 010eb01c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -18,3 +18,4 @@ $(obj)/ksmbd_spnego_negtokeninit.asn1.o: $(obj)/ksmbd_spnego_negtokeninit.asn1.c
$(obj)/ksmbd_spnego_negtokentarg.asn1.o: $(obj)/ksmbd_spnego_negtokentarg.asn1.c $(obj)/ksmbd_spnego_negtokentarg.asn1.h

ksmbd-$(CONFIG_SMB_SERVER_SMBDIRECT) += transport_rdma.o
ksmbd-$(CONFIG_PROC_FS) += proc.o
+57 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include "connection.h"
#include "transport_tcp.h"
#include "transport_rdma.h"
#include "misc.h"

static DEFINE_MUTEX(init_lock);

@@ -22,6 +23,60 @@ static struct ksmbd_conn_ops default_conn_ops;
DEFINE_HASHTABLE(conn_list, CONN_HASH_BITS);
DECLARE_RWSEM(conn_list_lock);

#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *proc_clients;

static int proc_show_clients(struct seq_file *m, void *v)
{
	struct ksmbd_conn *conn;
	struct timespec64 now, t;
	int i;

	seq_printf(m, "#%-20s %-10s %-10s %-10s %-10s %-10s\n",
			"<name>", "<dialect>", "<credits>", "<open files>",
			"<requests>", "<last active>");

	down_read(&conn_list_lock);
	hash_for_each(conn_list, i, conn, hlist) {
		jiffies_to_timespec64(jiffies - conn->last_active, &t);
		ktime_get_real_ts64(&now);
		t = timespec64_sub(now, t);
		if (conn->inet_addr)
			seq_printf(m, "%-20pI4", &conn->inet_addr);
		else
			seq_printf(m, "%-20pI6c", &conn->inet6_addr);
		seq_printf(m, "   0x%-10x %-10u %-12d %-10d %ptT\n",
			   conn->dialect,
			   conn->total_credits,
			   atomic_read(&conn->stats.open_files_count),
			   atomic_read(&conn->req_running),
			   &t);
	}
	up_read(&conn_list_lock);
	return 0;
}

static int create_proc_clients(void)
{
	proc_clients = ksmbd_proc_create("clients",
					 proc_show_clients, NULL);
	if (!proc_clients)
		return -ENOMEM;
	return 0;
}

static void delete_proc_clients(void)
{
	if (proc_clients) {
		proc_remove(proc_clients);
		proc_clients = NULL;
	}
}
#else
static int create_proc_clients(void) { return 0; }
static void delete_proc_clients(void) {}
#endif

/**
 * ksmbd_conn_free() - free resources of the connection instance
 *
@@ -472,6 +527,7 @@ int ksmbd_conn_transport_init(void)
	}
out:
	mutex_unlock(&init_lock);
	create_proc_clients();
	return ret;
}

@@ -502,6 +558,7 @@ static void stop_sessions(void)

void ksmbd_conn_transport_destroy(void)
{
	delete_proc_clients();
	mutex_lock(&init_lock);
	ksmbd_tcp_destroy();
	ksmbd_rdma_stop_listening();
+3 −2
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
#define __KSMBD_CONNECTION_H__

#include <linux/list.h>
#include <linux/inet.h>
#include <linux/ip.h>
#include <net/sock.h>
#include <net/tcp.h>
@@ -33,7 +34,7 @@ enum {
	KSMBD_SESS_RELEASING
};

struct ksmbd_stats {
struct ksmbd_conn_stats {
	atomic_t			open_files_count;
	atomic64_t			request_served;
};
@@ -78,7 +79,7 @@ struct ksmbd_conn {
	struct list_head		requests;
	struct list_head		async_requests;
	int				connection_type;
	struct ksmbd_stats		stats;
	struct ksmbd_conn_stats		stats;
	char				ClientGUID[SMB2_CLIENT_GUID_SIZE];
	struct ntlmssp_auth		ntlmssp;

+3 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@

#include "../transport_ipc.h"
#include "../connection.h"
#include "../stats.h"

#include "tree_connect.h"
#include "user_config.h"
@@ -85,6 +86,7 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name)
		status.ret = -ENOMEM;
		goto out_error;
	}
	ksmbd_counter_inc(KSMBD_COUNTER_TREE_CONNS);
	kvfree(resp);
	return status;

@@ -115,6 +117,7 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
	ret = ksmbd_ipc_tree_disconnect_request(sess->id, tree_conn->id);
	ksmbd_release_tree_conn_id(sess, tree_conn->id);
	ksmbd_share_config_put(tree_conn->share_conf);
	ksmbd_counter_dec(KSMBD_COUNTER_TREE_CONNS);
	if (atomic_dec_and_test(&tree_conn->refcount))
		kfree(tree_conn);
	return ret;
+2 −4
Original line number Diff line number Diff line
@@ -90,11 +90,9 @@ void ksmbd_free_user(struct ksmbd_user *user)
	kfree(user);
}

int ksmbd_anonymous_user(struct ksmbd_user *user)
bool ksmbd_anonymous_user(struct ksmbd_user *user)
{
	if (user->name[0] == '\0')
		return 1;
	return 0;
	return user->name[0] == '\0';
}

bool ksmbd_compare_user(struct ksmbd_user *u1, struct ksmbd_user *u2)
Loading