summaryrefslogtreecommitdiffstats
path: root/sbin/fsck_ffs/inode.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1998-12-03 02:27:35 +0000
committerjulian <julian@FreeBSD.org>1998-12-03 02:27:35 +0000
commitc1ef9f83c919949e90841ae0990aa9a0273d6490 (patch)
tree766d55719160577172499b05ce54cc96670cf3c4 /sbin/fsck_ffs/inode.c
parent1a5eceeafeb45fc95a5c9fe1830e0d3e349ec69a (diff)
downloadFreeBSD-src-c1ef9f83c919949e90841ae0990aa9a0273d6490.zip
FreeBSD-src-c1ef9f83c919949e90841ae0990aa9a0273d6490.tar.gz
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.
Diffstat (limited to 'sbin/fsck_ffs/inode.c')
-rw-r--r--sbin/fsck_ffs/inode.c92
1 files changed, 58 insertions, 34 deletions
diff --git a/sbin/fsck_ffs/inode.c b/sbin/fsck_ffs/inode.c
index b7e80cd..a54f2ce 100644
--- a/sbin/fsck_ffs/inode.c
+++ b/sbin/fsck_ffs/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--;
}
OpenPOWER on IntegriCloud