/*
 * DF-3118 measurement helper (read-only; setup tooling, not part of attack).
 * Reports hmp->flusher.{done,next} and the ring gap for the hammer(1)
 * mount on /tmp/hmr.  Loadable repeatedly (kldload/kldunload seqstat).
 */
#include <sys/param.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/mount.h>
#include "vfs/hammer/hammer.h"

static int
seqstat_cb(struct mount *mp, void *data __unused)
{
	hammer_mount_t hmp;

	if (strcmp(mp->mnt_stat.f_fstypename, "hammer"))
		return (0);
	if (strstr(mp->mnt_stat.f_mntonname, "/tmp/hmr") == NULL)
		return (0);
	hmp = (hammer_mount_t)mp->mnt_data;
	lwkt_gettoken(&hmp->fs_token);
	kprintf("seqstat: done=%d(0x%x) next=%d(0x%x) gap=%u\n",
		hmp->flusher.done, hmp->flusher.done,
		hmp->flusher.next, hmp->flusher.next,
		(unsigned)hmp->flusher.next - (unsigned)hmp->flusher.done);
	lwkt_reltoken(&hmp->fs_token);
	return (0);
}

static int
seqstat_modevent(module_t mod, int type, void *data)
{
	switch (type) {
	case MOD_LOAD:
		mountlist_scan(seqstat_cb, NULL, MNTSCAN_FORWARD);
		return (0);
	case MOD_UNLOAD:
		return (0);
	}
	return (EOPNOTSUPP);
}

static moduledata_t seqstat_mod = { "seqstat", seqstat_modevent, 0 };
DECLARE_MODULE(seqstat, seqstat_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
