aboutsummaryrefslogtreecommitdiff
path: root/module/os/freebsd/spl/spl_procfs_list.c
diff options
context:
space:
mode:
authorMatt Macy <mmacy@FreeBSD.org>2020-10-01 23:09:24 +0000
committerMatt Macy <mmacy@FreeBSD.org>2020-10-01 23:09:24 +0000
commite2228bd99047bb6a0cef0da931147b1f28f155c2 (patch)
tree2859f65ec0723fe7424b97206b84c5d760d12b1c /module/os/freebsd/spl/spl_procfs_list.c
parent01ea34f1d8bc20a76845a15e968388679693ee44 (diff)
downloadsrc-e2228bd99047bb6a0cef0da931147b1f28f155c2.tar.gz
src-e2228bd99047bb6a0cef0da931147b1f28f155c2.zip
Update OpenZFS to 2.0.0-rc3-gfc5966vendor/openzfs/2.0-rc3-gfc5966
Notes
Notes: svn path=/vendor-sys/openzfs/dist/; revision=366348 svn path=/vendor-sys/openzfs/2.0-rc3-gfc5966/; revision=366349; tag=vendor/openzfs/2.0-rc3-gfc5966
Diffstat (limited to 'module/os/freebsd/spl/spl_procfs_list.c')
-rw-r--r--module/os/freebsd/spl/spl_procfs_list.c86
1 files changed, 84 insertions, 2 deletions
diff --git a/module/os/freebsd/spl/spl_procfs_list.c b/module/os/freebsd/spl/spl_procfs_list.c
index 7b4ae9d0e357..e8448ce00686 100644
--- a/module/os/freebsd/spl/spl_procfs_list.c
+++ b/module/os/freebsd/spl/spl_procfs_list.c
@@ -32,12 +32,74 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/procfs_list.h>
+typedef struct procfs_list_iter {
+ procfs_list_t *pli_pl;
+ void *pli_elt;
+} pli_t;
+
void
-seq_printf(struct seq_file *m, const char *fmt, ...)
-{}
+seq_printf(struct seq_file *f, const char *fmt, ...)
+{
+ va_list adx;
+
+ va_start(adx, fmt);
+ (void) vsnprintf(f->sf_buf, f->sf_size, fmt, adx);
+ va_end(adx);
+}
+
+static int
+procfs_list_update(kstat_t *ksp, int rw)
+{
+ procfs_list_t *pl = ksp->ks_private;
+
+ if (rw == KSTAT_WRITE)
+ pl->pl_clear(pl);
+
+ return (0);
+}
+
+static int
+procfs_list_data(char *buf, size_t size, void *data)
+{
+ pli_t *p;
+ void *elt;
+ procfs_list_t *pl;
+ struct seq_file f;
+
+ p = data;
+ pl = p->pli_pl;
+ elt = p->pli_elt;
+ free(p, M_TEMP);
+ f.sf_buf = buf;
+ f.sf_size = size;
+ return (pl->pl_show(&f, elt));
+}
+
+static void *
+procfs_list_addr(kstat_t *ksp, loff_t n)
+{
+ procfs_list_t *pl = ksp->ks_private;
+ void *elt = ksp->ks_private1;
+ pli_t *p = NULL;
+
+
+ if (n == 0)
+ ksp->ks_private1 = list_head(&pl->pl_list);
+ else if (elt)
+ ksp->ks_private1 = list_next(&pl->pl_list, elt);
+
+ if (ksp->ks_private1) {
+ p = malloc(sizeof (*p), M_TEMP, M_WAITOK);
+ p->pli_pl = pl;
+ p->pli_elt = ksp->ks_private1;
+ }
+
+ return (p);
+}
void
procfs_list_install(const char *module,
+ const char *submodule,
const char *name,
mode_t mode,
procfs_list_t *procfs_list,
@@ -46,12 +108,31 @@ procfs_list_install(const char *module,
int (*clear)(procfs_list_t *procfs_list),
size_t procfs_list_node_off)
{
+ kstat_t *procfs_kstat;
+
mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL);
list_create(&procfs_list->pl_list,
procfs_list_node_off + sizeof (procfs_list_node_t),
procfs_list_node_off + offsetof(procfs_list_node_t, pln_link));
+ procfs_list->pl_show = show;
+ procfs_list->pl_show_header = show_header;
+ procfs_list->pl_clear = clear;
procfs_list->pl_next_id = 1;
procfs_list->pl_node_offset = procfs_list_node_off;
+
+ procfs_kstat = kstat_create(module, 0, name, submodule,
+ KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
+
+ if (procfs_kstat) {
+ procfs_kstat->ks_lock = &procfs_list->pl_lock;
+ procfs_kstat->ks_ndata = UINT32_MAX;
+ procfs_kstat->ks_private = procfs_list;
+ procfs_kstat->ks_update = procfs_list_update;
+ kstat_set_seq_raw_ops(procfs_kstat, show_header,
+ procfs_list_data, procfs_list_addr);
+ kstat_install(procfs_kstat);
+ procfs_list->pl_private = procfs_kstat;
+ }
}
void
@@ -62,6 +143,7 @@ void
procfs_list_destroy(procfs_list_t *procfs_list)
{
ASSERT(list_is_empty(&procfs_list->pl_list));
+ kstat_delete(procfs_list->pl_private);
list_destroy(&procfs_list->pl_list);
mutex_destroy(&procfs_list->pl_lock);
}