about summary refs log tree commit diff
path: root/db2/mp/mp_pr.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-06-09 15:16:55 +0000
committerUlrich Drepper <drepper@redhat.com>1998-06-09 15:16:55 +0000
commitbf7997b65c7887d2acda95f5201d818a19d81711 (patch)
treeda3583de3a0b5892f90a4b1eb773a87b554ae37e /db2/mp/mp_pr.c
parent7646e67e6cc4c738a7b402c60fed39d52db0433b (diff)
downloadglibc-bf7997b65c7887d2acda95f5201d818a19d81711.tar.gz
glibc-bf7997b65c7887d2acda95f5201d818a19d81711.tar.xz
glibc-bf7997b65c7887d2acda95f5201d818a19d81711.zip
Update.
1998-06-09  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/sysv/linux/netinet/ip.h (struct ip_options): Define
	__data member only for gcc.  Reported by ak@muc.de.

	* misc/mntent.h: Undo last patch.
	* sysdeps/unix/sysv/linux/fstatvfs.c (fstatvfs): Undo last patch.
	* misc/tst/mntent.c: Adjust code for this change.

	* io/fts.c: Updated from a slightly more recent BSD version.
	* io/fts.h: Likewise.

	* libc.map: Add __libc_stack_end.

	* db2/Makefile (routines): Add lock_region.
	* db2/config.h: Update from db-2.4.14.
	* db2/db.h: Likewise.
	* db2/db_185.h: Likewise.
	* db2/db_int.h: Likewise.
	* db2/bt_close.c: Likewise.
	* db2/bt_compare.c: Likewise.
	* db2/bt_conv.c: Likewise.
	* db2/bt_cursor.c: Likewise.
	* db2/bt_delete.c: Likewise.
	* db2/bt_open.c: Likewise.
	* db2/bt_page.c: Likewise.
	* db2/bt_put.c: Likewise.
	* db2/bt_rec.c: Likewise.
	* db2/bt_recno.c: Likewise.
	* db2/bt_rsearch.c: Likewise.
	* db2/bt_search.c: Likewise.
	* db2/bt_split.c: Likewise.
	* db2/bt_stat.c: Likewise.
	* db2/btree.src: Likewise.
	* db2/btree_auto.c: Likewise.
	* db2/getlong.c: Likewise.
	* db2/db_appinit.c: Likewise.
	* db2/db_apprec.c: Likewise.
	* db2/db_byteorder.c: Likewise.
	* db2/db_err.c: Likewise.
	* db2/db_log2.c: Likewise.
	* db2/db_region.c: Likewise.
	* db2/db_salloc.c: Likewise.
	* db2/db_shash.c: Likewise.
	* db2/db.c: Likewise.
	* db2/db.src: Likewise.
	* db2/db_auto.c: Likewise.
	* db2/db_conv.c: Likewise.
	* db2/db_dispatch.c: Likewise.
	* db2/db_dup.c: Likewise.
	* db2/db_overflow.c: Likewise.
	* db2/db_pr.c: Likewise.
	* db2/db_rec.c: Likewise.
	* db2/db_ret.c: Likewise.
	* db2/db_thread.c: Likewise.
	* db2/db185.c: Likewise.
	* db2/db185_int.h: Likewise.
	* db2/dbm.c: Likewise.
	* db2/hash.c: Likewise.
	* db2/hash.src: Likewise.
	* db2/hash_auto.c: Likewise.
	* db2/hash_conv.c: Likewise.
	* db2/hash_debug.c: Likewise.
	* db2/hash_dup.c: Likewise.
	* db2/hash_func.c: Likewise.
	* db2/hash_page.c: Likewise.
	* db2/hash_rec.c: Likewise.
	* db2/hash_stat.c: Likewise.
	* db2/btree.h: Likewise.
	* db2/btree_ext.h: Likewise.
	* db2/clib_ext.h: Likewise.
	* db2/common_ext.h: Likewise.
	* db2/cxx_int.h: Likewise.
	* db2/db.h.src: Likewise.
	* db2/db_185.h.src: Likewise.
	* db2/db_am.h: Likewise.
	* db2/db_auto.h: Likewise.
	* db2/db_cxx.h: Likewise.
	* db2/db_dispatch.h: Likewise.
	* db2/db_ext.h: Likewise.
	* db2/db_int.h.src: Likewise.
	* db2/db_page.h: Likewise.
	* db2/db_shash.h: Likewise.
	* db2/db_swap.h: Likewise.
	* db2/hash.h: Likewise.
	* db2/hash_ext.h: Likewise.
	* db2/lock.h: Likewise.
	* db2/lock_ext.h: Likewise.
	* db2/log.h: Likewise.
	* db2/log_ext.h: Likewise.
	* db2/mp.h: Likewise.
	* db2/mp_ext.h: Likewise.
	* db2/mutex_ext.h: Likewise.
	* db2/os_ext.h: Likewise.
	* db2/os_func.h: Likewise.
	* db2/queue.h: Likewise.
	* db2/shqueue.h: Likewise.
	* db2/txn.h: Likewise.
	* db2/lock.c: Likewise.
	* db2/lock_conflict.c: Likewise.
	* db2/lock_deadlock.c: Likewise.
	* db2/lock_region.c: Likewise.
	* db2/lock_util.c: Likewise.
	* db2/log.c: Likewise.
	* db2/log.src: Likewise.
	* db2/log_archive.c: Likewise.
	* db2/log_auto.c: Likewise.
	* db2/log_compare.c: Likewise.
	* db2/log_findckp.c: Likewise.
	* db2/log_get.c: Likewise.
	* db2/log_put.c: Likewise.
	* db2/log_rec.c: Likewise.
	* db2/log_register.c: Likewise.
	* db2/mp_bh.c: Likewise.
	* db2/mp_fget.c: Likewise.
	* db2/mp_fopen.c: Likewise.
	* db2/mp_fput.c: Likewise.
	* db2/mp_fset.c: Likewise.
	* db2/mp_open.c: Likewise.
	* db2/mp_pr.c: Likewise.
	* db2/mp_region.c: Likewise.
	* db2/mp_sync.c: Likewise.
	* db2/68020.gcc: Likewise.
	* db2/mutex.c: Likewise.
	* db2/parisc.gcc: Likewise.
	* db2/parisc.hp: Likewise.
	* db2/sco.cc: Likewise.
	* db2/os_abs.c: Likewise.
	* db2/os_alloc.c: Likewise.
	* db2/os_config.c: Likewise.
	* db2/os_dir.c: Likewise.
	* db2/os_fid.c: Likewise.
	* db2/os_fsync.c: Likewise.
	* db2/os_map.c: Likewise.
	* db2/os_oflags.c: Likewise.
	* db2/os_open.c: Likewise.
	* db2/os_rpath.c: Likewise.
	* db2/os_rw.c: Likewise.
	* db2/os_seek.c: Likewise.
	* db2/os_sleep.c: Likewise.
	* db2/os_spin.c: Likewise.
	* db2/os_stat.c: Likewise.
	* db2/os_unlink.c: Likewise.
	* db2/db_archive.c: Likewise.
	* db2/db_checkpoint.c: Likewise.
	* db2/db_deadlock.c: Likewise.
	* db2/db_dump.c: Likewise.
	* db2/db_dump185.c: Likewise.
	* db2/db_load.c: Likewise.
	* db2/db_printlog.c: Likewise.
	* db2/db_recover.c: Likewise.
	* db2/db_stat.c: Likewise.
	* db2/txn.c: Likewise.
	* db2/txn.src: Likewise.
	* db2/txn_auto.c: Likewise.
	* db2/txn_rec.c: Likewise.

	* elf/rtld.c: Move definition of __libc_stack_end to ...
	* sysdeps/generic/dl-sysdep.h: ...here.

	* sysdeps/unix/sysv/linux/fstatvfs.c: Handle nodiratime option.
	* sysdeps/unix/sysv/linux/bits/statvfs.h: Define ST_NODIRATIME.
	* sysdeps/unix/sysv/linux/sys/mount.h: Define MS_NODIRATIME.

