mirror of
https://github.com/torvalds/linux.git
synced 2026-10-08 03:26:02 +02:00
ksmbd: report session and open file details in procfs
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>
This commit is contained in:
parent
fe4dc5987d
commit
7f9832651e
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user