[Midnightbsd-cvs] src [9289] trunk/sbin: fsck_ffs -d should track the number, data type and running time of io.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Thu Mar 2 18:07:36 EST 2017


Revision: 9289
          http://svnweb.midnightbsd.org/src/?rev=9289
Author:   laffer1
Date:     2017-03-02 18:07:36 -0500 (Thu, 02 Mar 2017)
Log Message:
-----------
fsck_ffs -d should track the number, data type and running time of io. fsck part 3

Modified Paths:
--------------
    trunk/sbin/fsck_ffs/dir.c
    trunk/sbin/fsck_ffs/ea.c
    trunk/sbin/fsck_ffs/fsck.h
    trunk/sbin/fsck_ffs/fsutil.c
    trunk/sbin/fsck_ffs/inode.c
    trunk/sbin/fsck_ffs/main.c
    trunk/sbin/fsck_ffs/pass1.c
    trunk/sbin/fsck_ffs/pass5.c
    trunk/sbin/fsck_ffs/setup.c
    trunk/sbin/fsck_ffs/suj.c
    trunk/sbin/fsdb/fsdb.c
    trunk/sbin/fsdb/fsdbutil.c

Modified: trunk/sbin/fsck_ffs/dir.c
===================================================================
--- trunk/sbin/fsck_ffs/dir.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsck_ffs/dir.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -708,6 +708,6 @@
 
 	if (pdirbp != 0)
 		pdirbp->b_flags &= ~B_INUSE;
-	pdirbp = getdatablk(blkno, size);
+	pdirbp = getdatablk(blkno, size, BT_DIRDATA);
 	return (pdirbp);
 }

Modified: trunk/sbin/fsck_ffs/ea.c
===================================================================
--- trunk/sbin/fsck_ffs/ea.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsck_ffs/ea.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -73,7 +73,7 @@
 	else
 		blksiz = sblock.fs_bsize;
 	printf("blksiz = %ju\n", (intmax_t)blksiz);
-	bp = getdatablk(dp->di_extb[0], blksiz);
+	bp = getdatablk(dp->di_extb[0], blksiz, BT_EXTATTR);
 	cp = (u_char *)bp->b_un.b_buf;
 	for (n = 0; n < blksiz; n++) {
 		printf("%02x", cp[n]);

Modified: trunk/sbin/fsck_ffs/fsck.h
===================================================================
--- trunk/sbin/fsck_ffs/fsck.h	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsck_ffs/fsck.h	2017-03-02 23:07:36 UTC (rev 9289)
@@ -138,6 +138,7 @@
 	int b_size;
 	int b_errs;
 	int b_flags;
+	int b_type;
 	union {
 		char *b_buf;			/* buffer space */
 		ufs1_daddr_t *b_indir1;		/* UFS1 indirect block */
@@ -165,9 +166,38 @@
  * Buffer flags
  */
 #define	B_INUSE 	0x00000001	/* Buffer is in use */
+/*
+ * Type of data in buffer
+ */
+#define	BT_UNKNOWN 	 0	/* Buffer holds a superblock */
+#define	BT_SUPERBLK 	 1	/* Buffer holds a superblock */
+#define	BT_CYLGRP 	 2	/* Buffer holds a cylinder group map */
+#define	BT_LEVEL1 	 3	/* Buffer holds single level indirect */
+#define	BT_LEVEL2 	 4	/* Buffer holds double level indirect */
+#define	BT_LEVEL3 	 5	/* Buffer holds triple level indirect */
+#define	BT_EXTATTR 	 6	/* Buffer holds external attribute data */
+#define	BT_INODES 	 7	/* Buffer holds external attribute data */
+#define	BT_DIRDATA 	 8	/* Buffer holds directory data */
+#define	BT_DATA	 	 9	/* Buffer holds user data */
+#define BT_NUMBUFTYPES	10
+#define BT_NAMES {			\
+	"unknown",			\
+	"Superblock",			\
+	"Cylinder Group",		\
+	"Single Level Indirect",	\
+	"Double Level Indirect",	\
+	"Triple Level Indirect",	\
+	"External Attribute",		\
+	"Inode Block",			\
+	"Directory Contents",		\
+	"User Data" }
+long readcnt[BT_NUMBUFTYPES];
+long totalreadcnt[BT_NUMBUFTYPES];
+struct timespec readtime[BT_NUMBUFTYPES];
+struct timespec totalreadtime[BT_NUMBUFTYPES];
+struct timespec startprog;
 
 struct bufarea sblk;		/* file system superblock */
-struct bufarea cgblk;		/* cylinder group blocks */
 struct bufarea *pdirbp;		/* current directory contents */
 struct bufarea *pbp;		/* current inode block */
 
@@ -177,16 +207,15 @@
 	else \
 		(bp)->b_dirty = 1; \
 } while (0)
-#define	initbarea(bp) do { \
+#define	initbarea(bp, type) do { \
 	(bp)->b_dirty = 0; \
 	(bp)->b_bno = (ufs2_daddr_t)-1; \
 	(bp)->b_flags = 0; \
+	(bp)->b_type = type; \
 } while (0)
 
 #define	sbdirty()	dirty(&sblk)
-#define	cgdirty()	dirty(&cgblk)
 #define	sblock		(*sblk.b_un.b_fs)
-#define	cgrp		(*cgblk.b_un.b_cg)
 
 enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE};
 ino_t cursnapshot;
@@ -329,6 +358,37 @@
 
 #define	EEXIT	8		/* Standard error exit. */
 
