diff options
author | Matt Macy <mmacy@FreeBSD.org> | 2020-10-01 23:09:24 +0000 |
---|---|---|
committer | Matt Macy <mmacy@FreeBSD.org> | 2020-10-01 23:09:24 +0000 |
commit | e2228bd99047bb6a0cef0da931147b1f28f155c2 (patch) | |
tree | 2859f65ec0723fe7424b97206b84c5d760d12b1c /module/os/freebsd/spl/spl_procfs_list.c | |
parent | 01ea34f1d8bc20a76845a15e968388679693ee44 (diff) | |
download | src-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.c | 86 |
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); } |