aboutsummaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ffs
diff options
context:
space:
mode:
authorKirk McKusick <mckusick@FreeBSD.org>2018-11-13 21:40:56 +0000
committerKirk McKusick <mckusick@FreeBSD.org>2018-11-13 21:40:56 +0000
commit9fc5d538fc57f438ca860e07db191b946b4768c9 (patch)
tree0f73178df156f836c4d9dde3af92b526b95c4e72 /sbin/fsck_ffs
parentf183fb162c1dbc58cc3f7e2c27891bd881db2bf2 (diff)
downloadsrc-9fc5d538fc57f438ca860e07db191b946b4768c9.tar.gz
src-9fc5d538fc57f438ca860e07db191b946b4768c9.zip
In preparation for adding inode check-hashes, clean up and
document the libufs interface for fetching and storing inodes. The undocumented getino / putino interface has been replaced with a new getinode / putinode interface. Convert the utilities that had been using the undocumented interface to use the new documented interface. No functional change (as for now the libufs library does not do inode check-hashes). Reviewed by: kib Tested by: Peter Holm Sponsored by: Netflix
Notes
Notes: svn path=/head/; revision=340411
Diffstat (limited to 'sbin/fsck_ffs')
-rw-r--r--sbin/fsck_ffs/dir.c13
-rw-r--r--sbin/fsck_ffs/fsck.h2
-rw-r--r--sbin/fsck_ffs/gjournal.c32
-rw-r--r--sbin/fsck_ffs/inode.c21
-rw-r--r--sbin/fsck_ffs/main.c22
-rw-r--r--sbin/fsck_ffs/pass5.c5
6 files changed, 51 insertions, 44 deletions
diff --git a/sbin/fsck_ffs/dir.c b/sbin/fsck_ffs/dir.c
index a590ee74227b..e923714c3c72 100644
--- a/sbin/fsck_ffs/dir.c
+++ b/sbin/fsck_ffs/dir.c
@@ -254,14 +254,14 @@ fileerror(ino_t cwd, ino_t ino, const char *errmesg)
char pathbuf[MAXPATHLEN + 1];
pwarn("%s ", errmesg);
- pinode(ino);
- printf("\n");
- getpathname(pathbuf, cwd, ino);
if (ino < UFS_ROOTINO || ino > maxino) {
- pfatal("NAME=%s\n", pathbuf);
+ pfatal("out-of-range inode number %ju", (uintmax_t)ino);
return;
}
dp = ginode(ino);
+ prtinode(ino, dp);
+ printf("\n");
+ getpathname(pathbuf, cwd, ino);
if (ftypeok(dp))
pfatal("%s=%s\n",
(DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE",
@@ -309,7 +309,7 @@ adjust(struct inodesc *idesc, int lcnt)
if (lcnt != 0) {
pwarn("LINK COUNT %s", (lfdir == idesc->id_number) ? lfname :
((DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE"));
- pinode(idesc->id_number);
+ prtinode(idesc->id_number, dp);
printf(" COUNT %d SHOULD BE %d",
DIP(dp, di_nlink), DIP(dp, di_nlink) - lcnt);
if (preen || usedsoftdep) {
@@ -390,7 +390,8 @@ linkup(ino_t orphan, ino_t parentdir, char *name)
dp = ginode(orphan);
lostdir = (DIP(dp, di_mode) & IFMT) == IFDIR;
pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");
- pinode(orphan);
+ prtinode(orphan, dp);
+ printf("\n");
if (preen && DIP(dp, di_size) == 0)
return (0);
if (cursnapshot != 0) {
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index cfac25bdfe3d..ffe41be6cf3b 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/fsck.h
@@ -463,8 +463,8 @@ void pass4(void);
int pass4check(struct inodesc *);
void pass5(void);
void pfatal(const char *fmt, ...) __printflike(1, 2);
-void pinode(ino_t ino);
void propagate(void);
+void prtinode(ino_t ino, union dinode *dp);
void pwarn(const char *fmt, ...) __printflike(1, 2);
int readsb(int listerr);
int reply(const char *question);
diff --git a/sbin/fsck_ffs/gjournal.c b/sbin/fsck_ffs/gjournal.c
index 79f670c00567..17361f78a058 100644
--- a/sbin/fsck_ffs/gjournal.c
+++ b/sbin/fsck_ffs/gjournal.c
@@ -392,13 +392,12 @@ clear_inode(struct ufs2_dinode *dino)
void
gjournal_check(const char *filesys)
{
- struct ufs2_dinode *dino;
- void *p;
+ union dinodep dp;
struct cgchain *cgc;
struct cg *cgp;
uint8_t *inosused;
ino_t cino, ino;
- int cg, mode;
+ int cg;
devnam = filesys;
opendisk();
@@ -444,19 +443,20 @@ gjournal_check(const char *filesys)
/* Unallocated? Skip it. */
if (isclr(inosused, cino))
continue;
- if (getino(diskp, &p, ino, &mode) == -1)
- err(1, "getino(cg=%d ino=%ju)",
- cg, (uintmax_t)ino);
- dino = p;
+ if (getinode(diskp, &dp, ino) == -1)
+ err(1, "getinode (cg=%d ino=%ju) %s",
+ cg, (uintmax_t)ino, diskp->d_error);
/* Not a regular file nor directory? Skip it. */
- if (!S_ISREG(dino->di_mode) && !S_ISDIR(dino->di_mode))
+ if (!S_ISREG(dp.dp2->di_mode) &&
+ !S_ISDIR(dp.dp2->di_mode))
continue;
/* Has reference(s)? Skip it. */
- if (dino->di_nlink > 0)
+ if (dp.dp2->di_nlink > 0)
continue;
- //printf("Clearing inode=%d (size=%jd)\n", ino, (intmax_t)dino->di_size);
+ /* printf("Clearing inode=%d (size=%jd)\n", ino,
+ (intmax_t)dp.dp2->di_size); */
/* Free inode's blocks. */
- clear_inode(dino);
+ clear_inode(dp.dp2);
/* Deallocate it. */
clrbit(inosused, cino);
/* Update position of last used inode. */
@@ -469,17 +469,17 @@ gjournal_check(const char *filesys)
cgp->cg_unrefs--;
fs->fs_unrefs--;
/* If this is directory, update related statistics. */
- if (S_ISDIR(dino->di_mode)) {
+ if (S_ISDIR(dp.dp2->di_mode)) {
cgp->cg_cs.cs_ndir--;
fs->fs_cs(fs, cg).cs_ndir--;
fs->fs_cstotal.cs_ndir--;
}
/* Zero-fill the inode. */
- *dino = ufs2_zino;
+ *dp.dp2 = ufs2_zino;
/* Write the inode back. */
- if (putino(diskp) == -1)
- err(1, "putino(cg=%d ino=%ju)",
- cg, (uintmax_t)ino);
+ if (putinode(diskp) == -1)
+ err(1, "putinode (cg=%d ino=%ju) %s",
+ cg, (uintmax_t)ino, diskp->d_error);
if (cgp->cg_unrefs == 0) {
//printf("No more unreferenced inodes in cg=%d.\n", cg);
break;
diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c
index 7cce44953a69..3f1cab8b3bd5 100644
--- a/sbin/fsck_ffs/inode.c
+++ b/sbin/fsck_ffs/inode.c
@@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
#include <pwd.h>
#include <string.h>
#include <time.h>
+#include <libufs.h>
#include "fsck.h"
@@ -342,7 +343,11 @@ getnextinode(ino_t inumber, int rebuildcg)
nextinop = inobuf.b_un.b_buf;
}
dp = (union dinode *)nextinop;
- if (rebuildcg && nextinop == inobuf.b_un.b_buf) {
+ if (sblock.fs_magic == FS_UFS1_MAGIC)
+ nextinop += sizeof(struct ufs1_dinode);
+ else
+ nextinop += sizeof(struct ufs2_dinode);
+ if (rebuildcg && (char *)dp == inobuf.b_un.b_buf) {
/*
* Try to determine if we have reached the end of the
* allocated inodes.
@@ -355,7 +360,7 @@ getnextinode(ino_t inumber, int rebuildcg)
UFS_NIADDR * sizeof(ufs2_daddr_t)) ||
dp->dp2.di_mode || dp->dp2.di_size)
return (NULL);
- goto inodegood;
+ return (dp);
}
if (!ftypeok(dp))
return (NULL);
@@ -389,11 +394,6 @@ getnextinode(ino_t inumber, int rebuildcg)
if (DIP(dp, di_ib[j]) != 0)
return (NULL);
}
-inodegood:
- if (sblock.fs_magic == FS_UFS1_MAGIC)
- nextinop += sizeof(struct ufs1_dinode);
- else
- nextinop += sizeof(struct ufs2_dinode);
return (dp);
}
@@ -534,7 +534,8 @@ clri(struct inodesc *idesc, const char *type, int flag)
if (flag == 1) {
pwarn("%s %s", type,
(DIP(dp, di_mode) & IFMT) == IFDIR ? "DIR" : "FILE");
- pinode(idesc->id_number);
+ prtinode(idesc->id_number, dp);
+ printf("\n");
}
if (preen || reply("CLEAR") == 1) {
if (preen)
@@ -600,9 +601,8 @@ clearentry(struct inodesc *idesc)
}
void
-pinode(ino_t ino)
+prtinode(ino_t ino, union dinode *dp)
{
- union dinode *dp;
char *p;
struct passwd *pw;
time_t t;
@@ -610,7 +610,6 @@ pinode(ino_t ino)
printf(" I=%lu ", (u_long)ino);
if (ino < UFS_ROOTINO || ino > maxino)
return;
- dp = ginode(ino);
printf(" OWNER=");
if ((pw = getpwuid((int)DIP(dp, di_uid))) != NULL)
printf("%s ", pw->pw_name);
diff --git a/sbin/fsck_ffs/main.c b/sbin/fsck_ffs/main.c
index e5118619475b..ce4d0a89a36a 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/main.c
@@ -458,30 +458,40 @@ checkfilesys(char *filesys)
if (preen == 0 && yflag == 0 && sblock.fs_magic != FS_UFS1_MAGIC &&
fswritefd != -1 && getosreldate() >= P_OSREL_CK_CYLGRP) {
if ((sblock.fs_metackhash & CK_CYLGRP) == 0 &&
- reply("ADD CYLINDER GROUP CHECK-HASH PROTECTION") != 0)
+ reply("ADD CYLINDER GROUP CHECK-HASH PROTECTION") != 0) {
ckhashadd |= CK_CYLGRP;
+ sblock.fs_metackhash |= CK_CYLGRP;
+ }
if ((sblock.fs_metackhash & CK_SUPERBLOCK) == 0 &&
getosreldate() >= P_OSREL_CK_SUPERBLOCK &&
reply("ADD SUPERBLOCK CHECK-HASH PROTECTION") != 0) {
+ ckhashadd |= CK_SUPERBLOCK;
sblock.fs_metackhash |= CK_SUPERBLOCK;
- sbdirty();
}
#ifdef notyet
if ((sblock.fs_metackhash & CK_INODE) == 0 &&
getosreldate() >= P_OSREL_CK_INODE &&
- reply("ADD INODE CHECK-HASH PROTECTION") != 0)
+ reply("ADD INODE CHECK-HASH PROTECTION") != 0) {
ckhashadd |= CK_INODE;
+ sblock.fs_metackhash |= CK_INODE;
+ }
if ((sblock.fs_metackhash & CK_INDIR) == 0 &&
getosreldate() >= P_OSREL_CK_INDIR &&
- reply("ADD INDIRECT BLOCK CHECK-HASH PROTECTION") != 0)
+ reply("ADD INDIRECT BLOCK CHECK-HASH PROTECTION") != 0) {
ckhashadd |= CK_INDIR;
+ sblock.fs_metackhash |= CK_INDIR;
+ }
if ((sblock.fs_metackhash & CK_DIR) == 0 &&
getosreldate() >= P_OSREL_CK_DIR &&
- reply("ADD DIRECTORY CHECK-HASH PROTECTION") != 0)
+ reply("ADD DIRECTORY CHECK-HASH PROTECTION") != 0) {
ckhashadd |= CK_DIR;
+ sblock.fs_metackhash |= CK_DIR;
+ }
#endif /* notyet */
- if (ckhashadd != 0)
+ if (ckhashadd != 0) {
sblock.fs_flags |= FS_METACKHASH;
+ sbdirty();
+ }
}
/*
* Cleared if any questions answered no. Used to decide if
diff --git a/sbin/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c
index 71e3eda74c1b..436d184c327b 100644
--- a/sbin/fsck_ffs/pass5.c
+++ b/sbin/fsck_ffs/pass5.c
@@ -74,11 +74,8 @@ pass5(void)
memset(newcg, 0, (size_t)fs->fs_cgsize);
newcg->cg_niblk = fs->fs_ipg;
/* check to see if we are to add a cylinder group check hash */
- if ((ckhashadd & CK_CYLGRP) != 0) {
- fs->fs_metackhash |= CK_CYLGRP;
+ if ((ckhashadd & CK_CYLGRP) != 0)
rewritecg = 1;
- sbdirty();
- }
if (cvtlevel >= 3) {
if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
if (preen)