1998-06-08 21:44  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/unix/sysv/linux/fstatvfs.c: Handle constant option string
	from mntent correctly.

1998-06-06  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

	* sunrpc/Makefile (generated): Correct typo.

1998-06-04  Philip Blundell  <philb@gnu.org>

	* elf/elf.h (EM_ARM, et al.): New definitions.
	* sysdeps/arm/dl-machine.h: Update for new draft ARM ELF ABI.
Diffstat (limited to 'db2/mp/mp_pr.c')
-rw-r--r--db2/mp/mp_pr.c294
1 files changed, 125 insertions, 169 deletions
diff --git a/db2/mp/mp_pr.c b/db2/mp/mp_pr.c
index 13a6c62d35..e83e0f44fa 100644
--- a/db2/mp/mp_pr.c
+++ b/db2/mp/mp_pr.c
@@ -1,13 +1,13 @@
 /*-
  * See the file LICENSE for redistribution information.
  *
- * Copyright (c) 1996, 1997
+ * Copyright (c) 1996, 1997, 1998
  *	Sleepycat Software.  All rights reserved.
  */
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_pr.c	10.21 (Sleepycat) 1/6/98";
+static const char sccsid[] = "@(#)mp_pr.c	10.26 (Sleepycat) 5/23/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -15,20 +15,20 @@ static const char sccsid[] = "@(#)mp_pr.c	10.21 (Sleepycat) 1/6/98";
 
 #include <errno.h>
 #include <stdio.h>
-#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 #endif
 
 #include "db_int.h"
+#include "db_page.h"
 #include "shqueue.h"
 #include "db_shash.h"
 #include "mp.h"
+#include "db_auto.h"
+#include "db_ext.h"
+#include "common_ext.h"
 
-static void __memp_pbh __P((FILE *, DB_MPOOL *, BH *, int));
-static void __memp_pdbmf __P((FILE *, DB_MPOOLFILE *, int));
-static void __memp_pmf __P((FILE *, MPOOLFILE *, int));
-static void __memp_pmp __P((FILE *, DB_MPOOL *, MPOOL *, int));
+static void __memp_pbh __P((DB_MPOOL *, BH *, size_t *, FILE *));
 
 /*
  * memp_stat --
@@ -64,6 +64,8 @@ memp_stat(dbmp, gspp, fspp, db_malloc)
 		    dbmp->mp->rlayout.lock.mutex_set_wait;
 		(*gspp)->st_region_nowait =
 		    dbmp->mp->rlayout.lock.mutex_set_nowait;
+		(*gspp)->st_refcnt = dbmp->mp->rlayout.refcnt;
+		(*gspp)->st_regsize = dbmp->mp->rlayout.size;
 
 		UNLOCKREGION(dbmp);
 	}
@@ -77,7 +79,8 @@ memp_stat(dbmp, gspp, fspp, db_malloc)
 		for (len = 0,
 		    mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
 		    mfp != NULL;
-		    ++len, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile));
+		    ++len, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile))
+			;
 
 		UNLOCKREGION(dbmp);
 
@@ -148,174 +151,118 @@ __memp_fns(dbmp, mfp)
 	return ((char *)R_ADDR(dbmp, mfp->path_off));
 }
 
+#define	FMAP_ENTRIES	200			/* Files we map. */
+
+#define	MPOOL_DUMP_HASH	0x01			/* Debug hash chains. */
+#define	MPOOL_DUMP_LRU	0x02			/* Debug LRU chains. */
+#define	MPOOL_DUMP_MEM	0x04			/* Debug region memory. */
+#define	MPOOL_DUMP_ALL	0x07			/* Debug all. */
+
+
 /*
- * __memp_debug --
+ * __memp_dump_region --
  *	Display MPOOL structures.
  *
- * PUBLIC: void __memp_debug __P((DB_MPOOL *, FILE *, int));
+ * PUBLIC: void __memp_dump_region __P((DB_MPOOL *, char *, FILE *));
  */
 void
-__memp_debug(dbmp, fp, data)
+__memp_dump_region(dbmp, area, fp)
 	DB_MPOOL *dbmp;
+	char *area;
 	FILE *fp;
-	int data;
 {
+	BH *bhp;
+	DB_HASHTAB *htabp;
 	DB_MPOOLFILE *dbmfp;
-	u_long cnt;
+	MPOOL *mp;
+	MPOOLFILE *mfp;
+	size_t bucket, fmap[FMAP_ENTRIES + 1];
+	u_int32_t flags;
+	int cnt;
 
 	/* Make it easy to call from the debugger. */
 	if (fp == NULL)
 		fp = stderr;
 
-	/* Welcome message. */
-	(void)fprintf(fp, "%s\nMpool per-process (%lu) statistics\n",
-	    DB_LINE, (u_long)getpid());
-
-	if (data)
-		(void)fprintf(fp, "    fd: %d; addr %lx; maddr %lx\n",
-		    dbmp->fd, (u_long)dbmp->addr, (u_long)dbmp->maddr);
-
-	/* Display the DB_MPOOLFILE structures. */
-	for (cnt = 0, dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
-	    dbmfp != NULL; ++cnt, dbmfp = TAILQ_NEXT(dbmfp, q));
-	(void)fprintf(fp, "%lu process-local files\n", cnt);
-	for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
-	    dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q)) {
-		(void)fprintf(fp, "%s\n", __memp_fn(dbmfp));
-		__memp_pdbmf(fp, dbmfp, data);
-	}
+	for (flags = 0; *area != '\0'; ++area)
+		switch (*area) {
+		case 'A':
+			LF_SET(MPOOL_DUMP_ALL);
+			break;
+		case 'h':
+			LF_SET(MPOOL_DUMP_HASH);
+			break;
+		case 'l':
+			LF_SET(MPOOL_DUMP_LRU);
+			break;
+		case 'm':
+			LF_SET(MPOOL_DUMP_MEM);
+			break;
+		}
 
