svn commit: r328383 - head/sbin/fsck_ffs

Kirk McKusick mckusick at FreeBSD.org
Wed Jan 24 23:57:41 UTC 2018


Author: mckusick
Date: Wed Jan 24 23:57:40 2018
New Revision: 328383
URL: https://svnweb.freebsd.org/changeset/base/328383

Log:
  More throughly integrate libufs into fsck_ffs by using its cgput()
  routine to write out the cylinder groups rather than recreating the
  calculation of the cylinder-group check hash in fsck_ffs.
  
  No functional change intended.

Modified:
  head/sbin/fsck_ffs/fsck.h
  head/sbin/fsck_ffs/fsutil.c
  head/sbin/fsck_ffs/gjournal.c
  head/sbin/fsck_ffs/setup.c
  head/sbin/fsck_ffs/suj.c

Modified: head/sbin/fsck_ffs/fsck.h
==============================================================================
--- head/sbin/fsck_ffs/fsck.h	Wed Jan 24 22:36:21 2018	(r328382)
+++ head/sbin/fsck_ffs/fsck.h	Wed Jan 24 23:57:40 2018	(r328383)
@@ -327,6 +327,7 @@ extern char	skipclean;		/* skip clean file systems if 
 extern int	fsmodified;		/* 1 => write done to file system */
 extern int	fsreadfd;		/* file descriptor for reading file system */
 extern int	fswritefd;		/* file descriptor for writing file system */
+extern struct	uufsd disk;		/* libufs user-ufs disk structure */
 extern int	surrender;		/* Give up if reads fail */
 extern int	wantrestart;		/* Restart fsck on early termination */
 

Modified: head/sbin/fsck_ffs/fsutil.c
==============================================================================
--- head/sbin/fsck_ffs/fsutil.c	Wed Jan 24 22:36:21 2018	(r328382)
+++ head/sbin/fsck_ffs/fsutil.c	Wed Jan 24 23:57:40 2018	(r328383)
@@ -352,20 +352,6 @@ flush(int fd, struct bufarea *bp)
 
 	if (!bp->b_dirty)
 		return;
-	/*
-	 * Calculate any needed check hashes.
-	 */
-	switch (bp->b_type) {
-	case BT_CYLGRP:
-		if ((sblock.fs_metackhash & CK_CYLGRP) == 0)
-			break;
-		bp->b_un.b_cg->cg_ckhash = 0;
-		bp->b_un.b_cg->cg_ckhash =
-		    calculate_crc32c(~0L, bp->b_un.b_buf, bp->b_size);
-		break;
-	default:
-		break;
-	}
 	bp->b_dirty = 0;
 	if (fswritefd < 0) {
 		pfatal("WRITING IN READ_ONLY MODE.\n");
@@ -376,13 +362,30 @@ flush(int fd, struct bufarea *bp)
 		    (bp->b_errs == bp->b_size / dev_bsize) ? "" : "PARTIALLY ",
 		    (long long)bp->b_bno);
 	bp->b_errs = 0;
-	blwrite(fd, bp->b_un.b_buf, bp->b_bno, bp->b_size);
-	if (bp != &sblk)
-		return;
-	for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
-		blwrite(fswritefd, (char *)sblock.fs_csp + i,
-		    fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
-		    MIN(sblock.fs_cssize - i, sblock.fs_bsize));
+	/*
+	 * Write using the appropriate function.
+	 */
+	switch (bp->b_type) {
+	case BT_SUPERBLK:
+		if (bp != &sblk)
+			pfatal("BUFFER 0x%x DOES NOT MATCH SBLK 0x%x\n",
+			    (u_int)bp, (u_int)&sblk);
+		blwrite(fd, bp->b_un.b_buf, bp->b_bno, bp->b_size);
+		for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize,
+		   j++) {
+			blwrite(fswritefd, (char *)sblock.fs_csp + i,
+			    fsbtodb(&sblock,
+			    sblock.fs_csaddr + j * sblock.fs_frag),
+			    MIN(sblock.fs_cssize - i, sblock.fs_bsize));
+		}
+		break;
+	case BT_CYLGRP:
+		if (cgput(&disk, (struct cg *)bp->b_un.b_buf) == 0)
+			fsmodified = 1;
+		break;
+	default:
+		blwrite(fd, bp->b_un.b_buf, bp->b_bno, bp->b_size);
+		break;
 	}
 }
 