+int flushentry(void);
+/*
+ * Wrapper for malloc() that flushes the cylinder group cache to try 
+ * to get space.
+ */
+static inline void*
+Malloc(int size)
+{
+	void *retval;
+
+	while ((retval = malloc(size)) == NULL)
+		if (flushentry() == 0)
+			break;
+	return (retval);
+}
+
+/*
+ * Wrapper for calloc() that flushes the cylinder group cache to try 
+ * to get space.
+ */
+static inline void*
+Calloc(int cnt, int size)
+{
+	void *retval;
+
+	while ((retval = calloc(cnt, size)) == NULL)
+		if (flushentry() == 0)
+			break;
+	return (retval);
+}
+
 struct fstab;
 
 
@@ -346,7 +406,7 @@
 void		catch(int);
 void		catchquit(int);
 int		changeino(ino_t dir, const char *name, ino_t newnum);
-int		check_cgmagic(int cg, struct cg *cgp);
+int		check_cgmagic(int cg, struct bufarea *cgbp);
 int		chkrange(ufs2_daddr_t blk, int cnt);
 void		ckfini(int markclean);
 int		ckinode(union dinode *dp, struct inodesc *);
@@ -357,6 +417,7 @@
 int		dofix(struct inodesc *, const char *msg);
 int		eascan(struct inodesc *, struct ufs2_dinode *dp);
 void		fileerror(ino_t cwd, ino_t ino, const char *errmesg);
+void		finalIOstats(void);
 int		findino(struct inodesc *);
 int		findname(struct inodesc *);
 void		flush(int fd, struct bufarea *bp);
@@ -365,7 +426,8 @@
 void		freeinodebuf(void);
 int		ftypeok(union dinode *dp);
 void		getblk(struct bufarea *bp, ufs2_daddr_t blk, long size);
-struct bufarea *getdatablk(ufs2_daddr_t blkno, long size);
+struct bufarea *cgget(int cg);
+struct bufarea *getdatablk(ufs2_daddr_t blkno, long size, int type);
 struct inoinfo *getinoinfo(ino_t inumber);
 union dinode   *getnextinode(ino_t inumber, int rebuildcg);
 void		getpathname(char *namebuf, ino_t curdir, ino_t ino);
@@ -375,6 +437,7 @@
 void		inocleanup(void);
 void		inodirty(void);
 struct inostat *inoinfo(ino_t inum);
+void		IOstats(char *what);
 int		linkup(ino_t orphan, ino_t parentdir, char *name);
 int		makeentry(ino_t parent, ino_t ino, const char *name);
 void		panic(const char *fmt, ...) __printflike(1, 2);

Modified: trunk/sbin/fsck_ffs/fsutil.c
===================================================================
--- trunk/sbin/fsck_ffs/fsutil.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsck_ffs/fsutil.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -56,6 +56,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <time.h>
 #include <unistd.h>
 
 #include "fsck.h"
@@ -62,13 +63,17 @@
 
 static void slowio_start(void);
 static void slowio_end(void);
+static void printIOstats(void);
 
-long	diskreads, totalreads;	/* Disk cache statistics */
+static long diskreads, totaldiskreads, totalreads; /* Disk cache statistics */
+static struct timespec startpass, finishpass;
 struct timeval slowio_starttime;
 int slowio_delay_usec = 10000;	/* Initial IO delay for background fsck */
 int slowio_pollcnt;
+static struct bufarea cgblk;	/* backup buffer for cylinder group blocks */
 static TAILQ_HEAD(buflist, bufarea) bufhead;	/* head of buffer cache list */
 static int numbufs;				/* size of buffer cache */
+static char *buftype[BT_NUMBUFTYPES] = BT_NAMES;
 
 int
 ftypeok(union dinode *dp)
@@ -158,18 +163,18 @@
 	char *bufp;
 
 	pbp = pdirbp = (struct bufarea *)0;
-	bufp = malloc((unsigned int)sblock.fs_bsize);
+	bufp = Malloc((unsigned int)sblock.fs_bsize);
 	if (bufp == 0)
 		errx(EEXIT, "cannot allocate buffer pool");
 	cgblk.b_un.b_buf = bufp;
-	initbarea(&cgblk);
+	initbarea(&cgblk, BT_CYLGRP);
 	TAILQ_INIT(&bufhead);
 	bufcnt = MAXBUFS;
 	if (bufcnt < MINBUFS)
 		bufcnt = MINBUFS;
 	for (i = 0; i < bufcnt; i++) {
-		bp = (struct bufarea *)malloc(sizeof(struct bufarea));
-		bufp = malloc((unsigned int)sblock.fs_bsize);
+		bp = (struct bufarea *)Malloc(sizeof(struct bufarea));
+		bufp = Malloc((unsigned int)sblock.fs_bsize);
 		if (bp == NULL || bufp == NULL) {
 			if (i >= MINBUFS)
 				break;
@@ -177,16 +182,72 @@
 		}
 		bp->b_un.b_buf = bufp;
 		TAILQ_INSERT_HEAD(&bufhead, bp, b_list);
-		initbarea(bp);
+		initbarea(bp, BT_UNKNOWN);
 	}
 	numbufs = i;	/* save number of buffers */