-	/* Switch to global statistics. */
-	(void)fprintf(fp, "\n%s\nMpool statistics\n", DB_LINE);
+	LOCKREGION(dbmp);
 
-	/* Display the MPOOL structure. */
-	__memp_pmp(fp, dbmp, dbmp->mp, data);
+	mp = dbmp->mp;
 
-	/* Flush in case we're debugging. */
-	(void)fflush(fp);
-}
-
-/*
- * __memp_pdbmf --
- *	Display a DB_MPOOLFILE structure.
- */
-static void
-__memp_pdbmf(fp, dbmfp, data)
-	FILE *fp;
-	DB_MPOOLFILE *dbmfp;
-	int data;
-{
-	if (!data)
-		return;
-
-	(void)fprintf(fp, "    fd: %d; %s\n",
-	    dbmfp->fd, F_ISSET(dbmfp, MP_READONLY) ? "readonly" : "read/write");
-}
-
-/*
- * __memp_pmp --
- *	Display the MPOOL structure.
- */
-static void
-__memp_pmp(fp, dbmp, mp, data)
-	FILE *fp;
-	DB_MPOOL *dbmp;
-	MPOOL *mp;
-	int data;
-{
-	BH *bhp;
-	MPOOLFILE *mfp;
-	DB_HASHTAB *htabp;
-	size_t bucket;
-	int cnt;
-	const char *sep;
-
-	(void)fprintf(fp, "references: %lu; cachesize: %lu\n",
-	    (u_long)mp->rlayout.refcnt, (u_long)mp->stat.st_cachesize);
-	(void)fprintf(fp,
-	    "    %lu pages created\n", (u_long)mp->stat.st_page_create);
-	(void)fprintf(fp,
-	    "    %lu mmap pages returned\n", (u_long)mp->stat.st_map);
-	(void)fprintf(fp, "    %lu I/O's (%lu read, %lu written)\n",
-	    (u_long)mp->stat.st_page_in + mp->stat.st_page_out,
-	    (u_long)mp->stat.st_page_in, (u_long)mp->stat.st_page_out);
-	if (mp->stat.st_cache_hit + mp->stat.st_cache_miss != 0)
-		(void)fprintf(fp,
-		    "    %.0f%% cache hit rate (%lu hit, %lu miss)\n",
-		    ((double)mp->stat.st_cache_hit /
-	    (mp->stat.st_cache_hit + mp->stat.st_cache_miss)) * 100,
-		    (u_long)mp->stat.st_cache_hit,
-		    (u_long)mp->stat.st_cache_miss);
+	/* Display MPOOL structures. */
+	(void)fprintf(fp, "%s\nPool (region addr 0x%lx, alloc addr 0x%lx)\n",
+	    DB_LINE, (u_long)dbmp->reginfo.addr, (u_long)dbmp->addr);
 
 	/* Display the MPOOLFILE structures. */
-	for (cnt = 0, mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
-	    mfp != NULL; ++cnt, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile));
-	(void)fprintf(fp, "%d total files\n", cnt);
-	for (cnt = 1, mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
-	    mfp != NULL; ++cnt, mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
-		(void)fprintf(fp, "file %d\n", cnt);
-		__memp_pmf(fp, mfp, data);
+	cnt = 0;
+	for (mfp = SH_TAILQ_FIRST(&dbmp->mp->mpfq, __mpoolfile);
+	    mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile), ++cnt) {
+		(void)fprintf(fp, "file #%d: %s: %lu references: %s\n",
+		    cnt + 1, __memp_fns(dbmp, mfp), (u_long)mfp->ref,
+		    F_ISSET(mfp, MP_CAN_MMAP) ? "mmap" : "read/write");
+		    if (cnt < FMAP_ENTRIES)
+			fmap[cnt] = R_OFFSET(dbmp, mfp);
 	}
 
