aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/dumpfs/dumpfs.c18
-rw-r--r--sbin/fsck_ffs/fsutil.c15
-rw-r--r--sbin/fsck_ffs/pass5.c13
-rw-r--r--sbin/fsdb/Makefile2
-rw-r--r--sbin/newfs/mkfs.c23
5 files changed, 70 insertions, 1 deletions
diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c
index cea9a95ba4ae..e163b4b69747 100644
--- a/sbin/dumpfs/dumpfs.c
+++ b/sbin/dumpfs/dumpfs.c
@@ -276,6 +276,24 @@ dumpfs(const char *name)
if (fsflags != 0)
printf("unknown flags (%#x)", fsflags);
putchar('\n');
+ printf("check hashes\t");
+ fsflags = afs.fs_metackhash;
+ if (fsflags == 0)
+ printf("none");
+ if (fsflags & CK_SUPERBLOCK)
+ printf("superblock ");
+ if (fsflags & CK_CYLGRP)
+ printf("cylinder-groups ");
+ if (fsflags & CK_INODE)
+ printf("inodes ");
+ if (fsflags & CK_INDIR)
+ printf("indirect-blocks ");
+ if (fsflags & CK_DIR)
+ printf("directories ");
+ fsflags &= ~(CK_SUPERBLOCK | CK_CYLGRP | CK_INODE | CK_INDIR | CK_DIR);
+ if (fsflags != 0)
+ printf("unknown flags (%#x)", fsflags);
+ putchar('\n');
printf("fsmnt\t%s\n", afs.fs_fsmnt);
printf("volname\t%s\tswuid\t%ju\tprovidersize\t%ju\n",
afs.fs_volname, (uintmax_t)afs.fs_swuid,
diff --git a/sbin/fsck_ffs/fsutil.c b/sbin/fsck_ffs/fsutil.c
index f4da123b18f9..16d960d155af 100644
--- a/sbin/fsck_ffs/fsutil.c
+++ b/sbin/fsck_ffs/fsutil.c
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
+#include <libufs.h>
#include "fsck.h"
@@ -349,6 +350,20 @@ 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");
diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c
index ef289c4342ac..16c46bece00b 100644
--- a/sbin/fsck_ffs/pass5.c
+++ b/sbin/fsck_ffs/pass5.c
@@ -71,6 +71,13 @@ pass5(void)
inoinfo(UFS_WINO)->ino_state = USTATE;
memset(newcg, 0, (size_t)fs->fs_cgsize);
newcg->cg_niblk = fs->fs_ipg;
+ if (preen == 0 && yflag == 0 && fs->fs_magic == FS_UFS2_MAGIC &&
+ fswritefd != -1 && (fs->fs_metackhash & CK_CYLGRP) == 0 &&
+ reply("ADD CYLINDER GROUP CHECKSUM PROTECTION") != 0) {
+ fs->fs_metackhash |= CK_CYLGRP;
+ rewritecg = 1;
+ sbdirty();
+ }
if (cvtlevel >= 3) {
if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
if (preen)
@@ -305,6 +312,12 @@ pass5(void)
sump[run]++;
}
}
+ if ((fs->fs_metackhash & CK_CYLGRP) != 0) {
+ newcg->cg_ckhash = 0;
+ newcg->cg_ckhash =
+ calculate_crc32c(~0L, (void *)newcg, fs->fs_cgsize);
+ }
+
if (bkgrdflag != 0) {
cstotal.cs_nffree += cg->cg_cs.cs_nffree;
cstotal.cs_nbfree += cg->cg_cs.cs_nbfree;
diff --git a/sbin/fsdb/Makefile b/sbin/fsdb/Makefile
index a3e7545c7c5a..96b93cd1690b 100644
--- a/sbin/fsdb/Makefile
+++ b/sbin/fsdb/Makefile
@@ -10,7 +10,7 @@ SRCS= fsdb.c fsdbutil.c \
pass5.c setup.c utilities.c ffs_subr.c ffs_tables.c globs.c
CFLAGS+= -I${.CURDIR:H}/fsck_ffs
WARNS?= 2
-LIBADD= edit
+LIBADD= edit ufs
.PATH: ${.CURDIR:H}/fsck_ffs ${SRCTOP}/sys/ufs/ffs
.include <bsd.prog.mk>
diff --git a/sbin/newfs/mkfs.c b/sbin/newfs/mkfs.c
index dbfab4536bd6..f68c42ec6b36 100644
--- a/sbin/newfs/mkfs.c
+++ b/sbin/newfs/mkfs.c
@@ -98,6 +98,7 @@ static void iput(union dinode *, ino_t);
static int makedir(struct direct *, int);
static void setblock(struct fs *, unsigned char *, int);
static void wtfs(ufs2_daddr_t, int, char *);
+static void cgckhash(struct cg *);
static u_int32_t newfs_random(void);
static int
@@ -491,6 +492,11 @@ restart:
sblock.fs_old_cstotal.cs_nifree = sblock.fs_cstotal.cs_nifree;
sblock.fs_old_cstotal.cs_nffree = sblock.fs_cstotal.cs_nffree;
}
+ /*
+ * Set flags for metadata that is being check-hashed.
+ */
+ if (Oflag > 1)
+ sblock.fs_metackhash = CK_CYLGRP;
/*
* Dump out summary information about file system.
@@ -791,6 +797,7 @@ initcg(int cylno, time_t utime)
}
}
*cs = acg.cg_cs;
+ cgckhash(&acg);
/*
* Write out the duplicate super block, the cylinder group map
* and two blocks worth of inodes in a single write.
@@ -1006,6 +1013,7 @@ goth:
setbit(cg_blksfree(&acg), d + i);
}
/* XXX cgwrite(&disk, 0)??? */
+ cgckhash(&acg);
wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize,
(char *)&acg);
return ((ufs2_daddr_t)d);
@@ -1027,6 +1035,7 @@ iput(union dinode *ip, ino_t ino)
}
acg.cg_cs.cs_nifree--;
setbit(cg_inosused(&acg), ino);
+ cgckhash(&acg);
wtfs(fsbtodb(&sblock, cgtod(&sblock, 0)), sblock.fs_cgsize,
(char *)&acg);
sblock.fs_cstotal.cs_nifree--;
@@ -1060,6 +1069,20 @@ wtfs(ufs2_daddr_t bno, int size, char *bf)
}
/*
+ * Calculate the check-hash of the cylinder group.
+ */
+static void
+cgckhash(cgp)
+ struct cg *cgp;
+{
+
+ if ((sblock.fs_metackhash & CK_CYLGRP) == 0)
+ return;
+ cgp->cg_ckhash = 0;
+ cgp->cg_ckhash = calculate_crc32c(~0L, (void *)cgp, sblock.fs_cgsize);
+}
+
+/*
* check if a block is available
*/
static int