From: Namjae Jeon <linkinjeon@kernel.org>
To: linux-cifs@vger.kernel.org
Cc: smfrench@gmail.com, senozhatsky@chromium.org, tom@talpey.com,
atteh.mailbox@gmail.com, Namjae Jeon <linkinjeon@kernel.org>
Subject: [PATCH 5/7] ksmbd: report session and open file details in procfs
Date: Thu, 16 Jul 2026 18:57:08 +0900 [thread overview]
Message-ID: <20260716095711.6228-5-linkinjeon@kernel.org> (raw)
In-Reply-To: <20260716095711.6228-1-linkinjeon@kernel.org>
Session and file proc entries lack the state needed to correlate inactive
sessions with durable or delete-pending opens.
Add the account type, dialect, idle time, open-file count, tree-connect
count, and per-channel POSIX negotiation state to session entries. Extend
the open-file table with the file state, durable timeout, create options,
share access, and descriptive flags for durable, persistent, resilient,
delete-on-close, stream, POSIX, and attribute-only opens.
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
---
fs/smb/server/mgmt/user_session.c | 82 ++++++++++++++++++++----------
fs/smb/server/vfs_cache.c | 84 +++++++++++++++++++++++++------
2 files changed, 123 insertions(+), 43 deletions(-)
diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
index 09c944a67141..b2bc8119984f 100644
--- a/fs/smb/server/mgmt/user_session.c
+++ b/fs/smb/server/mgmt/user_session.c
@@ -78,6 +78,28 @@ static const char *session_user_name(struct ksmbd_session *session)
return session->user->name;
}
+static const char *session_account_type(struct ksmbd_session *session)
+{
+ if (user_guest(session->user))
+ return "guest";
+ if (ksmbd_anonymous_user(session->user))
+ return "anonymous";
+ return "user";
+}
+
+static unsigned int session_open_file_count(struct ksmbd_session *session)
+{
+ struct ksmbd_file *fp;
+ unsigned int count = 0;
+ unsigned int id;
+
+ read_lock(&session->file_table.lock);
+ idr_for_each_entry(session->file_table.idr, fp, id)
+ count++;
+ read_unlock(&session->file_table.lock);
+ return count;
+}
+
static int show_proc_session(struct seq_file *m, void *v)
{
struct ksmbd_session *sess;
@@ -90,9 +112,16 @@ static int show_proc_session(struct seq_file *m, void *v)
sess = (struct ksmbd_session *)m->private;
ksmbd_user_session_get(sess);
- seq_printf(m, "%-20s\t%s\n", "user", session_user_name(sess));
- seq_printf(m, "%-20s\t%llu\n", "id", sess->id);
- seq_printf(m, "%-20s\t%s\n", "state", session_state_string(sess));
+ seq_printf(m, "user:\t%s\n", session_user_name(sess));
+ seq_printf(m, "account_type:\t%s\n",
+ session_account_type(sess));
+ seq_printf(m, "id:\t%llu\n", sess->id);
+ seq_printf(m, "state:\t%s\n", session_state_string(sess));
+ seq_printf(m, "dialect:\t0x%04x\n", sess->dialect);
+ seq_printf(m, "last_active_seconds:\t%lu\n",
+ jiffies_to_msecs(jiffies - sess->last_active) / MSEC_PER_SEC);
+ seq_printf(m, "open_files:\t%u\n",
+ session_open_file_count(sess));
i = 0;
down_read(&sess->chann_lock);
@@ -101,21 +130,23 @@ static int show_proc_session(struct seq_file *m, void *v)
#if IS_ENABLED(CONFIG_IPV6)
if (chan->conn->inet_addr)
- seq_printf(m, "%-20s\t%pI4\n", "client",
+ seq_printf(m, "client:\t%pI4\n",
&chan->conn->inet_addr);
else
- seq_printf(m, "%-20s\t%pI6c\n", "client",
+ seq_printf(m, "client:\t%pI6c\n",
&chan->conn->inet6_addr);
#else
- seq_printf(m, "%-20s\t%pI4\n", "client",
+ seq_printf(m, "client:\t%pI4\n",
&chan->conn->inet_addr);
#endif
- seq_printf(m, "%-20s\t", "capabilities");
+ seq_puts(m, "capabilities:\t");
ksmbd_proc_show_flag_names(m,
ksmbd_sess_cap_const_names,
ARRAY_SIZE(ksmbd_sess_cap_const_names),
chan->conn->vals->req_capabilities);
seq_putc(m, '\n');
+ seq_printf(m, "posix_extensions:\t%s\n",
+ chan->conn->posix_ext_supported ? "yes" : "no");
if (sess->sign) {
unsigned int algorithm =
@@ -125,9 +156,9 @@ static int show_proc_session(struct seq_file *m, void *v)
ARRAY_SIZE(ksmbd_signing_const_names),
algorithm);
if (name)
- seq_printf(m, "%-20s\t%s\n", "signing", name);
+ seq_printf(m, "signing:\t%s\n", name);
else
- seq_printf(m, "%-20s\t0x%04x\n", "signing",
+ seq_printf(m, "signing:\t0x%04x\n",
algorithm);
}
if (sess->enc) {
@@ -137,30 +168,30 @@ static int show_proc_session(struct seq_file *m, void *v)
ARRAY_SIZE(ksmbd_cipher_const_names),
cipher);
if (name)
- seq_printf(m, "%-20s\t%s\n", "encryption", name);
+ seq_printf(m, "encryption:\t%s\n", name);
else
- seq_printf(m, "%-20s\t0x%04x\n", "encryption",
+ seq_printf(m, "encryption:\t0x%04x\n",
cipher);
}
i++;
}
up_read(&sess->chann_lock);
- seq_printf(m, "%-20s\t%d\n", "channels", i);
+ seq_printf(m, "channels:\t%d\n", i);
i = 0;
down_read(&sess->tree_conns_lock);
xa_for_each(&sess->tree_conns, id, tree_conn) {
share_conf = tree_conn->share_conf;
- seq_printf(m, "%-20s\t%s\t%8d", "share",
- share_conf->name, tree_conn->id);
- if (test_share_config_flag(share_conf, KSMBD_SHARE_FLAG_PIPE))
- seq_printf(m, " %s ", "pipe");
- else
- seq_printf(m, " %s ", "disk");
- seq_putc(m, '\n');
+ seq_printf(m, "share:\t%s\n", share_conf->name);
+ seq_printf(m, "tree_id:\t%d\n", tree_conn->id);
+ seq_printf(m, "share_type:\t%s\n",
+ test_share_config_flag(share_conf, KSMBD_SHARE_FLAG_PIPE) ?
+ "pipe" : "disk");
+ i++;
}
up_read(&sess->tree_conns_lock);
+ seq_printf(m, "tree_connects:\t%d\n", i);
ksmbd_user_session_put(sess);
return 0;
@@ -189,9 +220,6 @@ static int show_proc_sessions(struct seq_file *m, void *v)
int i;
unsigned long id;
- seq_printf(m, "#%-40s %-15s %-10s %-10s\n",
- "<client>", "<user>", "<sess_id>", "<state>");
-
down_read(&sessions_table_lock);
hash_for_each(sessions_table, i, session, hlist) {
down_read(&session->chann_lock);
@@ -201,13 +229,13 @@ static int show_proc_sessions(struct seq_file *m, void *v)
#if IS_ENABLED(CONFIG_IPV6)
if (!chan->conn->inet_addr)
- seq_printf(m, " %-40pI6c", &chan->conn->inet6_addr);
+ seq_printf(m, "client:\t%pI6c\n", &chan->conn->inet6_addr);
else
#endif
- seq_printf(m, " %-40pI4", &chan->conn->inet_addr);
- seq_printf(m, " %-15s %-10llu %-10s\n",
- session_user_name(session),
- session->id,
+ seq_printf(m, "client:\t%pI4\n", &chan->conn->inet_addr);
+ seq_printf(m, "user:\t%s\n", session_user_name(session));
+ seq_printf(m, "id:\t%llu\n", session->id);
+ seq_printf(m, "state:\t%s\n\n",
session_state_string(session));
ksmbd_user_session_put(session);
diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
index c867cf32ae9c..5c1929a81234 100644
--- a/fs/smb/server/vfs_cache.c
+++ b/fs/smb/server/vfs_cache.c
@@ -70,24 +70,63 @@ static const struct ksmbd_const_name ksmbd_oplock_const_names[] = {
{SMB2_OPLOCK_LEVEL_BATCH, "OPLOCK_BATCH"},
};
+static const struct ksmbd_const_name ksmbd_file_state_names[] = {
+ {FP_NEW, "new"},
+ {FP_INITED, "open"},
+ {FP_CLOSED, "closed"},
+};
+
+#define KSMBD_PROC_FILE_DURABLE BIT(0)
+#define KSMBD_PROC_FILE_PERSISTENT BIT(1)
+#define KSMBD_PROC_FILE_RESILIENT BIT(2)
+#define KSMBD_PROC_FILE_DELETE_ON_CLOSE BIT(3)
+#define KSMBD_PROC_FILE_STREAM BIT(4)
+#define KSMBD_PROC_FILE_POSIX BIT(5)
+#define KSMBD_PROC_FILE_ATTRIB_ONLY BIT(6)
+
+static const struct ksmbd_const_name ksmbd_file_flag_names[] = {
+ {KSMBD_PROC_FILE_DURABLE, "durable"},
+ {KSMBD_PROC_FILE_PERSISTENT, "persistent"},
+ {KSMBD_PROC_FILE_RESILIENT, "resilient"},
+ {KSMBD_PROC_FILE_DELETE_ON_CLOSE, "delete-on-close"},
+ {KSMBD_PROC_FILE_STREAM, "stream"},
+ {KSMBD_PROC_FILE_POSIX, "posix"},
+ {KSMBD_PROC_FILE_ATTRIB_ONLY, "attrib-only"},
+};
+
+static unsigned int ksmbd_proc_file_flags(struct ksmbd_file *fp)
+{
+ unsigned int flags = 0;
+
+ if (fp->is_durable)
+ flags |= KSMBD_PROC_FILE_DURABLE;
+ if (fp->is_persistent)
+ flags |= KSMBD_PROC_FILE_PERSISTENT;
+ if (fp->is_resilient)
+ flags |= KSMBD_PROC_FILE_RESILIENT;
+ if (fp->coption & FILE_DELETE_ON_CLOSE_LE)
+ flags |= KSMBD_PROC_FILE_DELETE_ON_CLOSE;
+ if (fp->stream.name)
+ flags |= KSMBD_PROC_FILE_STREAM;
+ if (fp->is_posix_ctxt)
+ flags |= KSMBD_PROC_FILE_POSIX;
+ if (fp->attrib_only)
+ flags |= KSMBD_PROC_FILE_ATTRIB_ONLY;
+ return flags;
+}
+
static int proc_show_files(struct seq_file *m, void *v)
{
struct ksmbd_file *fp = NULL;
unsigned int id;
struct oplock_info *opinfo;
- seq_printf(m, "#%-10s %-18s %-18s %-10s %-16s %-10s %-10s %s\n",
- "<tree id>", "<pid>", "<vid>", "<refcnt>",
- "<oplock>", "<daccess>", "<saccess>",
- "<name>");
-
read_lock(&global_ft.lock);
idr_for_each_entry(global_ft.idr, fp, id) {
- seq_printf(m, " %#-10x %#-18llx %#-18llx %#-10x",
- fp->tcon ? fp->tcon->id : 0,
- fp->persistent_id,
- fp->volatile_id,
- atomic_read(&fp->refcount));
+ seq_printf(m, "tree_id:\t0x%x\n", fp->tcon ? fp->tcon->id : 0);
+ seq_printf(m, "persistent_id:\t0x%llx\n", fp->persistent_id);
+ seq_printf(m, "volatile_id:\t0x%llx\n", fp->volatile_id);
+ seq_printf(m, "refcount:\t%d\n", atomic_read(&fp->refcount));
rcu_read_lock();
opinfo = rcu_dereference(fp->f_opinfo);
@@ -109,17 +148,30 @@ static int proc_show_files(struct seq_file *m, void *v)
rcu_read_unlock();
name = ksmbd_proc_const_name(const_names, count, level);
if (name)
- seq_printf(m, " %-16s", name);
+ seq_printf(m, "oplock:\t%s\n", name);
else
- seq_printf(m, " 0x%-14x", level);
+ seq_printf(m, "oplock:\t0x%x\n", level);
} else {
rcu_read_unlock();
- seq_printf(m, " %-16s", " ");
+ seq_puts(m, "oplock:\tnone\n");
}
- seq_printf(m, " %#010x %#010x %s\n",
- le32_to_cpu(fp->daccess),
- le32_to_cpu(fp->saccess),
+ seq_printf(m, "state:\t%s\n",
+ ksmbd_proc_const_name(ksmbd_file_state_names,
+ ARRAY_SIZE(ksmbd_file_state_names),
+ fp->f_state));
+ seq_printf(m, "durable_timeout:\t%u\n", fp->durable_timeout);
+ seq_printf(m, "create_options:\t0x%08x\n",
+ le32_to_cpu(fp->coption));
+ seq_printf(m, "desired_access:\t0x%08x\n",
+ le32_to_cpu(fp->daccess));
+ seq_printf(m, "share_access:\t0x%08x\n",
+ le32_to_cpu(fp->saccess));
+ seq_puts(m, "flags:\t");
+ ksmbd_proc_show_flag_names(m, ksmbd_file_flag_names,
+ ARRAY_SIZE(ksmbd_file_flag_names),
+ ksmbd_proc_file_flags(fp));
+ seq_printf(m, "\nname:\t%s\n\n",
fp->filp->f_path.dentry->d_name.name);
}
read_unlock(&global_ft.lock);
--
2.25.1
next prev parent reply other threads:[~2026-07-16 9:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 9:57 [PATCH 1/7] ksmbd: implement the command sequence window Namjae Jeon
2026-07-16 9:57 ` [PATCH 2/7] ksmbd: add SMB3 request replay support Namjae Jeon
2026-07-16 9:57 ` [PATCH 3/7] ksmbd: fix malformed procfs status output Namjae Jeon
2026-07-16 9:57 ` [PATCH 4/7] ksmbd: expose connection runtime state in procfs Namjae Jeon
2026-07-16 9:57 ` Namjae Jeon [this message]
2026-07-16 9:57 ` [PATCH 6/7] ksmbd: add procfs monitoring for active shares Namjae Jeon
2026-07-16 9:57 ` [PATCH 7/7] ksmbd: extend procfs server statistics Namjae Jeon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260716095711.6228-5-linkinjeon@kernel.org \
--to=linkinjeon@kernel.org \
--cc=atteh.mailbox@gmail.com \
--cc=linux-cifs@vger.kernel.org \
--cc=senozhatsky@chromium.org \
--cc=smfrench@gmail.com \
--cc=tom@talpey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox