summaryrefslogtreecommitdiff
path: root/ufs-fsck
diff options
context:
space:
mode:
Diffstat (limited to 'ufs-fsck')
-rw-r--r--ufs-fsck/inode.c55
1 files changed, 49 insertions, 6 deletions
diff --git a/ufs-fsck/inode.c b/ufs-fsck/inode.c
index 44b79de3..e8924e1a 100644
--- a/ufs-fsck/inode.c
+++ b/ufs-fsck/inode.c
@@ -20,12 +20,43 @@
static void
inode_iterate (struct dinode *dp,
- int (*fn (daddr_t, int)),
+ int (*fn) (daddr_t, int),
int doaddrblocks)
{
mode_t mode = dp->di_model & IFMT;
int nb, maxb;
+ /* Call FN for iblock IBLOCK of level LEVEL and recurse down
+ the indirect block pointers. */
+ int
+ scaniblock (daddr_t iblock, int level)
+ {
+ int cont;
+ daddr_t ptrs[NIADDR(sblock)];
+ int i;
+
+ if (doaddrblocks)
+ {
+ cont = (*fn)(iblock, sblock->fs_frag);
+ if (cont == RET_STOP)
+ return RET_STOP;
+ else if (cont == RET_BAD)
+ return RET_GOOD;
+ }
+
+ readblock (fsbtodb (iblock), buf, sblock->fs_bsize);
+ for (i = 0; i < NIADDR (sblock); i++)
+ {
+ if (level == 0)
+ cont = (*fn)(ptrs[i], sblock->fs_frag);
+ else
+ cont = scaniblock (ptrs[i], level - 1);
+ if (cont == RET_STOP)
+ return RET_STOP;
+ }
+ return RET_GOOD;
+ }
+
if (mode == IFBLK || mode == IFCHR
|| (mode == IFLNK && sblock->fs_maxsymlinklen != -1
&& (dp->di_size < sblock->fs_maxsymlinklen
@@ -44,17 +75,29 @@ inode_iterate (struct dinode *dp,
else
nfrags = sblock->fs_frag;
- if (dp->di_db[nb] != 0)
- if ((*fn)(dp->di_db[nb], nfrags) != RET_GOOD)
- return;
+ if (dp->di_db[nb] && (*fn)(dp->di_db[nb], nfrags) != RET_GOOD)
+ return;
}
for (nb = 0; nb < NIADDR; nb++)
- if (scaniblock (dp->di_db[nb], nb) != RET_GOOD)
+ if (dp->di_ib[nb] && scaniblock (dp->di_ib[nb], nb) != RET_GOOD)
return;
if (doaddrblocks && dp->di_trans)
(*fn)(dp->di_trans, sblock->fs_frag);
}
-
+void
+datablocks_iterate (struct dinode *dp,
+ int (*fn) (daddr_t, int))
+{
+ inode_iterate (dp, fn, 0);
+}
+
+void
+allblock_iterate (struct dinode *dp,
+ int (*fn) (daddr_t, int))
+{
+ inode_iterate (dp, fn, 1);
+}
+