-	if (!data)
-		return;
+	for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
+	    dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q), ++cnt) {
+		(void)fprintf(fp, "file #%d: %s: fd: %d: per-process, %s\n",
+		    cnt + 1, __memp_fn(dbmfp), dbmfp->fd,
+		    F_ISSET(dbmfp, MP_READONLY) ? "readonly" : "read/write");
+		    if (cnt < FMAP_ENTRIES)
+			fmap[cnt] = R_OFFSET(dbmp, mfp);
+	}
+	if (cnt < FMAP_ENTRIES)
+		fmap[cnt] = INVALID;
+	else
+		fmap[FMAP_ENTRIES] = INVALID;
 
 	/* Display the hash table list of BH's. */
-	(void)fprintf(fp, "%s\nHASH table of BH's (%lu buckets):\n",
-	    DB_LINE, (u_long)mp->htab_buckets);
-	(void)fprintf(fp,
-	    "longest chain searched %lu\n", (u_long)mp->stat.st_hash_longest);
-	(void)fprintf(fp, "average chain searched %lu (total/calls: %lu/%lu)\n",
-	    (u_long)mp->stat.st_hash_examined /
-	    (mp->stat.st_hash_searches ? mp->stat.st_hash_searches : 1),
-	    (u_long)mp->stat.st_hash_examined,
-	    (u_long)mp->stat.st_hash_searches);
-	for (htabp = dbmp->htab,
-	    bucket = 0; bucket < mp->htab_buckets; ++htabp, ++bucket) {
-		if (SH_TAILQ_FIRST(&dbmp->htab[bucket], __bh) != NULL)
-			(void)fprintf(fp, "%lu:\n", (u_long)bucket);
-		for (bhp = SH_TAILQ_FIRST(&dbmp->htab[bucket], __bh);
-		    bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh))
-			__memp_pbh(fp, dbmp, bhp, data);
+	if (LF_ISSET(MPOOL_DUMP_HASH)) {
+		(void)fprintf(fp,
+	    "%s\nBH hash table (%lu hash slots)\npageno, file, ref, address\n",
+		    DB_LINE, (u_long)mp->htab_buckets);
+		for (htabp = dbmp->htab,
+		    bucket = 0; bucket < mp->htab_buckets; ++htabp, ++bucket) {
+			if (SH_TAILQ_FIRST(&dbmp->htab[bucket], __bh) != NULL)
+				(void)fprintf(fp, "%lu:\n", (u_long)bucket);
+			for (bhp = SH_TAILQ_FIRST(&dbmp->htab[bucket], __bh);
+			    bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, hq, __bh))
+				__memp_pbh(dbmp, bhp, fmap, fp);
+		}
 	}
 
 	/* Display the LRU list of BH's. */
