[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