X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/75c260400bc8f350c60574eb92836e0e49e0eae6..05cd4ae7f2de5ffa37cbcf90b515126852adce0e:/usr/src/sbin/dump/traverse.c
diff --git a/usr/src/sbin/dump/traverse.c b/usr/src/sbin/dump/traverse.c
index fb89bc3a27..8decd11a54 100644
--- a/usr/src/sbin/dump/traverse.c
+++ b/usr/src/sbin/dump/traverse.c
@@ -1,28 +1,32 @@
-static char *sccsid = "@(#)traverse.c 1.9 (Berkeley) %G%";
+/*
+ * Copyright (c) 1980, 1988 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)traverse.c 5.5 (Berkeley) %G%";
+#endif not lint
#include "dump.h"
-#include
pass(fn, map)
- int (*fn)();
- char *map;
+ register int (*fn)();
+ register char *map;
{
- struct dinode *dp;
- int bits;
+ register int bits;
ino_t maxino;
maxino = sblock->fs_ipg * sblock->fs_ncg - 1;
for (ino = 0; ino < maxino; ) {
- if((ino % NBBY) == 0) {
+ if ((ino % NBBY) == 0) {
bits = ~0;
- if(map != NULL)
+ if (map != NULL)
bits = *map++;
}
ino++;
- if(bits & 1) {
- dp = getino(ino);
- (*fn)(dp);
- }
+ if (bits & 1)
+ (*fn)(getino(ino));
bits >>= 1;
}
}
@@ -30,13 +34,14 @@ pass(fn, map)
mark(ip)
struct dinode *ip;
{
- register f;
+ register int f;
+ extern int anydskipped;
f = ip->di_mode & IFMT;
- if(f == 0)
+ if (f == 0)
return;
BIS(ino, clrmap);
- if(f == IFDIR)
+ if (f == IFDIR)
BIS(ino, dirmap);
if ((ip->di_mtime >= spcl.c_ddate || ip->di_ctime >= spcl.c_ddate) &&
!BIT(ino, nodmap)) {
@@ -46,25 +51,29 @@ mark(ip)
return;
}
est(ip);
- }
+ } else if (f == IFDIR)
+ anydskipped = 1;
}
add(ip)
register struct dinode *ip;
{
register int i;
+ long filesize;
if(BIT(ino, nodmap))
return;
nsubdir = 0;
dadded = 0;
+ filesize = ip->di_size;
for (i = 0; i < NDADDR; i++) {
if (ip->di_db[i] != 0)
- dsrch(ip->di_db[i], dblksize(sblock, ip, i));
+ dsrch(ip->di_db[i], dblksize(sblock, ip, i), filesize);
+ filesize -= sblock->fs_bsize;
}
for (i = 0; i < NIADDR; i++) {
if (ip->di_ib[i] != 0)
- indir(ip->di_ib[i], i);
+ indir(ip->di_ib[i], i, &filesize);
}
if(dadded) {
nadded++;
@@ -78,9 +87,9 @@ add(ip)
BIC(ino, dirmap);
}
-indir(d, n)
+indir(d, n, filesize)
daddr_t d;
- int n;
+ int n, *filesize;
{
register i;
daddr_t idblk[MAXNINDIR];
@@ -90,18 +99,28 @@ indir(d, n)
for(i=0; i < NINDIR(sblock); i++) {
d = idblk[i];
if(d != 0)
- dsrch(d, sblock->fs_bsize);
+ dsrch(d, sblock->fs_bsize, *filesize);
+ *filesize -= sblock->fs_bsize;
}
} else {
n--;
for(i=0; i < NINDIR(sblock); i++) {
d = idblk[i];
if(d != 0)
- indir(d, n);
+ indir(d, n, filesize);
}
}
}
+dirdump(ip)
+ struct dinode *ip;
+{
+ /* watchout for dir inodes deleted and maybe reallocated */
+ if ((ip->di_mode & IFMT) != IFDIR)
+ return;
+ dump(ip);
+}
+
dump(ip)
struct dinode *ip;
{
@@ -117,6 +136,8 @@ dump(ip)
spcl.c_type = TS_INODE;
spcl.c_count = 0;
i = ip->di_mode & IFMT;
+ if (i == 0) /* free inode */
+ return;
if ((i != IFDIR && i != IFREG && i != IFLNK) || ip->di_size == 0) {
spclrec();
return;
@@ -147,7 +168,7 @@ dmpindir(blk, lvl, size)
if (blk != 0)
bread(fsbtodb(sblock, blk), (char *)idblk, sblock->fs_bsize);
else
- blkclr(idblk, sblock->fs_bsize);
+ bzero(idblk, sblock->fs_bsize);
if (lvl <= 0) {
if (*size < NINDIR(sblock) * sblock->fs_bsize)
cnt = howmany(*size, sblock->fs_fsize);
@@ -171,8 +192,8 @@ blksout(blkp, frags)
{
int i, j, count, blks, tbperdb;
- blks = frags * BLKING(sblock);
- tbperdb = BLKING(sblock) * sblock->fs_frag;
+ blks = howmany(frags * sblock->fs_fsize, TP_BSIZE);
+ tbperdb = sblock->fs_bsize / TP_BSIZE;
for (i = 0; i < blks; i += TP_NINDIR) {
if (i + TP_NINDIR > blks)
count = blks;
@@ -200,18 +221,11 @@ blksout(blkp, frags)
bitmap(map, typ)
char *map;
{
- register i, n;
+ register i;
char *cp;
- n = -1;
- for (i = 0; i < msiz; i++)
- if(map[i])
- n = i;
- if (n < 0)
- return;
- n++;
spcl.c_type = typ;
- spcl.c_count = howmany(n * sizeof(map[0]), TP_BSIZE);
+ spcl.c_count = howmany(msiz * sizeof(map[0]), TP_BSIZE);
spclrec();
for (i = 0, cp = map; i < spcl.c_count; i++, cp += TP_BSIZE)
taprec(cp);
@@ -226,15 +240,18 @@ spclrec()
spcl.c_checksum = 0;
ip = (int *)&spcl;
s = 0;
- for(i = 0; i < sizeof(union u_spcl)/sizeof(int); i++)
- s += *ip++;
+ i = sizeof(union u_spcl) / (4*sizeof(int));
+ while (--i >= 0) {
+ s += *ip++; s += *ip++;
+ s += *ip++; s += *ip++;
+ }
spcl.c_checksum = CHECKSUM - s;
taprec((char *)&spcl);
}
-dsrch(d, size)
+dsrch(d, size, filesize)
daddr_t d;
- int size;
+ int size, filesize;
{
register struct direct *dp;
long loc;
@@ -242,11 +259,15 @@ dsrch(d, size)
if(dadded)
return;
- bread(fsbtodb(sblock, d), dblk, size);
- for (loc = 0; loc < size; ) {
+ if (filesize > size)
+ filesize = size;
+ bread(fsbtodb(sblock, d), dblk, filesize);
+ for (loc = 0; loc < filesize; ) {
dp = (struct direct *)(dblk + loc);
- if (dp->d_reclen == 0)
+ if (dp->d_reclen == 0) {
+ msg("corrupted directory, inumber %d\n", ino);
break;
+ }
loc += dp->d_reclen;
if(dp->d_ino == 0)
continue;
@@ -284,42 +305,58 @@ getino(ino)
int breaderrors = 0;
#define BREADEMAX 32
-bread(da, ba, c)
+bread(da, ba, cnt)
daddr_t da;
char *ba;
- int c;
+ int cnt;
{
- register n;
- register regc;
+ int n, i;
+ extern int errno;
- if (lseek(fi, (long)(da * DEV_BSIZE), 0) < 0){
+loop:
+ if (lseek(fi, (long)(da * dev_bsize), 0) < 0){
msg("bread: lseek fails\n");
}
- regc = c; /* put c someplace safe; it gets clobbered */
- n = read(fi, ba, c);
- if (n != c || regc != c) {
- msg("(This should not happen)bread from %s [block %d]: c=0x%x, regc=0x%x, &c=0x%x, n=0x%x\n",
- disk, da, c, regc, &c, n);
-#ifdef ERNIE
- msg("Notify Robert Henry of this error.\n");
-#endif
- if (++breaderrors > BREADEMAX){
- msg("More than %d block read errors from %d\n",
- BREADEMAX, disk);
- broadcast("DUMP IS AILING!\n");
- msg("This is an unrecoverable error.\n");
- if (!query("Do you want to attempt to continue?")){
- dumpabort();
- /*NOTREACHED*/
- } else
- breaderrors = 0;
- }
+ n = read(fi, ba, cnt);
+ if (n == cnt)
+ return;
+ if (da + (cnt / dev_bsize) > fsbtodb(sblock, sblock->fs_size)) {
+ /*
+ * Trying to read the final fragment.
+ *
+ * NB - dump only works in TP_BSIZE blocks, hence
+ * rounds `dev_bsize' fragments up to TP_BSIZE pieces.
+ * It should be smarter about not actually trying to
+ * read more than it can get, but for the time being
+ * we punt and scale back the read only when it gets
+ * us into trouble. (mkm 9/25/83)
+ */
+ cnt -= dev_bsize;
+ goto loop;
+ }
+ msg("read error from %s [block %d]: count=%d, got=%d, errno=%d\n",
+ disk, da, cnt, n, errno);
+ if (++breaderrors > BREADEMAX){
+ msg("More than %d block read errors from %d\n",
+ BREADEMAX, disk);
+ broadcast("DUMP IS AILING!\n");
+ msg("This is an unrecoverable error.\n");
+ if (!query("Do you want to attempt to continue?")){
+ dumpabort();
+ /*NOTREACHED*/
+ } else
+ breaderrors = 0;
+ }
+ /*
+ * Zero buffer, then try to read each sector of buffer separately.
+ */
+ bzero(ba, cnt);
+ for (i = 0; i < cnt; i += dev_bsize, ba += dev_bsize, da++) {
+ if (lseek(fi, (long)(da * dev_bsize), 0) < 0)
+ msg("bread: lseek2 fails!\n");
+ n = read(fi, ba, dev_bsize);
+ if (n != dev_bsize)
+ msg(" read error from %s [sector %d, errno %d]\n",
+ disk, da, errno);
}
-}
-
-blkclr(cp, size)
- char *cp;
- long size;
-{
- asm("movc5 $0,(r0),$0,8(ap),*4(ap)");
}