-	(void)fprintf(fp, "LRU list of BH's (pgno/offset):");
-	for (sep = "\n    ", bhp = SH_TAILQ_FIRST(&dbmp->mp->bhq, __bh);
-	    bhp != NULL; sep = ", ", bhp = SH_TAILQ_NEXT(bhp, q, __bh))
-		(void)fprintf(fp, "%s%lu/%lu", sep,
-		    (u_long)bhp->pgno, (u_long)R_OFFSET(dbmp, bhp));
-	(void)fprintf(fp, "\n");
-}
+	if (LF_ISSET(MPOOL_DUMP_LRU)) {
+		(void)fprintf(fp, "%s\nBH LRU list\n", DB_LINE);
+		(void)fprintf(fp, "pageno, file, ref, address\n");
+		for (bhp = SH_TAILQ_FIRST(&dbmp->mp->bhq, __bh);
+		    bhp != NULL; bhp = SH_TAILQ_NEXT(bhp, q, __bh))
+			__memp_pbh(dbmp, bhp, fmap, fp);
+	}
 
-/*
- * __memp_pmf --
- *	Display an MPOOLFILE structure.
- */
-static void
-__memp_pmf(fp, mfp, data)
-	FILE *fp;
-	MPOOLFILE *mfp;
-	int data;
-{
-	(void)fprintf(fp, "    %lu pages created\n",
-	    (u_long)mfp->stat.st_page_create);
-	(void)fprintf(fp, "    %lu I/O's (%lu read, %lu written)\n",
-	    (u_long)mfp->stat.st_page_in + mfp->stat.st_page_out,
-	    (u_long)mfp->stat.st_page_in, (u_long)mfp->stat.st_page_out);
-	if (mfp->stat.st_cache_hit + mfp->stat.st_cache_miss != 0)
-		(void)fprintf(fp,
-		    "    %.0f%% cache hit rate (%lu hit, %lu miss)\n",
-		    ((double)mfp->stat.st_cache_hit /
-		    (mfp->stat.st_cache_hit + mfp->stat.st_cache_miss)) * 100,
-		    (u_long)mfp->stat.st_cache_hit,
-		    (u_long)mfp->stat.st_cache_miss);
-	if (!data)
-		return;
-
-	(void)fprintf(fp, "    %d references; %s; pagesize: %lu\n", mfp->ref,
-	    F_ISSET(mfp, MP_CAN_MMAP) ? "mmap" : "read/write",
-	    (u_long)mfp->stat.st_pagesize);
+	if (LF_ISSET(MPOOL_DUMP_MEM))
+		__db_shalloc_dump(dbmp->addr, fp);
+
+	UNLOCKREGION(dbmp);
+
+	/* Flush in case we're debugging. */
+	(void)fflush(fp);
 }
 
 /*
@@ -323,28 +270,37 @@ __memp_pmf(fp, mfp, data)
  *	Display a BH structure.
  */
 static void
