From owner-svn-src-head@freebsd.org Wed Jan 24 23:57:41 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 43833ECDC01; Wed, 24 Jan 2018 23:57:41 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id E96CB7E4EA; Wed, 24 Jan 2018 23:57:40 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id E011B24995; Wed, 24 Jan 2018 23:57:40 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w0ONvehu047571; Wed, 24 Jan 2018 23:57:40 GMT (envelope-from mckusick@FreeBSD.org) Received: (from mckusick@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w0ONve5P047566; Wed, 24 Jan 2018 23:57:40 GMT (envelope-from mckusick@FreeBSD.org) Message-Id: <201801242357.w0ONve5P047566@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mckusick set sender to mckusick@FreeBSD.org using -f From: Kirk McKusick Date: Wed, 24 Jan 2018 23:57:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r328383 - head/sbin/fsck_ffs X-SVN-Group: head X-SVN-Commit-Author: mckusick X-SVN-Commit-Paths: head/sbin/fsck_ffs X-SVN-Commit-Revision: 328383 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Jan 2018 23:57:41 -0000 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 #include #include +#include #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;