Modified: head/sbin/fsck_ffs/gjournal.c
==============================================================================
--- head/sbin/fsck_ffs/gjournal.c	Wed Jan 24 22:36:21 2018	(r328382)
+++ head/sbin/fsck_ffs/gjournal.c	Wed Jan 24 23:57:40 2018	(r328383)
@@ -91,7 +91,7 @@ static unsigned ncgs = 0;
 static LIST_HEAD(, cgchain) cglist = LIST_HEAD_INITIALIZER(cglist);
 
 static const char *devnam;
-static struct uufsd *disk = NULL;
+static struct uufsd *diskp = NULL;
 static struct fs *fs = NULL;
 struct ufs2_dinode ufs2_zino;
 
@@ -107,7 +107,7 @@ getcg(int cg)
 {
 	struct cgchain *cgc;
 
-	assert(disk != NULL && fs != NULL);
+	assert(diskp != NULL && fs != NULL);
 	LIST_FOREACH(cgc, &cglist, cgc_next) {
 		if (cgc->cgc_cg.cg_cgx == cg) {
 			//printf("%s: Found cg=%d\n", __func__, cg);
@@ -134,7 +134,7 @@ getcg(int cg)
 		if (cgc == NULL)
 			err(1, "malloc(%zu)", sizeof(*cgc));
 	}
-	if (cgget(disk, cg, &cgc->cgc_cg) == -1)
+	if (cgget(diskp, cg, &cgc->cgc_cg) == -1)
 		err(1, "cgget(%d)", cg);
 	cgc->cgc_busy = 0;
 	cgc->cgc_dirty = 0;
@@ -183,14 +183,14 @@ putcgs(void)
 {
 	struct cgchain *cgc, *cgc2;
 
-	assert(disk != NULL && fs != NULL);
+	assert(diskp != NULL && fs != NULL);
 	LIST_FOREACH_SAFE(cgc, &cglist, cgc_next, cgc2) {
 		if (cgc->cgc_busy)
 			continue;
 		LIST_REMOVE(cgc, cgc_next);
 		ncgs--;
 		if (cgc->cgc_dirty) {
-			if (cgput(disk, &cgc->cgc_cg) == -1)
+			if (cgput(diskp, &cgc->cgc_cg) == -1)
 				err(1, "cgput(%d)", cgc->cgc_cg.cg_cgx);
 			//printf("%s: Wrote cg=%d\n", __func__,
 			//    cgc->cgc_cg.cg_cgx);
@@ -208,7 +208,7 @@ cancelcgs(void)
 {
 	struct cgchain *cgc;
 
-	assert(disk != NULL && fs != NULL);
+	assert(diskp != NULL && fs != NULL);
 	while ((cgc = LIST_FIRST(&cglist)) != NULL) {
 		if (cgc->cgc_busy)
 			continue;
@@ -225,16 +225,14 @@ cancelcgs(void)
 static void
 opendisk(void)
 {
-	if (disk != NULL)
+	if (diskp != NULL)
 		return;
-	disk = malloc(sizeof(*disk));
-	if (disk == NULL)
-		err(1, "malloc(%zu)", sizeof(*disk));
-	if (ufs_disk_fillout(disk, devnam) == -1) {
+	diskp = &disk;
+	if (ufs_disk_fillout(diskp, devnam) == -1) {
 		err(1, "ufs_disk_fillout(%s) failed: %s", devnam,
-		    disk->d_error);
+		    diskp->d_error);
 	}
-	fs = &disk->d_fs;
+	fs = &diskp->d_fs;
 }
 
 /*
@@ -245,12 +243,12 @@ closedisk(void)
 {
 
 	fs->fs_clean = 1;
-	if (sbwrite(disk, 0) == -1)
+	if (sbwrite(diskp, 0) == -1)
 		err(1, "sbwrite(%s)", devnam);
-	if (ufs_disk_close(disk) == -1)
+	if (ufs_disk_close(diskp) == -1)
 		err(1, "ufs_disk_close(%s)", devnam);
-	free(disk);
-	disk = NULL;
+	free(diskp);
+	diskp = NULL;
 	fs = NULL;
 }
 
@@ -328,8 +326,8 @@ freeindir(ufs2_daddr_t blk, int level)
 	ufs2_daddr_t *blks;
 	int i;
 
-	if (bread(disk, fsbtodb(fs, blk), (void *)&sblks, (size_t)fs->fs_bsize) == -1)
-		err(1, "bread: %s", disk->d_error);
+	if (bread(diskp, fsbtodb(fs, blk), (void *)&sblks, (size_t)fs->fs_bsize) == -1)
+		err(1, "bread: %s", diskp->d_error);
 	blks = (ufs2_daddr_t *)&sblks;
 	for (i = 0; i < NINDIR(fs); i++) {
 		if (blks[i] == 0)
@@ -446,7 +444,7 @@ gjournal_check(const char *filesys)
 			/* Unallocated? Skip it. */
 			if (isclr(inosused, cino))
 				continue;
-			if (getino(disk, &p, ino, &mode) == -1)
+			if (getino(diskp, &p, ino, &mode) == -1)
 				err(1, "getino(cg=%d ino=%ju)",
 				    cg, (uintmax_t)ino);
 			dino = p;
@@ -479,7 +477,7 @@ gjournal_check(const char *filesys)
 			/* Zero-fill the inode. */
 			*dino = ufs2_zino;
 			/* Write the inode back. */
-			if (putino(disk) == -1)
+			if (putino(diskp) == -1)
 				err(1, "putino(cg=%d ino=%ju)",
 				    cg, (uintmax_t)ino);
 			if (cgp->cg_unrefs == 0) {

Modified: head/sbin/fsck_ffs/setup.c
==============================================================================
--- head/sbin/fsck_ffs/setup.c	Wed Jan 24 22:36:21 2018	(r328382)
+++ head/sbin/fsck_ffs/setup.c	Wed Jan 24 23:57:40 2018	(r328383)
@@ -54,9 +54,11 @@ __FBSDID("$FreeBSD$");
 #include <limits.h>
 #include <stdint.h>
 #include <string.h>
+#include <libufs.h>
 
 #include "fsck.h"
 
+struct uufsd disk;
 struct bufarea asblk;
 #define altsblock (*asblk.b_un.b_fs)
 #define POWEROF2(num)	(((num) & ((num) - 1)) == 0)
@@ -124,7 +126,8 @@ setup(char *dev)
 			}
 		}
 	}
-	if ((fsreadfd = open(dev, O_RDONLY)) < 0) {
+	if ((fsreadfd = open(dev, O_RDONLY)) < 0 ||
+	    ufs_disk_fillout(&disk, dev) < 0) {
 		if (bkgrdflag) {
 			unlink(snapname);
 			bkgrdflag = 0;
@@ -168,7 +171,8 @@ setup(char *dev)
 	if (preen == 0)
 		printf("** %s", dev);
 	if (bkgrdflag == 0 &&
-	    (nflag || (fswritefd = open(dev, O_WRONLY)) < 0)) {
+	    (nflag || ufs_disk_write(&disk) < 0 ||
+	     (fswritefd = dup(disk.d_fd)) < 0)) {
 		fswritefd = -1;
 		if (preen)
 			pfatal("NO WRITE ACCESS");

Modified: head/sbin/fsck_ffs/suj.c
==============================================================================
--- head/sbin/fsck_ffs/suj.c	Wed Jan 24 22:36:21 2018	(r328382)
+++ head/sbin/fsck_ffs/suj.c	Wed Jan 24 23:57:40 2018	(r328383)
@@ -134,7 +134,6 @@ static struct data_blk *lastblk;
 
 static TAILQ_HEAD(seghd, suj_seg) allsegs;
 static uint64_t oldseq;
-static struct uufsd *disk = NULL;
 static struct fs *fs = NULL;
 static ino_t sujino;
 
@@ -190,29 +189,6 @@ err_suj(const char * restrict fmt, ...)
 }
 
 /*
- * Open the given provider, load superblock.
- */
-static void
-opendisk(const char *devnam)
-{
-	if (disk != NULL)
-		return;
-	disk = Malloc(sizeof(*disk));
-	if (disk == NULL)
-		err(EX_OSERR, "malloc(%zu)", sizeof(*disk));
-	if (ufs_disk_fillout(disk, devnam) == -1) {
-		err(EX_OSERR, "ufs_disk_fillout(%s) failed: %s", devnam,
-		    disk->d_error);
-	}
-	fs = &disk->d_fs;
-	if (real_dev_bsize == 0 && ioctl(disk->d_fd, DIOCGSECTORSIZE,
-	    &real_dev_bsize) == -1)
-		real_dev_bsize = secsize;
-	if (debug)
-		printf("dev_bsize %u\n", real_dev_bsize);
-}
-
-/*
  * Mark file system as clean, write the super-block back, close the disk.
  */
 static void
@@ -237,12 +213,10 @@ closedisk(const char *devnam)
 	fs->fs_clean = 1;
 	fs->fs_time = time(NULL);
 	fs->fs_mtime = time(NULL);
-	if (sbwrite(disk, 0) == -1)
+	if (sbwrite(&disk, 0) == -1)
 		err(EX_OSERR, "sbwrite(%s)", devnam);
-	if (ufs_disk_close(disk) == -1)
+	if (ufs_disk_close(&disk) == -1)
 		err(EX_OSERR, "ufs_disk_close(%s)", devnam);
-	free(disk);
-	disk = NULL;
 	fs = NULL;
 }
 
@@ -272,7 +246,11 @@ cg_lookup(int cgx)
 	sc->sc_cgp = (struct cg *)sc->sc_cgbuf;
 	sc->sc_cgx = cgx;
 	LIST_INSERT_HEAD(hd, sc, sc_next);
-	if (bread(disk, fsbtodb(fs, cgtod(fs, sc->sc_cgx)), sc->sc_cgbuf,
+	/*
+	 * Use bread() here rather than cgget() because the cylinder group
+	 * may be corrupted but we want it anyway so we can fix it.
+	 */
+	if (bread(&disk, fsbtodb(fs, cgtod(fs, sc->sc_cgx)), sc->sc_cgbuf,
 	    fs->fs_bsize) == -1)
 		err_suj("Unable to read cylinder group %d\n", sc->sc_cgx);
 
@@ -376,7 +354,7 @@ dblk_read(ufs2_daddr_t blk, int size)
 			free(dblk->db_buf);
 		dblk->db_buf = errmalloc(size);
 		dblk->db_size = size;
-		if (bread(disk, fsbtodb(fs, blk), dblk->db_buf, size) == -1)
+		if (bread(&disk, fsbtodb(fs, blk), dblk->db_buf, size) == -1)
 			err_suj("Failed to read data block %jd\n", blk);
 	}
 	return (dblk->db_buf);
@@ -401,7 +379,7 @@ dblk_write(void)
 		LIST_FOREACH(dblk, &dbhash[i], db_next) {
 			if (dblk->db_dirty == 0 || dblk->db_size == 0)
 				continue;
-			if (bwrite(disk, fsbtodb(fs, dblk->db_blk),
+			if (bwrite(&disk, fsbtodb(fs, dblk->db_blk),
 			    dblk->db_buf, dblk->db_size) == -1)
 				err_suj("Unable to write block %jd\n",
 				    dblk->db_blk);
@@ -435,7 +413,7 @@ ino_read(ino_t ino)
 	iblk->ib_buf = errmalloc(fs->fs_bsize);
 	iblk->ib_blk = blk;
 	LIST_INSERT_HEAD(hd, iblk, ib_next);
-	if (bread(disk, fsbtodb(fs, blk), iblk->ib_buf, fs->fs_bsize) == -1)
+	if (bread(&disk, fsbtodb(fs, blk), iblk->ib_buf, fs->fs_bsize) == -1)
 		err_suj("Failed to read inode block %jd\n", blk);
 found:
 	sc->sc_lastiblk = iblk;
@@ -478,7 +456,7 @@ iblk_write(struct ino_blk *iblk)
 
 	if (iblk->ib_dirty == 0)
 		return;
-	if (bwrite(disk, fsbtodb(fs, iblk->ib_blk), iblk->ib_buf,
+	if (bwrite(&disk, fsbtodb(fs, iblk->ib_blk), iblk->ib_buf,
 	    fs->fs_bsize) == -1)
 		err_suj("Failed to write inode block %jd\n", iblk->ib_blk);
 }
@@ -1892,7 +1870,7 @@ cg_write(struct suj_cg *sc)
 	 * before writing the block.
 	 */
 	fs->fs_cs(fs, sc->sc_cgx) = cgp->cg_cs;
-	if (cgput(disk, cgp) == -1)
+	if (cgput(&disk, cgp) == -1)
 		err_suj("Unable to write cylinder group %d\n", sc->sc_cgx);
 }
 
@@ -2457,7 +2435,7 @@ jblocks_next(struct jblocks *jblocks, int bytes, int *
 	int freecnt;
 	int blocks;
 
-	blocks = bytes / disk->d_bsize;
+	blocks = bytes / disk.d_bsize;
 	jext = &jblocks->jb_extent[jblocks->jb_head];
 	freecnt = jext->je_blocks - jblocks->jb_off;
 	if (freecnt == 0) {
@@ -2469,7 +2447,7 @@ jblocks_next(struct jblocks *jblocks, int bytes, int *
 	}
 	if (freecnt > blocks)
 		freecnt = blocks;
-	*actual = freecnt * disk->d_bsize;
+	*actual = freecnt * disk.d_bsize;
 	daddr = jext->je_daddr + jblocks->jb_off;
 
 	return (daddr);
@@ -2483,7 +2461,7 @@ static void
 jblocks_advance(struct jblocks *jblocks, int bytes)
 {
 
-	jblocks->jb_off += bytes / disk->d_bsize;
+	jblocks->jb_off += bytes / disk.d_bsize;
 }
 
 static void
@@ -2574,7 +2552,7 @@ restart:
 		/*
 		 * Read 1MB at a time and scan for records within this block.
 		 */
-		if (bread(disk, blk, &block, size) == -1) {
+		if (bread(&disk, blk, &block, size) == -1) {
 			err_suj("Error reading journal block %jd\n",
 			    (intmax_t)blk);
 		}
@@ -2655,7 +2633,7 @@ suj_find(ino_t ino, ufs_lbn_t lbn, ufs2_daddr_t blk, i
 	if (sujino)
 		return;
 	bytes = lfragtosize(fs, frags);
-	if (bread(disk, fsbtodb(fs, blk), block, bytes) <= 0)
+	if (bread(&disk, fsbtodb(fs, blk), block, bytes) <= 0)
 		err_suj("Failed to read UFS_ROOTINO directory block %jd\n",
 		    blk);
 	for (off = 0; off < bytes; off += dp->d_reclen) {
@@ -2687,7 +2665,12 @@ suj_check(const char *filesys)
 	struct suj_seg *segn;
 
 	initsuj();
-	opendisk(filesys);
+	fs = &sblock;
+	if (real_dev_bsize == 0 && ioctl(disk.d_fd, DIOCGSECTORSIZE,
+	    &real_dev_bsize) == -1)
+		real_dev_bsize = secsize;
+	if (debug)
+		printf("dev_bsize %u\n", real_dev_bsize);
 
 	/*
 	 * Set an exit point when SUJ check failed
@@ -2790,7 +2773,6 @@ initsuj(void)
 	lastblk = NULL;
 	TAILQ_INIT(&allsegs);
 	oldseq = 0;
-	disk = NULL;
 	fs = NULL;
 	sujino = 0;
 	freefrags = 0;


More information about the svn-src-head mailing list