diff options
author | guido <guido@FreeBSD.org> | 1996-10-08 14:54:53 +0000 |
---|---|---|
committer | guido <guido@FreeBSD.org> | 1996-10-08 14:54:53 +0000 |
commit | fa2df9711183d8333b77f915f0f7304e3b408afa (patch) | |
tree | e3c11f7e57d19cf474a8603163173ff4ce06bd57 /sbin/fsck_ifs | |
parent | c75b6f83bd908dad24cff37264fcd8c631923f96 (diff) | |
download | FreeBSD-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.h | 1 | ||||
-rw-r--r-- | sbin/fsck_ifs/fsck_ifs.8 | 2 | ||||
-rw-r--r-- | sbin/fsck_ifs/inode.c | 60 | ||||
-rw-r--r-- | sbin/fsck_ifs/main.c | 2 |
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; /* |