mirror of
https://github.com/torvalds/linux.git
synced 2026-10-08 11:36:02 +02:00
ksmbd: fix malformed procfs status output
The ksmbd procfs monitoring files produce misleading or malformed output. The constant-name helper uses a bitwise test for enum values. This omits zero-valued constants and can print multiple names for one lease state. It also unconditionally emits a newline, splitting entries in the open-file table across two lines. Session capabilities are printed as numeric flag values even though a table of descriptive names is available. Use exact matching for enum values. Print flag names as a comma-separated list, preserving unknown bits as hexadecimal values. Let callers control line termination so each open-file entry remains on one line. Print common session properties once, and report signing and encryption independently. Adjust client and open-file column widths for IPv6 addresses and 64-bit file IDs, and fix the misspelled OPLOCK_EXCLUSIVE name. Also expose and maintain the total request count alongside the per-command counters. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
This commit is contained in:
parent
bb8bf7eb13
commit
1f7dd03a88
|
|
@ -33,9 +33,9 @@ static int proc_show_clients(struct seq_file *m, void *v)
|
|||
struct timespec64 now, t;
|
||||
int i;
|
||||
|
||||
seq_printf(m, "#%-20s %-10s %-10s %-10s %-10s %-10s\n",
|
||||
"<name>", "<dialect>", "<credits>", "<open files>",
|
||||
"<requests>", "<last active>");
|
||||
seq_printf(m, "#%-40s %-10s %-10s %-12s %-10s %s\n",
|
||||
"<client>", "<dialect>", "<credits>", "<open files>",
|
||||
"<requests>", "<last active>");
|
||||
|
||||
down_read(&conn_list_lock);
|
||||
hash_for_each(conn_list, i, conn, hlist) {
|
||||
|
|
@ -44,11 +44,11 @@ static int proc_show_clients(struct seq_file *m, void *v)
|
|||
t = timespec64_sub(now, t);
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
if (!conn->inet_addr)
|
||||
seq_printf(m, "%-20pI6c", &conn->inet6_addr);
|
||||
seq_printf(m, " %-40pI6c", &conn->inet6_addr);
|
||||
else
|
||||
#endif
|
||||
seq_printf(m, "%-20pI4", &conn->inet_addr);
|
||||
seq_printf(m, " 0x%-10x %-10u %-12d %-10d %ptT\n",
|
||||
seq_printf(m, " %-40pI4", &conn->inet_addr);
|
||||
seq_printf(m, " 0x%-8x %-10u %-12d %-10d %ptT\n",
|
||||
conn->dialect,
|
||||
conn->total_credits,
|
||||
atomic_read(&conn->stats.open_files_count),
|
||||
|
|
|
|||
|
|
@ -90,9 +90,15 @@ 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));
|
||||
|
||||
i = 0;
|
||||
down_read(&sess->chann_lock);
|
||||
xa_for_each(&sess->ksmbd_chann_list, id, chan) {
|
||||
const char *name;
|
||||
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
if (chan->conn->inet_addr)
|
||||
seq_printf(m, "%-20s\t%pI4\n", "client",
|
||||
|
|
@ -104,29 +110,37 @@ static int show_proc_session(struct seq_file *m, void *v)
|
|||
seq_printf(m, "%-20s\t%pI4\n", "client",
|
||||
&chan->conn->inet_addr);
|
||||
#endif
|
||||
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, "%-20s\t", "capabilities");
|
||||
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');
|
||||
|
||||
if (sess->sign) {
|
||||
seq_printf(m, "%-20s\t", "signing");
|
||||
ksmbd_proc_show_const_name(m, "%s\t",
|
||||
ksmbd_signing_const_names,
|
||||
ARRAY_SIZE(ksmbd_signing_const_names),
|
||||
le16_to_cpu(chan->conn->signing_algorithm));
|
||||
} else if (sess->enc) {
|
||||
seq_printf(m, "%-20s\t", "encryption");
|
||||
ksmbd_proc_show_const_name(m, "%s\t",
|
||||
ksmbd_cipher_const_names,
|
||||
ARRAY_SIZE(ksmbd_cipher_const_names),
|
||||
le16_to_cpu(chan->conn->cipher_type));
|
||||
unsigned int algorithm =
|
||||
le16_to_cpu(chan->conn->signing_algorithm);
|
||||
|
||||
name = ksmbd_proc_const_name(ksmbd_signing_const_names,
|
||||
ARRAY_SIZE(ksmbd_signing_const_names),
|
||||
algorithm);
|
||||
if (name)
|
||||
seq_printf(m, "%-20s\t%s\n", "signing", name);
|
||||
else
|
||||
seq_printf(m, "%-20s\t0x%04x\n", "signing",
|
||||
algorithm);
|
||||
}
|
||||
if (sess->enc) {
|
||||
unsigned int cipher = le16_to_cpu(chan->conn->cipher_type);
|
||||
|
||||
name = ksmbd_proc_const_name(ksmbd_cipher_const_names,
|
||||
ARRAY_SIZE(ksmbd_cipher_const_names),
|
||||
cipher);
|
||||
if (name)
|
||||
seq_printf(m, "%-20s\t%s\n", "encryption", name);
|
||||
else
|
||||
seq_printf(m, "%-20s\t0x%04x\n", "encryption",
|
||||
cipher);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
|
@ -152,35 +166,6 @@ static int show_proc_session(struct seq_file *m, void *v)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void ksmbd_proc_show_flag_names(struct seq_file *m,
|
||||
const struct ksmbd_const_name *table,
|
||||
int count,
|
||||
unsigned int flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (table[i].const_value & flags)
|
||||
seq_printf(m, "0x%08x\t", table[i].const_value);
|
||||
}
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
|
||||
void ksmbd_proc_show_const_name(struct seq_file *m,
|
||||
const char *format,
|
||||
const struct ksmbd_const_name *table,
|
||||
int count,
|
||||
unsigned int const_value)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (table[i].const_value & const_value)
|
||||
seq_printf(m, format, table[i].name);
|
||||
}
|
||||
seq_putc(m, '\n');
|
||||
}
|
||||
|
||||
static int create_proc_session(struct ksmbd_session *sess)
|
||||
{
|
||||
char name[30];
|
||||
|
|
|
|||
|
|
@ -53,11 +53,8 @@ void ksmbd_proc_show_flag_names(struct seq_file *m,
|
|||
const struct ksmbd_const_name *table,
|
||||
int count,
|
||||
unsigned int flags);
|
||||
void ksmbd_proc_show_const_name(struct seq_file *m,
|
||||
const char *format,
|
||||
const struct ksmbd_const_name *table,
|
||||
int count,
|
||||
unsigned int const_value);
|
||||
const char *ksmbd_proc_const_name(const struct ksmbd_const_name *table,
|
||||
int count, unsigned int const_value);
|
||||
#else
|
||||
static inline void ksmbd_proc_init(void) {}
|
||||
static inline void ksmbd_proc_cleanup(void) {}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,42 @@ struct proc_dir_entry *ksmbd_proc_create(const char *name,
|
|||
show, v);
|
||||
}
|
||||
|
||||
void ksmbd_proc_show_flag_names(struct seq_file *m,
|
||||
const struct ksmbd_const_name *table,
|
||||
int count, unsigned int flags)
|
||||
{
|
||||
unsigned int remaining = flags;
|
||||
bool separator = false;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
unsigned int flag = table[i].const_value;
|
||||
|
||||
if (!flag || (remaining & flag) != flag)
|
||||
continue;
|
||||
seq_printf(m, "%s%s", separator ? "," : "", table[i].name);
|
||||
separator = true;
|
||||
remaining &= ~flag;
|
||||
}
|
||||
|
||||
if (remaining)
|
||||
seq_printf(m, "%s0x%08x", separator ? "," : "", remaining);
|
||||
else if (!separator)
|
||||
seq_puts(m, "none");
|
||||
}
|
||||
|
||||
const char *ksmbd_proc_const_name(const struct ksmbd_const_name *table,
|
||||
int count, unsigned int const_value)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (table[i].const_value == const_value)
|
||||
return table[i].name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ksmbd_const_smb2_process_req {
|
||||
unsigned int const_value;
|
||||
const char *name;
|
||||
|
|
@ -71,6 +107,8 @@ static int proc_show_ksmbd_stats(struct seq_file *m, void *v)
|
|||
ksmbd_counter_sum(KSMBD_COUNTER_SESSIONS));
|
||||
seq_printf(m, "tree connects: %lld\n",
|
||||
ksmbd_counter_sum(KSMBD_COUNTER_TREE_CONNS));
|
||||
seq_printf(m, "requests: %lld\n",
|
||||
ksmbd_counter_sum(KSMBD_COUNTER_REQUESTS));
|
||||
seq_printf(m, "read bytes: %lld\n",
|
||||
ksmbd_counter_sum(KSMBD_COUNTER_READ_BYTES));
|
||||
seq_printf(m, "written bytes: %lld\n",
|
||||
|
|
|
|||
|
|
@ -52,8 +52,10 @@ static inline void ksmbd_counter_sub(int type, s64 value)
|
|||
|
||||
static inline void ksmbd_counter_inc_reqs(unsigned int cmd)
|
||||
{
|
||||
if (cmd < KSMBD_COUNTER_MAX_REQS)
|
||||
if (cmd < KSMBD_COUNTER_MAX_REQS) {
|
||||
percpu_counter_inc(&ksmbd_counters.counters[KSMBD_COUNTER_REQUESTS]);
|
||||
percpu_counter_inc(&ksmbd_counters.counters[KSMBD_COUNTER_FIRST_REQ + cmd]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline s64 ksmbd_counter_sum(int type)
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ static const struct ksmbd_const_name ksmbd_lease_const_names[] = {
|
|||
static const struct ksmbd_const_name ksmbd_oplock_const_names[] = {
|
||||
{SMB2_OPLOCK_LEVEL_NONE, "OPLOCK_NONE"},
|
||||
{SMB2_OPLOCK_LEVEL_II, "OPLOCK_II"},
|
||||
{SMB2_OPLOCK_LEVEL_EXCLUSIVE, "OPLOCK_EXECL"},
|
||||
{SMB2_OPLOCK_LEVEL_EXCLUSIVE, "OPLOCK_EXCLUSIVE"},
|
||||
{SMB2_OPLOCK_LEVEL_BATCH, "OPLOCK_BATCH"},
|
||||
};
|
||||
|
||||
|
|
@ -76,14 +76,14 @@ static int proc_show_files(struct seq_file *m, void *v)
|
|||
unsigned int id;
|
||||
struct oplock_info *opinfo;
|
||||
|
||||
seq_printf(m, "#%-10s %-10s %-10s %-10s %-15s %-10s %-10s %s\n",
|
||||
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 %#-10llx %#-10llx %#-10x",
|
||||
seq_printf(m, " %#-10x %#-18llx %#-18llx %#-10x",
|
||||
fp->tcon ? fp->tcon->id : 0,
|
||||
fp->persistent_id,
|
||||
fp->volatile_id,
|
||||
|
|
@ -93,6 +93,7 @@ static int proc_show_files(struct seq_file *m, void *v)
|
|||
opinfo = rcu_dereference(fp->f_opinfo);
|
||||
if (opinfo) {
|
||||
const struct ksmbd_const_name *const_names;
|
||||
const char *name;
|
||||
int count;
|
||||
unsigned int level;
|
||||
|
||||
|
|
@ -106,11 +107,14 @@ static int proc_show_files(struct seq_file *m, void *v)
|
|||
level = opinfo->level;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
ksmbd_proc_show_const_name(m, " %-15s",
|
||||
const_names, count, level);
|
||||
name = ksmbd_proc_const_name(const_names, count, level);
|
||||
if (name)
|
||||
seq_printf(m, " %-16s", name);
|
||||
else
|
||||
seq_printf(m, " 0x%-14x", level);
|
||||
} else {
|
||||
rcu_read_unlock();
|
||||
seq_printf(m, " %-15s", " ");
|
||||
seq_printf(m, " %-16s", " ");
|
||||
}
|
||||
|
||||
seq_printf(m, " %#010x %#010x %s\n",
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user