-__memp_pbh(fp, dbmp, bhp, data)
-	FILE *fp;
+__memp_pbh(dbmp, bhp, fmap, fp)
 	DB_MPOOL *dbmp;
 	BH *bhp;
-	int data;
+	size_t *fmap;
+	FILE *fp;
 {
-	const char *sep;
-
-	if (!data)
-		return;
-
-	(void)fprintf(fp, "    BH @ %lu (mf: %lu): page %lu; ref %lu",
-	    (u_long)R_OFFSET(dbmp, bhp),
-	    (u_long)bhp->mf_offset, (u_long)bhp->pgno, (u_long)bhp->ref);
-	sep = "; ";
-	if (F_ISSET(bhp, BH_DIRTY)) {
-		(void)fprintf(fp, "%sdirty", sep);
-		sep = ", ";
-	}
-	if (F_ISSET(bhp, BH_WRITE)) {
-		(void)fprintf(fp, "%schk_write", sep);
-		sep = ", ";
-	}
+	static const FN fn[] = {
+		{ BH_CALLPGIN,	"callpgin" },
+		{ BH_DIRTY,	"dirty" },
+		{ BH_DISCARD,	"discard" },
+		{ BH_LOCKED,	"locked" },
+		{ BH_TRASH,	"trash" },
+		{ BH_WRITE,	"write" },
+		{ 0 },
+	};
+	int i;
+
+	for (i = 0; i < FMAP_ENTRIES; ++i)
+		if (fmap[i] == INVALID || fmap[i] == bhp->mf_offset)
+			break;
+
+	if (fmap[i] == INVALID)
+		(void)fprintf(fp, "  %4lu, %lu, %2lu, %lu",
+		    (u_long)bhp->pgno, (u_long)bhp->mf_offset,
+		    (u_long)bhp->ref, (u_long)R_OFFSET(dbmp, bhp));
+	else
+		(void)fprintf(fp, "  %4lu,   #%d,  %2lu, %lu",
+		    (u_long)bhp->pgno, i + 1,
+		    (u_long)bhp->ref, (u_long)R_OFFSET(dbmp, bhp));
+
+	__db_prflags(bhp->flags, fn, fp);
+
 	(void)fprintf(fp, "\n");
 }