|
|
1.1 root 1: /*
2: * phase 3 of fsck - Check Connectivity
3: */
4:
5: #include "fsck.h"
6:
7: char *lostname = "lost+found";
8:
9: phase3()
10: {
11: ino_t i;
12:
13: if (!qflag)
14: printf("Phase 3 : Check Connectivity\n");
15: for (i=FIRSTIN; i<=ninodes; i++)
16: if ( ((flags(i)&MODEMASK) == IDIR) &&
17: (linkctr(i) == 0) ) {
18: orflags(i, UNREFDIR);
19: markchildren(i);
20: }
21:
22: for (i=FIRSTIN; i<=ninodes; i++)
23: if ( (flags(i)&(UNREFDIR|CHILDDIR)) == UNREFDIR )
24: unrefdir(i);
25: }
26:
27: markchildren(ino)
28: ino_t ino;
29: {
30: struct dinode *dip;
31: struct direct *element;
32: daddr_t addrs[NADDR];
33: ino_t inumber;
34: fsize_t length;
35:
36: if ( badblks(ino) )
37: return;
38: dip = ptrino(ino, databuf);
39: if ( (length=dip->di_size) <= 0 )
40: return;
41: l3tol(addrs, dip->di_addr, NADDR);
42: cdbn = 0;
43: nextblock(addrs);
44: element = (struct direct *) databuf;
45: element += 2; /* skip over . and .. entries */
46: if ( (length-=2*DSIZE) <= 0 )
47: return;
48:
49: while ( length >= DSIZE ) {
50: while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
51: if ( ((inumber=element->d_ino) != 0) &&
52: ((flags(inumber)&MODEMASK)==IDIR) &&
53: (inumber!=ino) )
54: orflags(inumber, CHILDDIR);
55: element++;
56: length -= DSIZE;
57: }
58: nextblock(addrs);
59: element = (struct direct *) databuf;
60: }
61: }
62:
63: char *reconnect = "(Reconnect)";
64:
65: unrefdir(ino)
66: ino_t ino;
67: {
68: printf("Unref Dir\n");
69: if( (pinfo(ino) == 0) || (daction == NO) || (mounted == TRUE) ) {
70: if ( action(reconnect) == FALSE )
71: return;
72: } else
73: printf("%s FORCED\n", reconnect);
74:
75: connect(ino, IDIR);
76: }
77:
78: #define CONNECT 1
79: #define NOCONNECT 0
80:
81: connect(ino, type)
82: ino_t ino;
83: int type;
84: {
85: ino_t lostino;
86: struct dinode *dip;
87: daddr_t addrs[NADDR];
88: fsize_t length;
89: struct direct *element;
90: int chgino = FALSE;
91:
92: if ( ((lostino=lostfound()) == NUL) ||
93: ((flags(lostino)&MODEMASK) != IDIR) ||
94: ( badblks(lostino) ) ) {
95: nolost();
96: if (type==IDIR)
97: traverse(NOCONNECT, ino, lostino);
98: return(FAILURE);
99: }
100:
101: dip = ptrino(lostino, buf2);
102: l3tol(addrs, dip->di_addr, NADDR);
103: length = dip->di_size;
104: cdbn = 0;
105: while ( length>=DSIZE ) {
106: nextblock(addrs);
107: element = (struct direct *) databuf;
108: while ( element<&databuf[BSIZE] ) {
109: length -= DSIZE;
110: if ( element->d_ino == 0 ) {
111: element->d_ino = ino;
112: strncpy(element->d_name, nameit(ino), DIRSIZ);
113: if ( fixblock(addrs) == NUL )
114: fixblkerr();
115: linkincr(ino);
116: numfiles++;
117: if ( length<0 ) {
118: dip->di_size -= length;
119: chgino = TRUE;
120: }
121: if ( (type == IDIR) &&
122: (connected(ino, lostino)==YES) ) {
123: dip->di_nlink++;
124: writeino(lostino, buf2);
125: traverse(CONNECT, ino, lostino);
126: } else if (chgino) {
127: writeino(lostino, buf2);
128: }
129: return(SUCCESS);
130: }
131: element++;
132: }
133: }
134:
135: noroom();
136: if (type == IDIR)
137: traverse(NOCONNECT, ino, lostino);
138: return(FAILURE);
139: }
140:
141: traverse(flag, ino, lostino)
142: int flag;
143: ino_t ino, lostino;
144: {
145: struct direct dirlost, nothing, newtree;
146:
147: dirinit(&dirlost, lostino, lostname);
148: dirinit(¬hing, 0, "??");
149: dirinit(&newtree, ino, nameit(ino));
150: depth = 0;
151: if (flag == CONNECT)
152: path[depth++] = &dirlost;
153: else
154: path[depth++] = ¬hing;
155:
156: path[depth++] = &newtree;
157: checkpath(ino);
158: }
159:
160: dirinit(element, ino, name)
161: struct direct *element;
162: ino_t ino;
163: char *name;
164: {
165: element->d_ino = ino;
166: strncpy(element->d_name, name, DIRSIZ);
167: }
168:
169: connected(ino, lostino)
170: ino_t ino; /* inumber just reconnected */
171: ino_t lostino; /* inumber of lostfound directory */
172: {
173: struct dinode *dip;
174: daddr_t addrs[NADDR];
175: fsize_t length;
176: struct direct *element;
177:
178: if ( badblks(ino) ) {
179: badconnect(ino);
180: return(NO);
181: }
182: dip = ptrino(ino, databuf);
183: l3tol(addrs, dip->di_addr, NADDR);
184: length = dip->di_size;
185: cdbn = 0;
186: while ( length >= DSIZE ) {
187: nextblock(addrs);
188: element = (struct direct *) databuf;
189: while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
190: if ( strcmp(element->d_name, "..") == 0 ) {
191: printf("Dir i-number = %u connected. ", ino);
192: printf("Parent was i-number = %u.\n",
193: element->d_ino);
194: element->d_ino = lostino;
195: if ( fixblock(addrs) == NUL )
196: fixblkerr();
197: return(YES);
198: }
199: length -= DSIZE;
200: element++;
201: }
202: }
203: noparent(ino);
204: return(NO);
205: }
206:
207: badconnect(ino)
208: ino_t ino;
209: {
210: printf("Dir i-number = %u connected. It has bad/dup blocks.\n", ino);
211: }
212:
213: noparent(ino)
214: ino_t ino;
215: {
216: printf("Dir i-number = %u connected. It has no .. entry.\n", ino);
217: }
218:
219: ino_t
220: lostfound()
221: {
222: static daddr_t addrs[NADDR];
223: struct dinode *dip;
224: struct direct *element;
225: fsize_t length;
226:
227: dip = ptrino(ROOTIN, databuf);
228: l3tol(addrs, dip->di_addr, NADDR);
229: length = dip->di_size;
230: cdbn = 0;
231: while ( length>=DSIZE ) {
232: nextblock(addrs);
233: element = (struct direct *) databuf;
234: while ( (element<&databuf[BSIZE]) && (length>=DSIZE) ) {
235: if ( strcmp(element->d_name, lostname) == 0 )
236: return(element->d_ino);
237: length -= DSIZE;
238: element++;
239: }
240: }
241:
242: return(NUL);
243: }
244:
245: nolost()
246: {
247: printf("Sorry. No %s directory.\n", lostname);
248:
249: }
250:
251: noroom()
252: {
253: printf("Sorry. No space in %s directory.\n", lostname);
254: }
255:
256: char namebuf[DIRSIZ];
257:
258: char *
259: nameit(ino)
260: register ino_t ino;
261: {
262: register int i = DIRSIZ-1;
263:
264: namebuf[i] = '\0';
265: while ( (ino != 0) && (i>0) ) {
266: namebuf[--i] = '0' + ino%10;
267: ino = ino/10;
268: }
269: return(&namebuf[i]);
270: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.