Index: lib/libgeom/geom_stats.c =================================================================== --- lib/libgeom/geom_stats.c +++ lib/libgeom/geom_stats.c @@ -32,9 +32,12 @@ */ #include +#include +#include #include #include #include +#include #include #include #include @@ -53,7 +56,7 @@ { if (statsfd == -1) return; - munmap(statp, npages *pagesize); + munmap(statp, npages * pagesize); statp = NULL; close (statsfd); statsfd = -1; @@ -63,17 +66,22 @@ geom_stats_resync(void) { void *p; + off_t mediasize; + int error; if (statsfd == -1) return; - for (;;) { - p = mmap(statp, (npages + 1) * pagesize, - PROT_READ, MAP_SHARED, statsfd, 0); - if (p == MAP_FAILED) - break; - else - statp = p; - npages++; + error = ioctl(statsfd, DIOCGMEDIASIZE, &mediasize); + if (error) + err(1, "DIOCGMEDIASIZE(" _PATH_DEV DEVSTAT_DEVICE_NAME ")"); + + munmap(statp, npages * pagesize); + p = mmap(statp, mediasize, PROT_READ, MAP_SHARED, statsfd, 0); + if (p == MAP_FAILED) + err(1, "mmap(/dev/devstat):"); + else { + statp = p; + npages = mediasize / pagesize; } } @@ -128,9 +136,8 @@ free(sp); return (NULL); } - memset(sp->ptr, 0, pagesize * npages); /* page in, cache */ clock_gettime(CLOCK_REALTIME, &sp->time); - memset(sp->ptr, 0, pagesize * npages); /* page in, cache */ + memset(sp->ptr, 0, pagesize * npages); /* page in, cache */ memcpy(sp->ptr, statp, pagesize * npages); sp->pages = npages; sp->perpage = spp; Index: sbin/mdconfig/mdconfig.c =================================================================== --- sbin/mdconfig/mdconfig.c +++ sbin/mdconfig/mdconfig.c @@ -423,7 +423,7 @@ /* * Lists md(4) disks. Is used also as a query routine, since it handles XML * interface. 'units' can be NULL for listing memory disks. It might be - * coma-separated string containing md(4) disk names. 'opt' distinguished + * comma-separated string containing md(4) disk names. 'opt' distinguished * between list and query mode. */ static int Index: sys/kern/subr_devstat.c =================================================================== --- sys/kern/subr_devstat.c +++ sys/kern/subr_devstat.c @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -473,10 +474,12 @@ #define statsperpage (PAGE_SIZE / sizeof(struct devstat)) +static d_ioctl_t devstat_ioctl; static d_mmap_t devstat_mmap; static struct cdevsw devstat_cdevsw = { .d_version = D_VERSION, + .d_ioctl = devstat_ioctl, .d_mmap = devstat_mmap, .d_name = "devstat", }; @@ -487,9 +490,26 @@ u_int nfree; }; +static size_t pagelist_pages = 0; static TAILQ_HEAD(, statspage) pagelist = TAILQ_HEAD_INITIALIZER(pagelist); static MALLOC_DEFINE(M_DEVSTAT, "devstat", "Device statistics"); +static int +devstat_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, + struct thread *td) +{ + int error = ENOTTY; + + switch (cmd) { + case DIOCGMEDIASIZE: + error = 0; + *(off_t *)data = pagelist_pages * PAGE_SIZE; + break; + } + + return (error); +} + static int devstat_mmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int nprot, vm_memattr_t *memattr) @@ -556,6 +576,7 @@ * head but the order on the list determine the * sequence of the mapping so we can't do that. */ + pagelist_pages++; TAILQ_INSERT_TAIL(&pagelist, spp, list); } else break;