aboutsummaryrefslogtreecommitdiff
path: root/sbin/fsck_ifs/inode.c
diff options
context:
space:
mode:
authorJulian Elischer <julian@FreeBSD.org>1998-12-03 02:27:35 +0000
committerJulian Elischer <julian@FreeBSD.org>1998-12-03 02:27:35 +0000
commitd33e92f93e2ed9f0bec931917cc23c03c8b5a378 (patch)
treec68b2f7c5232d6013783c8637a106e69396adccc /sbin/fsck_ifs/inode.c
parent233fbe28b0a766be5dd3b15f4f8c8c6056c81c68 (diff)
downloadsrc-d33e92f93e2ed9f0bec931917cc23c03c8b5a378.tar.gz
src-d33e92f93e2ed9f0bec931917cc23c03c8b5a378.zip
Reviewed by: Don Lewis <Don.Lewis@tsc.tdk.com>
Submitted by: Kirk McKusick <mckusick@McKusick.COM> Obtained from: Mckusick, BSDI and a host of others This exactly matches Kirks sources imported under the Tag MCKUSICK2. These are as supplied by kirk with one small change needed to compile under freeBSD. Some FreeBSD patches will be added back, though many have been added to Kirk's sources already.
Notes
Notes: svn path=/head/; revision=41474
Diffstat (limited to 'sbin/fsck_ifs/inode.c')
-rw-r--r--sbin/fsck_ifs/inode.c92
1 files changed, 58 insertions, 34 deletions
diff --git a/sbin/fsck_ifs/inode.c b/sbin/fsck_ifs/inode.c
index b7e80cdffaa6..a54f2ce3d265 100644
--- a/sbin/fsck_ifs/inode.c
+++ b/sbin/fsck_ifs/inode.c
@@ -32,11 +32,7 @@
*/
#ifndef lint
-#if 0
static const char sccsid[] = "@(#)inode.c 8.8 (Berkeley) 4/28/95";
-#endif
-static const char rcsid[] =
- "$Id: inode.c,v 1.15 1998/06/28 19:23:02 bde Exp $";
#endif /* not lint */
#include <sys/param.h>
@@ -62,7 +58,8 @@ ckinode(dp, idesc)
register struct inodesc *idesc;
{
ufs_daddr_t *ap;
- long ret, n, ndb, offset;
+ int ret;
+ long n, ndb, offset;
struct dinode dino;
quad_t remsize, sizepb;
mode_t mode;
@@ -74,7 +71,7 @@ ckinode(dp, idesc)
idesc->id_filesize = dp->di_size;
mode = dp->di_mode & IFMT;
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
- (dp->di_size < sblock.fs_maxsymlinklen || dp->di_blocks == 0)))
+ dp->di_size < (unsigned)sblock.fs_maxsymlinklen))
return (KEEPON);
dino = *dp;
ndb = howmany(dino.di_size, sblock.fs_bsize);
@@ -239,8 +236,16 @@ chkrange(blk, cnt)
{
register int c;
- if (blk < 0 || blk >= maxfsblock || cnt < 0 || cnt > maxfsblock - blk)
+ if (cnt <= 0 || blk <= 0 || blk > maxfsblock ||
+ cnt - 1 > maxfsblock - blk)
return (1);
+ if (cnt > sblock.fs_frag ||
+ fragnum(&sblock, blk) + cnt > sblock.fs_frag) {
+ if (debug)
+ printf("bad size: blk %ld, offset %ld, size %ld\n",
+ blk, fragnum(&sblock, blk), cnt);
+ return (1);
+ }
c = dtog(&sblock, blk);
if (blk < cgdmin(&sblock, c)) {
if ((blk + cnt) > cgsblock(&sblock, c)) {
@@ -317,20 +322,29 @@ getnextinode(inumber)
size = inobufsize;
lastinum += fullcnt;
}
- (void)bread(fsreadfd, (char *)inodebuf, dblk, size); /* ??? */
+ /*
+ * If bread returns an error, it will already have zeroed
+ * out the buffer, so we do not need to do so here.
+ */
+ (void)bread(fsreadfd, (char *)inodebuf, dblk, size);
dp = inodebuf;
}
return (dp++);
}
void
-resetinodebuf()
+setinodebuf(inum)
+ ino_t inum;
{
+ if (inum % sblock.fs_ipg != 0)
+ errx(EEXIT, "bad inode number %d to setinodebuf", inum);
startinum = 0;
- nextino = 0;
- lastinum = 0;
+ nextino = inum;
+ lastinum = inum;
readcnt = 0;
+ if (inodebuf != NULL)
+ return;
inobufsize = blkroundup(&sblock, INOBUFSIZE);
fullcnt = inobufsize / sizeof(struct dinode);
readpercg = sblock.fs_ipg / fullcnt;
@@ -342,11 +356,8 @@ resetinodebuf()
partialcnt = fullcnt;
partialsize = inobufsize;
}
- if (inodebuf == NULL &&
- (inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
+ if ((inodebuf = (struct dinode *)malloc((unsigned)inobufsize)) == NULL)
errx(EEXIT, "cannot allocate space for inode buffer");
- while (nextino < ROOTINO)
- (void)getnextinode(nextino);
}
void
@@ -380,14 +391,11 @@ cacheino(dp, inumber)
inp = (struct inoinfo *)
malloc(sizeof(*inp) + (blks - 1) * sizeof(ufs_daddr_t));
if (inp == NULL)
- return;
+ errx(EEXIT, "cannot increase directory list");
inpp = &inphead[inumber % numdirs];
inp->i_nexthash = *inpp;
*inpp = inp;
- if (inumber == ROOTINO)
- inp->i_parent = ROOTINO;
- else
- inp->i_parent = (ino_t)0;
+ inp->i_parent = inumber == ROOTINO ? ROOTINO : (ino_t)0;
inp->i_dotdot = (ino_t)0;
inp->i_number = inumber;
inp->i_isize = dp->di_size;
@@ -465,7 +473,7 @@ clri(idesc, type, flag)
n_files--;
(void)ckinode(dp, idesc);
clearinode(dp);
- statemap[idesc->id_number] = USTATE;
+ inoinfo(idesc->id_number)->ino_state = USTATE;
inodirty();
}
}
@@ -476,8 +484,10 @@ findname(idesc)
{
register struct direct *dirp = idesc->id_dirp;
- if (dirp->d_ino != idesc->id_parent)
+ if (dirp->d_ino != idesc->id_parent || idesc->id_entryno < 2) {
+ idesc->id_entryno++;
return (KEEPON);
+ }
memmove(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
return (STOP|FOUND);
}
@@ -498,6 +508,20 @@ findino(idesc)
return (KEEPON);
}
+int
+clearentry(idesc)
+ struct inodesc *idesc;
+{
+ register struct direct *dirp = idesc->id_dirp;
+
+ if (dirp->d_ino != idesc->id_parent || idesc->id_entryno < 2) {
+ idesc->id_entryno++;
+ return (KEEPON);
+ }
+ dirp->d_ino = 0;
+ return (STOP|FOUND|ALTERED);
+}
+
void
pinode(ino)
ino_t ino;
@@ -534,14 +558,14 @@ blkerror(ino, type, blk)
pfatal("%ld %s I=%lu", blk, type, ino);
printf("\n");
- switch (statemap[ino]) {
+ switch (inoinfo(ino)->ino_state) {
case FSTATE:
- statemap[ino] = FCLEAR;
+ inoinfo(ino)->ino_state = FCLEAR;
return;
case DSTATE:
- statemap[ino] = DCLEAR;
+ inoinfo(ino)->ino_state = DCLEAR;
return;
case FCLEAR:
@@ -549,7 +573,7 @@ blkerror(ino, type, blk)
return;
default:
- errx(EEXIT, "BAD STATE %d TO BLKERR", statemap[ino]);
+ errx(EEXIT, "BAD STATE %d TO BLKERR", inoinfo(ino)->ino_state);
/* NOTREACHED */
}
}
@@ -569,10 +593,10 @@ allocino(request, type)
if (request == 0)
request = ROOTINO;
- else if (statemap[request] != USTATE)
+ else if (inoinfo(request)->ino_state != USTATE)
return (0);
for (ino = request; ino < maxino; ino++)
- if (statemap[ino] == USTATE)
+ if (inoinfo(ino)->ino_state == USTATE)
break;
if (ino == maxino)
return (0);
@@ -584,12 +608,12 @@ allocino(request, type)
cgp->cg_cs.cs_nifree--;
switch (type & IFMT) {
case IFDIR:
- statemap[ino] = DSTATE;
+ inoinfo(ino)->ino_state = DSTATE;
cgp->cg_cs.cs_ndir++;
break;
case IFREG:
case IFLNK:
- statemap[ino] = FSTATE;
+ inoinfo(ino)->ino_state = FSTATE;
break;
default:
return (0);
@@ -598,11 +622,11 @@ allocino(request, type)
dp = ginode(ino);
dp->di_db[0] = allocblk((long)1);
if (dp->di_db[0] == 0) {
- statemap[ino] = USTATE;
+ inoinfo(ino)->ino_state = USTATE;
return (0);
}
- dp->di_flags = 0;
dp->di_mode = type;
+ dp->di_flags = 0;
dp->di_atime = time(NULL);
dp->di_mtime = dp->di_ctime = dp->di_atime;
dp->di_size = sblock.fs_fsize;
@@ -610,7 +634,7 @@ allocino(request, type)
n_files++;
inodirty();
if (newinofmt)
- typemap[ino] = IFTODT(type);
+ inoinfo(ino)->ino_type = IFTODT(type);
return (ino);
}
@@ -632,6 +656,6 @@ freeino(ino)
(void)ckinode(dp, &idesc);
clearinode(dp);
inodirty();
- statemap[ino] = USTATE;
+ inoinfo(ino)->ino_state = USTATE;
n_files--;
}