+	for (i = 0; i < BT_NUMBUFTYPES; i++) {
+		readtime[i].tv_sec = totalreadtime[i].tv_sec = 0;
+		readtime[i].tv_nsec = totalreadtime[i].tv_nsec = 0;
+		readcnt[i] = totalreadcnt[i] = 0;
+	}
 }
 
 /*
+ * Manage cylinder group buffers.
+ */
+static struct bufarea *cgbufs;	/* header for cylinder group cache */
+static int flushtries;		/* number of tries to reclaim memory */
+
+struct bufarea *
+cgget(int cg)
+{
+	struct bufarea *cgbp;
+	struct cg *cgp;
+
+	if (cgbufs == NULL) {
+		cgbufs = Calloc(sblock.fs_ncg, sizeof(struct bufarea));
+		if (cgbufs == NULL)
+			errx(EEXIT, "cannot allocate cylinder group buffers");
+	}
+	cgbp = &cgbufs[cg];
+	if (cgbp->b_un.b_cg != NULL)
+		return (cgbp);
+	cgp = NULL;
+	if (flushtries == 0)
+		cgp = malloc((unsigned int)sblock.fs_cgsize);
+	if (cgp == NULL) {
+		getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize);
+		return (&cgblk);
+	}
+	cgbp->b_un.b_cg = cgp;
+	initbarea(cgbp, BT_CYLGRP);
+	getblk(cgbp, cgtod(&sblock, cg), sblock.fs_cgsize);
+	return (cgbp);
+}
+
+/*
+ * Attempt to flush a cylinder group cache entry.
+ * Return whether the flush was successful.
+ */
+int
+flushentry(void)
+{
+	struct bufarea *cgbp;
+
+	cgbp = &cgbufs[flushtries++];
+	if (cgbp->b_un.b_cg == NULL)
+		return (0);
+	flush(fswritefd, cgbp);
+	free(cgbp->b_un.b_buf);
+	cgbp->b_un.b_buf = NULL;
+	return (1);
+}
+
+/*
  * Manage a cache of directory blocks.
  */
 struct bufarea *
-getdatablk(ufs2_daddr_t blkno, long size)
+getdatablk(ufs2_daddr_t blkno, long size, int type)
 {
 	struct bufarea *bp;
 
@@ -198,9 +259,13 @@
 			break;
 	if (bp == NULL)
 		errx(EEXIT, "deadlocked buffer pool");
+	bp->b_type = type;
 	getblk(bp, blkno, size);
 	/* fall through */
 foundit:
+	if (debug && bp->b_type != type)
+		printf("Buffer type changed from %s to %s\n",
+		    buftype[bp->b_type], buftype[type]);
 	TAILQ_REMOVE(&bufhead, bp, b_list);
 	TAILQ_INSERT_HEAD(&bufhead, bp, b_list);
 	bp->b_flags |= B_INUSE;
@@ -207,17 +272,49 @@
 	return (bp);
 }
 
+/*
+ * Timespec operations (from <sys/time.h>).
+ */
+#define	timespecsub(vvp, uvp)						\
+	do {								\
+		(vvp)->tv_sec -= (uvp)->tv_sec;				\
+		(vvp)->tv_nsec -= (uvp)->tv_nsec;			\
+		if ((vvp)->tv_nsec < 0) {				\
+			(vvp)->tv_sec--;				\
+			(vvp)->tv_nsec += 1000000000;			\
+		}							\
+	} while (0)
+#define	timespecadd(vvp, uvp)						\
+	do {								\
+		(vvp)->tv_sec += (uvp)->tv_sec;				\
+		(vvp)->tv_nsec += (uvp)->tv_nsec;			\
+		if ((vvp)->tv_nsec >= 1000000000) {			\
+			(vvp)->tv_sec++;				\
+			(vvp)->tv_nsec -= 1000000000;			\
+		}							\
+	} while (0)
+
 void
 getblk(struct bufarea *bp, ufs2_daddr_t blk, long size)
 {
 	ufs2_daddr_t dblk;
+	struct timespec start, finish;
 
-	totalreads++;
 	dblk = fsbtodb(&sblock, blk);
-	if (bp->b_bno != dblk) {
+	if (bp->b_bno == dblk) {
+		totalreads++;
+	} else {
 		flush(fswritefd, bp);
-		diskreads++;
+		if (debug) {
+			readcnt[bp->b_type]++;
+			clock_gettime(CLOCK_REALTIME_PRECISE, &start);
+		}
 		bp->b_errs = blread(fsreadfd, bp->b_un.b_buf, dblk, size);
+		if (debug) {
+			clock_gettime(CLOCK_REALTIME_PRECISE, &finish);
+			timespecsub(&finish, &start);
+			timespecadd(&readtime[bp->b_type], &finish);
+		}
 		bp->b_bno = dblk;
 		bp->b_size = size;
 	}
@@ -291,8 +388,8 @@
 	}
 	if (debug && totalreads > 0)
 		printf("cache with %d buffers missed %ld of %ld (%d%%)\n",
-		    numbufs, diskreads, totalreads,
-		    (int)(diskreads * 100 / totalreads));
+		    numbufs, totaldiskreads, totalreads,
+		    (int)(totaldiskreads * 100 / totalreads));
 	if (fswritefd < 0) {
 		(void)close(fsreadfd);
 		return;
@@ -317,6 +414,13 @@
 	}
 	if (numbufs != cnt)
 		errx(EEXIT, "panic: lost %d buffers", numbufs - cnt);
