salvage the correct part of the directory
[unix-history] / usr / src / sbin / fsck / pass4.c
CommitLineData
76797561 1/*
fe32782c
KM
2 * Copyright (c) 1980, 1986 The Regents of the University of California.
3 * All rights reserved.
4 *
70ab3c27 5 * %sccs.include.redist.c%
76797561
DF
6 */
7
577b7874 8#ifndef lint
b82067db 9static char sccsid[] = "@(#)pass4.c 5.12 (Berkeley) %G%";
fe32782c 10#endif /* not lint */
577b7874
KM
11
12#include <sys/param.h>
b82067db 13#include <sys/time.h>
558b3a30
KB
14#include <ufs/ufs/dinode.h>
15#include <ufs/ffs/fs.h>
d72e970b
KM
16#include <stdlib.h>
17#include <string.h>
577b7874
KM
18#include "fsck.h"
19
20int pass4check();
21
22pass4()
23{
82dc9a9e
KM
24 register ino_t inumber;
25 register struct zlncnt *zlnp;
dbf20d0a 26 struct dinode *dp;
577b7874 27 struct inodesc idesc;
82dc9a9e 28 int n;
577b7874
KM
29
30 bzero((char *)&idesc, sizeof(struct inodesc));
31 idesc.id_type = ADDR;
32 idesc.id_func = pass4check;
33 for (inumber = ROOTINO; inumber <= lastino; inumber++) {
34 idesc.id_number = inumber;
35 switch (statemap[inumber]) {
36
37 case FSTATE:
993a756c 38 case DFOUND:
577b7874
KM
39 n = lncntp[inumber];
40 if (n)
41 adjust(&idesc, (short)n);
42 else {
82dc9a9e
KM
43 for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
44 if (zlnp->zlncnt == inumber) {
1a02fd3a
KM
45 zlnp->zlncnt = zlnhead->zlncnt;
46 zlnp = zlnhead;
47 zlnhead = zlnhead->next;
569ec282 48 free((char *)zlnp);
577b7874
KM
49 clri(&idesc, "UNREF", 1);
50 break;
51 }
52 }
53 break;
54
55 case DSTATE:
56 clri(&idesc, "UNREF", 1);
57 break;
58
993a756c 59 case DCLEAR:
dbf20d0a
KM
60 dp = ginode(inumber);
61 if (dp->di_size == 0) {
62 clri(&idesc, "ZERO LENGTH", 1);
63 break;
64 }
65 /* fall through */
993a756c 66 case FCLEAR:
577b7874
KM
67 clri(&idesc, "BAD/DUP", 1);
68 break;
ea4448dc
KM
69
70 case USTATE:
71 break;
72
73 default:
74 errexit("BAD STATE %d FOR INODE I=%d",
75 statemap[inumber], inumber);
577b7874
KM
76 }
77 }
577b7874
KM
78}
79
80pass4check(idesc)
81 register struct inodesc *idesc;
82{
62e6c152 83 register struct dups *dlp;
577b7874
KM
84 int nfrags, res = KEEPON;
85 daddr_t blkno = idesc->id_blkno;
86
87 for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
569ec282 88 if (chkrange(blkno, 1)) {
577b7874 89 res = SKIP;
569ec282 90 } else if (testbmap(blkno)) {
62e6c152
KM
91 for (dlp = duplist; dlp; dlp = dlp->next) {
92 if (dlp->dup != blkno)
93 continue;
94 dlp->dup = duplist->dup;
95 dlp = duplist;
96 duplist = duplist->next;
569ec282 97 free((char *)dlp);
62e6c152
KM
98 break;
99 }
100 if (dlp == 0) {
101 clrbmap(blkno);
102 n_blks--;
103 }
577b7874
KM
104 }
105 }
106 return (res);
107}