summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/fsck/SMM.doc/0.t2
-rw-r--r--sbin/fsck/SMM.doc/3.t13
-rw-r--r--sbin/fsck/fsck.82
-rw-r--r--sbin/fsck/fsck.h1
-rw-r--r--sbin/fsck/inode.c60
-rw-r--r--sbin/fsck/main.c2
-rw-r--r--sbin/fsck_ffs/SMM.doc/0.t2
-rw-r--r--sbin/fsck_ffs/SMM.doc/3.t13
-rw-r--r--sbin/fsck_ffs/fsck.h1
-rw-r--r--sbin/fsck_ffs/fsck_ffs.82
-rw-r--r--sbin/fsck_ffs/inode.c60
-rw-r--r--sbin/fsck_ffs/main.c2
-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
16 files changed, 220 insertions, 5 deletions
diff --git a/sbin/fsck/SMM.doc/0.t b/sbin/fsck/SMM.doc/0.t
index 9de391e..528dd96 100644
--- a/sbin/fsck/SMM.doc/0.t
+++ b/sbin/fsck/SMM.doc/0.t
@@ -94,7 +94,7 @@ Both the program and the interaction between the
program and the operator are described.
.sp 2
.LP
-Revised July 16, 1985
+Revised October 7, 1996
.AE
.LP
.bp
diff --git a/sbin/fsck/SMM.doc/3.t b/sbin/fsck/SMM.doc/3.t
index 07b5431..bb6f05b 100644
--- a/sbin/fsck/SMM.doc/3.t
+++ b/sbin/fsck/SMM.doc/3.t
@@ -344,6 +344,19 @@ will remove that directory entry.
Again,
this condition can only arise when there has been a hardware failure.
.PP
+.I Fsck
+also checks for directories with unallocated blocks (holes).
+Such directories should never be created.
+When found,
+.I fsck
+will prompt the user to adjust the length of the offending directory
+which is done by shortening the size of the directory to the end of the
+last allocated block preceeding the hole.
+Unfortunately, this means that another Phase 1 run has to be done.
+.I Fsck
+will remind the user to rerun fsck after repairing a
+directory containing an unallocated block.
+.PP
If a directory entry inode number references
outside the inode list, then
.I fsck
diff --git a/sbin/fsck/fsck.8 b/sbin/fsck/fsck.8
index 364327f..c8ae6fa 100644
--- a/sbin/fsck/fsck.8
+++ b/sbin/fsck/fsck.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/fsck.h b/sbin/fsck/fsck.h
index 317052f..57cb17a 100644
--- a/sbin/fsck/fsck.h
+++ b/sbin/fsck/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/inode.c b/sbin/fsck/inode.c
index 1c9f9b6..5adac75 100644
--- a/sbin/fsck/inode.c
+++ b/sbin/fsck/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/main.c b/sbin/fsck/main.c
index f2ac7d3..363bba7 100644
--- a/sbin/fsck/main.c
+++ b/sbin/fsck/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;
/*
diff --git a/sbin/fsck_ffs/SMM.doc/0.t b/sbin/fsck_ffs/SMM.doc/0.t
index 9de391e..528dd96 100644
--- a/sbin/fsck_ffs/SMM.doc/0.t
+++ b/sbin/fsck_ffs/SMM.doc/0.t
@@ -94,7 +94,7 @@ Both the program and the interaction between the
program and the operator are described.
.sp 2
.LP
-Revised July 16, 1985
+Revised October 7, 1996
.AE
.LP
.bp
diff --git a/sbin/fsck_ffs/SMM.doc/3.t b/sbin/fsck_ffs/SMM.doc/3.t
index 07b5431..bb6f05b 100644
--- a/sbin/fsck_ffs/SMM.doc/3.t
+++ b/sbin/fsck_ffs/SMM.doc/3.t
@@ -344,6 +344,19 @@ will remove that directory entry.
Again,
this condition can only arise when there has been a hardware failure.
.PP
+.I Fsck
+also checks for directories with unallocated blocks (holes).
+Such directories should never be created.
+When found,
+.I fsck
+will prompt the user to adjust the length of the offending directory
+which is done by shortening the size of the directory to the end of the
+last allocated block preceeding the hole.
+Unfortunately, this means that another Phase 1 run has to be done.
+.I Fsck
+will remind the user to rerun fsck after repairing a
+directory containing an unallocated block.
+.PP
If a directory entry inode number references
outside the inode list, then
.I fsck
diff --git a/sbin/fsck_ffs/fsck.h b/sbin/fsck_ffs/fsck.h
index 317052f..57cb17a 100644
--- a/sbin/fsck_ffs/fsck.h
+++ b/sbin/fsck_ffs/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_ffs/fsck_ffs.8 b/sbin/fsck_ffs/fsck_ffs.8
index 364327f..c8ae6fa 100644
--- a/sbin/fsck_ffs/fsck_ffs.8
+++ b/sbin/fsck_ffs/fsck_ffs.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_ffs/inode.c b/sbin/fsck_ffs/inode.c
index 1c9f9b6..5adac75 100644
--- a/sbin/fsck_ffs/inode.c
+++ b/sbin/fsck_ffs/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_ffs/main.c b/sbin/fsck_ffs/main.c
index f2ac7d3..363bba7 100644
--- a/sbin/fsck_ffs/main.c
+++ b/sbin/fsck_ffs/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;
/*
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