diff options
author | John Gallagher <[email protected]> | 2018-09-26 11:08:12 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2018-09-26 11:08:12 -0700 |
commit | d12614521a307c709778e5f7f91ae6085f63f9e0 (patch) | |
tree | 130e6dde286d0da760612a7f4d9595a660777011 /include/sys/zfs_context.h | |
parent | 3ed2fbcc1ce36fdc516aa11848692a4e4c4a2bc0 (diff) |
Fixes for procfs files backed by linked lists
There are some issues with the way the seq_file interface is implemented
for kstats backed by linked lists (zfs_dbgmsgs and certain per-pool
debugging info):
* We don't account for the fact that seq_file sometimes visits a node
multiple times, which results in missing messages when read through
procfs.
* We don't keep separate state for each reader of a file, so concurrent
readers will receive incorrect results.
* We don't account for the fact that entries may have been removed from
the list between read syscalls, so reading from these files in procfs
can cause the system to crash.
This change fixes these issues and adds procfs_list, a wrapper around a
linked list which abstracts away the details of implementing the
seq_file interface for a list and exposing the contents of the list
through procfs.
Reviewed by: Don Brady <[email protected]>
Reviewed-by: Serapheim Dimitropoulos <[email protected]>
Reviewed by: Brad Lewis <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: John Gallagher <[email protected]>
External-issue: LX-1211
Closes #7819
Diffstat (limited to 'include/sys/zfs_context.h')
-rw-r--r-- | include/sys/zfs_context.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/include/sys/zfs_context.h b/include/sys/zfs_context.h index 6f502897e..11c048c23 100644 --- a/include/sys/zfs_context.h +++ b/include/sys/zfs_context.h @@ -62,6 +62,7 @@ #include <sys/ctype.h> #include <sys/disp.h> #include <sys/trace.h> +#include <sys/procfs_list.h> #include <linux/dcache_compat.h> #include <linux/utsname_compat.h> @@ -352,6 +353,37 @@ extern void kstat_set_raw_ops(kstat_t *ksp, void *(*addr)(kstat_t *ksp, loff_t index)); /* + * procfs list manipulation + */ + +struct seq_file { }; +void seq_printf(struct seq_file *m, const char *fmt, ...); + +typedef struct procfs_list { + void *pl_private; + kmutex_t pl_lock; + list_t pl_list; + uint64_t pl_next_id; + size_t pl_node_offset; +} procfs_list_t; + +typedef struct procfs_list_node { + list_node_t pln_link; + uint64_t pln_id; +} procfs_list_node_t; + +void procfs_list_install(const char *module, + const char *name, + procfs_list_t *procfs_list, + int (*show)(struct seq_file *f, void *p), + int (*show_header)(struct seq_file *f), + int (*clear)(procfs_list_t *procfs_list), + size_t procfs_list_node_off); +void procfs_list_uninstall(procfs_list_t *procfs_list); +void procfs_list_destroy(procfs_list_t *procfs_list); +void procfs_list_add(procfs_list_t *procfs_list, void *p); + +/* * Kernel memory */ #define KM_SLEEP UMEM_NOFAIL |