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.
This commit is contained in:
parent
4cfb30ed21
commit
a6bbdf81b5
@ -327,6 +327,7 @@ extern char skipclean; /* skip clean file systems if preening */
|
||||
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 */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
||||
@ -189,29 +188,6 @@ err_suj(const char * restrict fmt, ...)
|
||||
longjmp(jmpbuf, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
@ -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 *actual)
|
||||
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 *actual)
|
||||
}
|
||||
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 @@ suj_read(void)
|
||||
/*
|
||||
* 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, int frags)
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user