summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ifs
diff options
context:
space:
mode:
authorguido <guido@FreeBSD.org>1996-10-08 14:54:53 +0000
committerguido <guido@FreeBSD.org>1996-10-08 14:54:53 +0000
commitfa2df9711183d8333b77f915f0f7304e3b408afa (patch)
treee3c11f7e57d19cf474a8603163173ff4ce06bd57 /sbin/fsck_ifs
parentc75b6f83bd908dad24cff37264fcd8c631923f96 (diff)
downloadFreeBSD-src-fa2df9711183d8333b77f915f0f7304e3b408afa.zip
FreeBSD-src-fa2df9711183d8333b77f915f0f7304e3b408afa.tar.gz
Fix the case where fsck would not see sparse directories and the kernel would
panic. If such a thing is fixed fsck needs a rerun (and bugs the user to do so). Reviewed by: Kirk McKusick
Diffstat (limited to 'sbin/fsck_ifs')
-rw-r--r--sbin/fsck_ifs/fsck.h1
-rw-r--r--sbin/fsck_ifs/fsck_ifs.82
-rw-r--r--sbin/fsck_ifs/inode.c60
-rw-r--r--sbin/fsck_ifs/main.c2
4 files changed, 64 insertions, 1 deletions
diff --git a/sbin/fsck_ifs/fsck.h b/sbin/fsck_ifs/fsck.h
index 317052f..57cb17a 100644
--- a/sbin/fsck_ifs/fsck.h
+++ b/sbin/fsck_ifs/fsck.h
@@ -180,6 +180,7 @@ int fsmodified; /* 1 => write done to file system */
int fsreadfd; /* file descriptor for reading file system */
int fswritefd; /* file descriptor for writing file system */
int returntosingle; /* return to single user mode */
+int rerun; /* rerun fsck. Only used in non-preen mode */
daddr_t maxfsblock; /* number of blocks in the file system */
char *blockmap; /* ptr to primary blk allocation map */
diff --git a/sbin/fsck_ifs/fsck_ifs.8 b/sbin/fsck_ifs/fsck_ifs.8
index 364327f..c8ae6fa 100644
--- a/sbin/fsck_ifs/fsck_ifs.8
+++ b/sbin/fsck_ifs/fsck_ifs.8
@@ -249,6 +249,8 @@ File pointing to unallocated inode.
.It
Inode number out of range.
.It
+Holes in directories.
+.It
Dot or dot-dot not the first two entries of a directory
or having the wrong inode number.
.El
diff --git a/sbin/fsck_ifs/inode.c b/sbin/fsck_ifs/inode.c
index 1c9f9b6..5adac75 100644
--- a/sbin/fsck_ifs/inode.c
+++ b/sbin/fsck_ifs/inode.c
@@ -61,6 +61,7 @@ ckinode(dp, idesc)
struct dinode dino;
quad_t remsize, sizepb;
mode_t mode;
+ char pathbuf[MAXPATHLEN + 1];
if (idesc->id_fix != IGNORE)
idesc->id_fix = DONTKNOW;
@@ -78,8 +79,26 @@ ckinode(dp, idesc)
numfrags(&sblock, fragroundup(&sblock, offset));
else
idesc->id_numfrags = sblock.fs_frag;
- if (*ap == 0)
+ if (*ap == 0) {
+ if (idesc->id_type == DATA && ndb >= 0) {
+ /* An empty block in a directory XXX */
+ getpathname(pathbuf, idesc->id_number,
+ idesc->id_number);
+ pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
+ pathbuf);
+ if (reply("ADJUST LENGTH") == 1) {
+ dp = ginode(idesc->id_number);
+ dp->di_size = (ap - &dino.di_db[0]) *
+ sblock.fs_bsize;
+ printf(
+ "YOU MUST RERUN FSCK AFTERWARDS\n");
+ rerun = 1;
+ inodirty();
+
+ }
+ }
continue;
+ }
idesc->id_blkno = *ap;
if (idesc->id_type == ADDR)
ret = (*idesc->id_func)(idesc);
@@ -97,6 +116,24 @@ ckinode(dp, idesc)
ret = iblock(idesc, n, remsize);
if (ret & STOP)
return (ret);
+ } else {
+ if (idesc->id_type == DATA && remsize > 0) {
+ /* An empty block in a directory XXX */
+ getpathname(pathbuf, idesc->id_number,
+ idesc->id_number);
+ pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
+ pathbuf);
+ if (reply("ADJUST LENGTH") == 1) {
+ dp = ginode(idesc->id_number);
+ dp->di_size -= remsize;
+ remsize = 0;
+ printf(
+ "YOU MUST RERUN FSCK AFTERWARDS\n");
+ rerun = 1;
+ inodirty();
+ break;
+ }
+ }
}
sizepb *= NINDIR(&sblock);
remsize -= sizepb;
@@ -116,6 +153,8 @@ iblock(idesc, ilevel, isize)
int i, n, (*func)(), nif;
quad_t sizepb;
char buf[BUFSIZ];
+ char pathbuf[MAXPATHLEN + 1];
+ struct dinode *dp;
if (idesc->id_type == ADDR) {
func = idesc->id_func;
@@ -158,6 +197,25 @@ iblock(idesc, ilevel, isize)
bp->b_flags &= ~B_INUSE;
return (n);
}
+ } else {
+ if (idesc->id_type == DATA && isize > 0) {
+ /* An empty block in a directory XXX */
+ getpathname(pathbuf, idesc->id_number,
+ idesc->id_number);
+ pfatal("DIRECTORY %s: CONTAINS EMPTY BLOCKS",
+ pathbuf);
+ if (reply("ADJUST LENGTH") == 1) {
+ dp = ginode(idesc->id_number);
+ dp->di_size -= isize;
+ isize = 0;
+ printf(
+ "YOU MUST RERUN FSCK AFTERWARDS\n");
+ rerun = 1;
+ inodirty();
+ bp->b_flags &= ~B_INUSE;
+ return(STOP);
+ }
+ }
}
isize -= sizepb;
}
diff --git a/sbin/fsck_ifs/main.c b/sbin/fsck_ifs/main.c
index f2ac7d3..363bba7 100644
--- a/sbin/fsck_ifs/main.c
+++ b/sbin/fsck_ifs/main.c
@@ -310,6 +310,8 @@ checkfilesys(filesys, mntpt, auxdata, child)
return (0);
if (!preen)
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
+ if (rerun)
+ printf("\n***** PLEASE RERUN FSCK *****\n");
if (hotroot) {
struct statfs stfs_buf;
/*
OpenPOWER on IntegriCloud