+	for (cnt = 0; cnt < sblock.fs_ncg; cnt++) {
+		if (cgbufs[cnt].b_un.b_cg == NULL)
+			continue;
+		flush(fswritefd, &cgbufs[cnt]);
+		free(cgbufs[cnt].b_un.b_cg);
+	}
+	free(cgbufs);
 	pbp = pdirbp = (struct bufarea *)0;
 	if (cursnapshot == 0 && sblock.fs_clean != markclean) {
 		if ((sblock.fs_clean = markclean) != 0) {
@@ -346,6 +450,84 @@
 	(void)close(fswritefd);
 }
 
+/*
+ * Print out I/O statistics.
+ */
+void
+IOstats(char *what)
+{
+	int i;
+
+	if (debug == 0)
+		return;
+	if (diskreads == 0) {
+		printf("%s: no I/O\n\n", what);
+		return;
+	}
+	if (startpass.tv_sec == 0)
+		startpass = startprog;
+	printf("%s: I/O statistics\n", what);
+	printIOstats();
+	totaldiskreads += diskreads;
+	diskreads = 0;
+	for (i = 0; i < BT_NUMBUFTYPES; i++) {
+		timespecadd(&totalreadtime[i], &readtime[i]);
+		totalreadcnt[i] += readcnt[i];
+		readtime[i].tv_sec = readtime[i].tv_nsec = 0;
+		readcnt[i] = 0;
+	}
+	clock_gettime(CLOCK_REALTIME_PRECISE, &startpass);
+}
+
+void
+finalIOstats(void)
+{
+	int i;
+
+	if (debug == 0)
+		return;
+	printf("Final I/O statistics\n");
+	totaldiskreads += diskreads;
+	diskreads = totaldiskreads;
+	startpass = startprog;
+	for (i = 0; i < BT_NUMBUFTYPES; i++) {
+		timespecadd(&totalreadtime[i], &readtime[i]);
+		totalreadcnt[i] += readcnt[i];
+		readtime[i] = totalreadtime[i];
+		readcnt[i] = totalreadcnt[i];
+	}
+	printIOstats();
+}
+
+static void printIOstats(void)
+{
+	long long msec, totalmsec;
+	int i;
+
+	clock_gettime(CLOCK_REALTIME_PRECISE, &finishpass);
+	timespecsub(&finishpass, &startpass);
+	printf("Running time: %jd.%03ld sec\n",
+		(intmax_t)finishpass.tv_sec, finishpass.tv_nsec / 1000000);
+	printf("buffer reads by type:\n");
+	for (totalmsec = 0, i = 0; i < BT_NUMBUFTYPES; i++)
+		totalmsec += readtime[i].tv_sec * 1000 +
+		    readtime[i].tv_nsec / 1000000;
+	if (totalmsec == 0)
+		totalmsec = 1;
+	for (i = 0; i < BT_NUMBUFTYPES; i++) {
+		if (readcnt[i] == 0)
+			continue;
+		msec =
+		    readtime[i].tv_sec * 1000 + readtime[i].tv_nsec / 1000000;
+		printf("%21s:%8ld %2ld.%ld%% %4jd.%03ld sec %2lld.%lld%%\n",
+		    buftype[i], readcnt[i], readcnt[i] * 100 / diskreads,
+		    (readcnt[i] * 1000 / diskreads) % 10,
+		    (intmax_t)readtime[i].tv_sec, readtime[i].tv_nsec / 1000000,
+		    msec * 100 / totalmsec, (msec * 1000 / totalmsec) % 10);
+	}
+	printf("\n");
+}
+
 int
 blread(int fd, char *buf, ufs2_daddr_t blk, long size)
 {
@@ -357,6 +539,8 @@
 	offset *= dev_bsize;
 	if (bkgrdflag)
 		slowio_start();
+	totalreads++;
+	diskreads++;
 	if (lseek(fd, offset, 0) < 0)
 		rwerror("SEEK BLK", blk);
 	else if (read(fd, buf, (int)size) == size) {
@@ -438,8 +622,9 @@
  * test fails, offer an option to rebuild the whole cylinder group.
  */
 int
-check_cgmagic(int cg, struct cg *cgp)
+check_cgmagic(int cg, struct bufarea *cgbp)
 {
+	struct cg *cgp = cgbp->b_un.b_cg;
 
 	/*
 	 * Extended cylinder group checks.
@@ -499,7 +684,7 @@
 		cgp->cg_nextfreeoff = cgp->cg_clusteroff +
 		    howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
 	}
-	cgdirty();
+	dirty(cgbp);
 	return (0);
 }
 
@@ -510,7 +695,8 @@
 allocblk(long frags)
 {
 	int i, j, k, cg, baseblk;
-	struct cg *cgp = &cgrp;
+	struct bufarea *cgbp;
+	struct cg *cgp;
 
 	if (frags <= 0 || frags > sblock.fs_frag)
 		return (0);
@@ -526,8 +712,9 @@
 				continue;
 			}
 			cg = dtog(&sblock, i + j);
-			getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize);
-			if (!check_cgmagic(cg, cgp))
+			cgbp = cgget(cg);
+			cgp = cgbp->b_un.b_cg;
+			if (!check_cgmagic(cg, cgbp))
 				return (0);
 			baseblk = dtogd(&sblock, i + j);
 			for (k = 0; k < frags; k++) {
@@ -539,7 +726,7 @@
 				cgp->cg_cs.cs_nbfree--;
 			else
 				cgp->cg_cs.cs_nffree -= frags;
-			cgdirty();
+			dirty(cgbp);
 			return (i + j);
 		}
 	}

Modified: trunk/sbin/fsck_ffs/inode.c
===================================================================
--- trunk/sbin/fsck_ffs/inode.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsck_ffs/inode.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -52,7 +52,7 @@
 
 static ino_t startinum;
 
-static int iblock(struct inodesc *, long ilevel, off_t isize);
+static int iblock(struct inodesc *, long ilevel, off_t isize, int type);
 
 int
 ckinode(union dinode *dp, struct inodesc *idesc)
@@ -121,7 +121,7 @@
 		sizepb *= NINDIR(&sblock);
 		if (DIP(&dino, di_ib[i])) {
 			idesc->id_blkno = DIP(&dino, di_ib[i]);
-			ret = iblock(idesc, i + 1, remsize);
+			ret = iblock(idesc, i + 1, remsize, BT_LEVEL1 + i);
 			if (ret & STOP)
 				return (ret);
 		} else {
@@ -151,7 +151,7 @@
 }
 
 static int
-iblock(struct inodesc *idesc, long ilevel, off_t isize)
+iblock(struct inodesc *idesc, long ilevel, off_t isize, int type)
 {
 	struct bufarea *bp;
 	int i, n, (*func)(struct inodesc *), nif;
@@ -168,7 +168,7 @@
 		func = dirscan;
 	if (chkrange(idesc->id_blkno, idesc->id_numfrags))
 		return (SKIP);
-	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize);
+	bp = getdatablk(idesc->id_blkno, sblock.fs_bsize, type);
 	ilevel--;
 	for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
 		sizepb *= NINDIR(&sblock);
@@ -199,7 +199,7 @@
 			if (ilevel == 0)
 				n = (*func)(idesc);
 			else
-				n = iblock(idesc, ilevel, isize);
+				n = iblock(idesc, ilevel, isize, type);
 			if (n & STOP) {
 				bp->b_flags &= ~B_INUSE;
 				return (n);
@@ -291,7 +291,7 @@
 		iblk = ino_to_fsba(&sblock, inumber);
 		if (pbp != 0)
 			pbp->b_flags &= ~B_INUSE;
-		pbp = getdatablk(iblk, sblock.fs_bsize);
+		pbp = getdatablk(iblk, sblock.fs_bsize, BT_INODES);
 		startinum = (inumber / INOPB(&sblock)) * INOPB(&sblock);
 	}
 	if (sblock.fs_magic == FS_UFS1_MAGIC)
@@ -305,8 +305,8 @@
  * over all the inodes in numerical order.
  */
 static ino_t nextino, lastinum, lastvalidinum;
-static long readcnt, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
-static caddr_t inodebuf;
+static long readcount, readpercg, fullcnt, inobufsize, partialcnt, partialsize;
+static struct bufarea inobuf;
 
 union dinode *
 getnextinode(ino_t inumber, int rebuildcg)
@@ -314,7 +314,7 @@
 	int j;
 	long size;
 	mode_t mode;
-	ufs2_daddr_t ndb, dblk;
+	ufs2_daddr_t ndb, blk;
 	union dinode *dp;
 	static caddr_t nextinop;
 
@@ -321,9 +321,9 @@
 	if (inumber != nextino++ || inumber > lastvalidinum)
 		errx(EEXIT, "bad inode number %d to nextinode", inumber);
 	if (inumber >= lastinum) {
-		readcnt++;
-		dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
-		if (readcnt % readpercg == 0) {
+		readcount++;
+		blk = ino_to_fsba(&sblock, lastinum);
+		if (readcount % readpercg == 0) {
 			size = partialsize;
 			lastinum += partialcnt;
 		} else {
@@ -331,14 +331,14 @@
 			lastinum += fullcnt;
 		}
 		/*
-		 * If blread returns an error, it will already have zeroed
+		 * If getblk encounters an error, it will already have zeroed
 		 * out the buffer, so we do not need to do so here.
 		 */
-		(void)blread(fsreadfd, inodebuf, dblk, size);
-		nextinop = inodebuf;
+		getblk(&inobuf, blk, size);
+		nextinop = inobuf.b_un.b_buf;
 	}
 	dp = (union dinode *)nextinop;
-	if (rebuildcg && nextinop == inodebuf) {
+	if (rebuildcg && nextinop == inobuf.b_un.b_buf) {
 		/*
 		 * Try to determine if we have reached the end of the
 		 * allocated inodes.
@@ -403,8 +403,8 @@
 	startinum = 0;
 	nextino = inum;
 	lastinum = inum;
-	readcnt = 0;
-	if (inodebuf != NULL)
+	readcount = 0;
+	if (inobuf.b_un.b_buf != NULL)
 		return;
 	inobufsize = blkroundup(&sblock, INOBUFSIZE);
 	fullcnt = inobufsize / ((sblock.fs_magic == FS_UFS1_MAGIC) ?
@@ -419,7 +419,8 @@
 		partialcnt = fullcnt;
 		partialsize = inobufsize;
 	}
-	if ((inodebuf = malloc((unsigned)inobufsize)) == NULL)
+	initbarea(&inobuf, BT_INODES);
+	if ((inobuf.b_un.b_buf = Malloc((unsigned)inobufsize)) == NULL)
 		errx(EEXIT, "cannot allocate space for inode buffer");
 }
 
@@ -427,9 +428,9 @@
 freeinodebuf(void)
 {
 
-	if (inodebuf != NULL)
-		free((char *)inodebuf);
-	inodebuf = NULL;
+	if (inobuf.b_un.b_buf != NULL)
+		free((char *)inobuf.b_un.b_buf);
+	inobuf.b_un.b_buf = NULL;
 }
 
 /*
@@ -450,7 +451,7 @@
 	else
 		blks = howmany(DIP(dp, di_size), sblock.fs_bsize);
 	inp = (struct inoinfo *)
-		malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs2_daddr_t));
+		Malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs2_daddr_t));
 	if (inp == NULL)
 		errx(EEXIT, "cannot increase directory list");
 	inpp = &inphead[inumber % dirhash];
@@ -653,7 +654,8 @@
 {
 	ino_t ino;
 	union dinode *dp;
-	struct cg *cgp = &cgrp;
+	struct bufarea *cgbp;
+	struct cg *cgp;
 	int cg;
 
 	if (request == 0)
@@ -666,8 +668,9 @@
 	if (ino == maxino)
 		return (0);
 	cg = ino_to_cg(&sblock, ino);
-	getblk(&cgblk, cgtod(&sblock, cg), sblock.fs_cgsize);
-	if (!check_cgmagic(cg, cgp))
+	cgbp = cgget(cg);
+	cgp = cgbp->b_un.b_cg;
+	if (!check_cgmagic(cg, cgbp))
 		return (0);
 	setbit(cg_inosused(cgp), ino % sblock.fs_ipg);
 	cgp->cg_cs.cs_nifree--;
@@ -683,7 +686,7 @@
 	default:
 		return (0);
 	}
-	cgdirty();
+	dirty(cgbp);
 	dp = ginode(ino);
 	DIP_SET(dp, di_db[0], allocblk((long)1));
 	if (DIP(dp, di_db[0]) == 0) {

Modified: trunk/sbin/fsck_ffs/main.c
===================================================================
--- trunk/sbin/fsck_ffs/main.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsck_ffs/main.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -426,7 +426,9 @@
 			printf("** Root file system\n");
 		printf("** Phase 1 - Check Blocks and Sizes\n");
 	}
+	clock_gettime(CLOCK_REALTIME_PRECISE, &startprog);
 	pass1();
+	IOstats("Pass1");
 
 	/*
 	 * 1b: locate first references to duplicates, if any
@@ -439,6 +441,7 @@
 			    usedsoftdep ? "softupdates" : "");
 		printf("** Phase 1b - Rescan For More DUPS\n");
 		pass1b();
+		IOstats("Pass1b");
 	}
 
 	/*
@@ -447,6 +450,7 @@
 	if (preen == 0)
 		printf("** Phase 2 - Check Pathnames\n");
 	pass2();
+	IOstats("Pass2");
 
 	/*
 	 * 3: scan inodes looking for disconnected directories
@@ -454,6 +458,7 @@
 	if (preen == 0)
 		printf("** Phase 3 - Check Connectivity\n");
 	pass3();
+	IOstats("Pass3");
 
 	/*
 	 * 4: scan inodes looking for disconnected files; check reference counts
@@ -461,6 +466,7 @@
 	if (preen == 0)
 		printf("** Phase 4 - Check Reference Counts\n");
 	pass4();
+	IOstats("Pass4");
 
 	/*
 	 * 5: check and repair resource counts in cylinder groups
@@ -468,6 +474,7 @@
 	if (preen == 0)
 		printf("** Phase 5 - Check Cyl groups\n");
 	pass5();
+	IOstats("Pass5");
 
 	/*
 	 * print out summary statistics
@@ -521,6 +528,7 @@
 	}
 	if (rerun)
 		resolved = 0;
+	finalIOstats();
 
 	/*
 	 * Check to see if the file system is mounted read-write.

Modified: trunk/sbin/fsck_ffs/pass1.c
===================================================================
--- trunk/sbin/fsck_ffs/pass1.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsck_ffs/pass1.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -61,6 +61,8 @@
 {
 	struct inostat *info;
 	struct inodesc idesc;
+	struct bufarea *cgbp;
+	struct cg *cgp;
 	ino_t inumber, inosused, mininos;
 	ufs2_daddr_t i, cgd;
 	u_int8_t *cp;
@@ -92,12 +94,13 @@
 	for (c = 0; c < sblock.fs_ncg; c++) {
 		inumber = c * sblock.fs_ipg;
 		setinodebuf(inumber);
-		getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
+		cgbp = cgget(c);
+		cgp = cgbp->b_un.b_cg;
 		rebuildcg = 0;
-		if (!check_cgmagic(c, &cgrp))
+		if (!check_cgmagic(c, cgbp))
 			rebuildcg = 1;
 		if (!rebuildcg && sblock.fs_magic == FS_UFS2_MAGIC) {
-			inosused = cgrp.cg_initediblk;
+			inosused = cgp->cg_initediblk;
 			if (inosused > sblock.fs_ipg) {
 				pfatal("%s (%d > %d) %s %d\nReset to %d\n",
 				    "Too many initialized inodes", inosused,
@@ -127,7 +130,7 @@
 		 * read only those inodes in from disk.
 		 */
 		if ((preen || inoopt) && usedsoftdep && !rebuildcg) {
-			cp = &cg_inosused(&cgrp)[(inosused - 1) / CHAR_BIT];
+			cp = &cg_inosused(cgp)[(inosused - 1) / CHAR_BIT];
 			for ( ; inosused > 0; inosused -= CHAR_BIT, cp--) {
 				if (*cp == 0)
 					continue;
@@ -149,7 +152,7 @@
 			inostathead[c].il_stat = 0;
 			continue;
 		}
-		info = calloc((unsigned)inosused, sizeof(struct inostat));
+		info = Calloc((unsigned)inosused, sizeof(struct inostat));
 		if (info == NULL)
 			errx(EEXIT, "cannot alloc %u bytes for inoinfo",
 			    (unsigned)(sizeof(struct inostat) * inosused));
@@ -169,7 +172,7 @@
 			 * valid number for this cylinder group.
 			 */
 			if (checkinode(inumber, &idesc, rebuildcg) == 0 &&
-			    i > cgrp.cg_initediblk)
+			    i > cgp->cg_initediblk)
 				break;
 		}
 		/*
@@ -181,16 +184,16 @@
 		mininos = roundup(inosused + INOPB(&sblock), INOPB(&sblock));
 		if (inoopt && !preen && !rebuildcg &&
 		    sblock.fs_magic == FS_UFS2_MAGIC &&
-		    cgrp.cg_initediblk > 2 * INOPB(&sblock) &&
-		    mininos < cgrp.cg_initediblk) {
-			i = cgrp.cg_initediblk;
+		    cgp->cg_initediblk > 2 * INOPB(&sblock) &&
+		    mininos < cgp->cg_initediblk) {
+			i = cgp->cg_initediblk;
 			if (mininos < 2 * INOPB(&sblock))
-				cgrp.cg_initediblk = 2 * INOPB(&sblock);
+				cgp->cg_initediblk = 2 * INOPB(&sblock);
 			else
-				cgrp.cg_initediblk = mininos;
+				cgp->cg_initediblk = mininos;
 			pwarn("CYLINDER GROUP %d: RESET FROM %ju TO %d %s\n",
-			    c, i, cgrp.cg_initediblk, "VALID INODES");
-			cgdirty();
+			    c, i, cgp->cg_initediblk, "VALID INODES");
+			dirty(cgbp);
 		}
 		if (inosused < sblock.fs_ipg)
 			continue;
@@ -199,11 +202,11 @@
 			inosused = 0;
 		else
 			inosused = lastino - (c * sblock.fs_ipg);
-		if (rebuildcg && inosused > cgrp.cg_initediblk &&
+		if (rebuildcg && inosused > cgp->cg_initediblk &&
 		    sblock.fs_magic == FS_UFS2_MAGIC) {
-			cgrp.cg_initediblk = roundup(inosused, INOPB(&sblock));
+			cgp->cg_initediblk = roundup(inosused, INOPB(&sblock));
 			pwarn("CYLINDER GROUP %d: FOUND %d VALID INODES\n", c,
-			    cgrp.cg_initediblk);
+			    cgp->cg_initediblk);
 		}
 		/*
 		 * If we were not able to determine in advance which inodes
@@ -219,7 +222,7 @@
 			inostathead[c].il_stat = 0;
 			continue;
 		}
-		info = calloc((unsigned)inosused, sizeof(struct inostat));
+		info = Calloc((unsigned)inosused, sizeof(struct inostat));
 		if (info == NULL)
 			errx(EEXIT, "cannot alloc %u bytes for inoinfo",
 			    (unsigned)(sizeof(struct inostat) * inosused));
@@ -482,7 +485,7 @@
 				}
 				return (STOP);
 			}
-			new = (struct dups *)malloc(sizeof(struct dups));
+			new = (struct dups *)Malloc(sizeof(struct dups));
 			if (new == NULL) {
 				pfatal("DUP TABLE OVERFLOW.");
 				if (reply("CONTINUE") == 0) {

Modified: trunk/sbin/fsck_ffs/pass5.c
===================================================================
--- trunk/sbin/fsck_ffs/pass5.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsck_ffs/pass5.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -59,7 +59,6 @@
 	int c, i, j, blk, frags, basesize, mapsize;
 	int inomapsize, blkmapsize;
 	struct fs *fs = &sblock;
-	struct cg *cg = &cgrp;
 	ufs2_daddr_t d, dbase, dmax, start;
 	int rewritecg = 0;
 	struct csum *cs;
@@ -66,7 +65,8 @@
 	struct csum_total cstotal;
 	struct inodesc idesc[3];
 	char buf[MAXBSIZE];
-	struct cg *newcg = (struct cg *)buf;
+	struct cg *cg, *newcg = (struct cg *)buf;
+	struct bufarea *cgbp;
 
 	inoinfo(WINO)->ino_state = USTATE;
 	memset(newcg, 0, (size_t)fs->fs_cgsize);
@@ -162,7 +162,8 @@
 			    c * 100 / sblock.fs_ncg);
 			got_sigalarm = 0;
 		}
-		getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize);
+		cgbp = cgget(c);
+		cg = cgbp->b_un.b_cg;
 		if (!cg_chkmagic(cg))
 			pfatal("CG %d: BAD MAGIC NUMBER\n", c);
 		newcg->cg_time = cg->cg_time;
@@ -324,7 +325,7 @@
 		}
 		if (rewritecg) {
 			memmove(cg, newcg, (size_t)fs->fs_cgsize);
-			cgdirty();
+			dirty(cgbp);
 			continue;
 		}
 		if (cursnapshot == 0 &&
@@ -331,7 +332,7 @@
 		    memcmp(newcg, cg, basesize) != 0 &&
 		    dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
 			memmove(cg, newcg, (size_t)basesize);
-			cgdirty();
+			dirty(cgbp);
 		}
 		if (bkgrdflag != 0 || usedsoftdep || debug)
 			update_maps(cg, newcg, bkgrdflag);
@@ -340,7 +341,7 @@
 		    dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
 			memmove(cg_inosused(cg), cg_inosused(newcg),
 			      (size_t)mapsize);
-			cgdirty();
+			dirty(cgbp);
 		}
 	}
 	if (cursnapshot == 0 &&

Modified: trunk/sbin/fsck_ffs/setup.c
===================================================================
--- trunk/sbin/fsck_ffs/setup.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsck_ffs/setup.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -240,7 +240,7 @@
 	 * read in the summary info.
 	 */
 	asked = 0;
-	sblock.fs_csp = calloc(1, sblock.fs_cssize);
+	sblock.fs_csp = Calloc(1, sblock.fs_cssize);
 	if (sblock.fs_csp == NULL) {
 		printf("cannot alloc %u bytes for cg summary info\n",
 		    (unsigned)sblock.fs_cssize);
@@ -249,6 +249,7 @@
 	for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
 		size = sblock.fs_cssize - i < sblock.fs_bsize ?
 		    sblock.fs_cssize - i : sblock.fs_bsize;
+		readcnt[sblk.b_type]++;
 		if (blread(fsreadfd, (char *)sblock.fs_csp + i,
 		    fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
 		    size) != 0 && !asked) {
@@ -264,13 +265,13 @@
 	 * allocate and initialize the necessary maps
 	 */
 	bmapsize = roundup(howmany(maxfsblock, CHAR_BIT), sizeof(short));
-	blockmap = calloc((unsigned)bmapsize, sizeof (char));
+	blockmap = Calloc((unsigned)bmapsize, sizeof (char));
 	if (blockmap == NULL) {
 		printf("cannot alloc %u bytes for blockmap\n",
 		    (unsigned)bmapsize);
 		goto badsb;
 	}
-	inostathead = calloc((unsigned)(sblock.fs_ncg),
+	inostathead = Calloc((unsigned)(sblock.fs_ncg),
 	    sizeof(struct inostatlist));
 	if (inostathead == NULL) {
 		printf("cannot alloc %u bytes for inostathead\n",
@@ -281,9 +282,9 @@
 	dirhash = numdirs;
 	inplast = 0;
 	listmax = numdirs + 10;
-	inpsort = (struct inoinfo **)calloc((unsigned)listmax,
+	inpsort = (struct inoinfo **)Calloc((unsigned)listmax,
 	    sizeof(struct inoinfo *));
-	inphead = (struct inoinfo **)calloc((unsigned)numdirs,
+	inphead = (struct inoinfo **)Calloc((unsigned)numdirs,
 	    sizeof(struct inoinfo *));
 	if (inpsort == NULL || inphead == NULL) {
 		printf("cannot alloc %ju bytes for inphead\n",
@@ -322,6 +323,7 @@
 
 	if (bflag) {
 		super = bflag;
+		readcnt[sblk.b_type]++;
 		if ((blread(fsreadfd, (char *)&sblock, super, (long)SBLOCKSIZE)))
 			return (0);
 		if (sblock.fs_magic == FS_BAD_MAGIC) {
@@ -337,6 +339,7 @@
 	} else {
 		for (i = 0; sblock_try[i] != -1; i++) {
 			super = sblock_try[i] / dev_bsize;
+			readcnt[sblk.b_type]++;
 			if ((blread(fsreadfd, (char *)&sblock, super,
 			    (long)SBLOCKSIZE)))
 				return (0);
@@ -439,10 +442,10 @@
 	fswritefd = -1;
 	fsmodified = 0;
 	lfdir = 0;
-	initbarea(&sblk);
-	initbarea(&asblk);
-	sblk.b_un.b_buf = malloc(SBLOCKSIZE);
-	asblk.b_un.b_buf = malloc(SBLOCKSIZE);
+	initbarea(&sblk, BT_SUPERBLK);
+	initbarea(&asblk, BT_SUPERBLK);
+	sblk.b_un.b_buf = Malloc(SBLOCKSIZE);
+	asblk.b_un.b_buf = Malloc(SBLOCKSIZE);
 	if (sblk.b_un.b_buf == NULL || asblk.b_un.b_buf == NULL)
 		errx(EEXIT, "cannot allocate space for superblock");
 	if ((lp = getdisklabel(NULL, fsreadfd)))

Modified: trunk/sbin/fsck_ffs/suj.c
===================================================================
--- trunk/sbin/fsck_ffs/suj.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsck_ffs/suj.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -161,7 +161,7 @@
 {
 	void *a;
 
-	a = malloc(n);
+	a = Malloc(n);
 	if (a == NULL)
 		err(EX_OSERR, "malloc(%zu)", n);
 	return (a);
@@ -194,7 +194,7 @@
 {
 	if (disk != NULL)
 		return;
-	disk = malloc(sizeof(*disk));
+	disk = Malloc(sizeof(*disk));
 	if (disk == NULL)
 		err(EX_OSERR, "malloc(%zu)", sizeof(*disk));
 	if (ufs_disk_fillout(disk, devnam) == -1) {

Modified: trunk/sbin/fsdb/fsdb.c
===================================================================
--- trunk/sbin/fsdb/fsdb.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsdb/fsdb.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -437,7 +437,8 @@
     ino_t inum, inosused;
     uint32_t *wantedblk32;
     uint64_t *wantedblk64;
-    struct cg *cgp = &cgrp;
+    struct bufarea *cgbp;
+    struct cg *cgp;
     int c, i, is_ufs2;
 
     wantedblksize = (argc - 1);
@@ -469,8 +470,8 @@
 	 */
 	inum = c * sblock.fs_ipg;
 	/* Read cylinder group. */
-	getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
-	memcpy(cgp, cgblk.b_un.b_cg, sblock.fs_cgsize);
+	cgbp = cgget(c);
+	cgp = cgbp->b_un.b_cg;
 	/*
 	 * Get a highest used inode number for a given cylinder group.
 	 * For UFS1 all inodes initialized at the newfs stage.

Modified: trunk/sbin/fsdb/fsdbutil.c
===================================================================
--- trunk/sbin/fsdb/fsdbutil.c	2017-03-02 23:06:07 UTC (rev 9288)
+++ trunk/sbin/fsdb/fsdbutil.c	2017-03-02 23:07:36 UTC (rev 9289)
@@ -241,11 +241,11 @@
 	/* for the final indirect level, don't use the cache */
 	bp = &buf;
 	bp->b_un.b_buf = bufp;
-	initbarea(bp);
+	initbarea(bp, BT_UNKNOWN);
 
 	getblk(bp, blk, sblock.fs_bsize);
     } else
-	bp = getdatablk(blk, sblock.fs_bsize);
+	bp = getdatablk(blk, sblock.fs_bsize, BT_UNKNOWN);
 
     cpl = charsperline();
     for (i = charssofar = 0; i < NINDIR(&sblock); i++) {



More information about the Midnightbsd-cvs mailing list