Deleted Added
full compact
pass2.c (8871) pass2.c (23675)
1/*
2 * Copyright (c) 1980, 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 18 unchanged lines hidden (view full) ---

27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
1/*
2 * Copyright (c) 1980, 1986, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 18 unchanged lines hidden (view full) ---

27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static const char sccsid[] = "@(#)pass2.c 8.2 (Berkeley) 2/27/94";
35static const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95";
36#endif /* not lint */
37
38#include <sys/param.h>
39#include <sys/time.h>
36#endif /* not lint */
37
38#include <sys/param.h>
39#include <sys/time.h>
40
40#include <ufs/ufs/dinode.h>
41#include <ufs/ufs/dir.h>
42#include <ufs/ffs/fs.h>
43#include <stdio.h>
44#include <stdlib.h>
41#include <ufs/ufs/dinode.h>
42#include <ufs/ufs/dir.h>
43#include <ufs/ffs/fs.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <err.h>
45#include <string.h>
47#include <string.h>
48
46#include "fsck.h"
47
48#define MINDIRSIZE (sizeof (struct dirtemplate))
49
49#include "fsck.h"
50
51#define MINDIRSIZE (sizeof (struct dirtemplate))
52
50int pass2check(), blksort();
53static int blksort __P((const void *, const void *));
54static int pass2check __P((struct inodesc *));
51
52void
53pass2()
54{
55 register struct dinode *dp;
56 register struct inoinfo **inpp, *inp;
57 struct inoinfo **inpend;
58 struct inodesc curino;
59 struct dinode dino;
60 char pathbuf[MAXPATHLEN + 1];
61
62 switch (statemap[ROOTINO]) {
63
64 case USTATE:
65 pfatal("ROOT INODE UNALLOCATED");
66 if (reply("ALLOCATE") == 0)
55
56void
57pass2()
58{
59 register struct dinode *dp;
60 register struct inoinfo **inpp, *inp;
61 struct inoinfo **inpend;
62 struct inodesc curino;
63 struct dinode dino;
64 char pathbuf[MAXPATHLEN + 1];
65
66 switch (statemap[ROOTINO]) {
67
68 case USTATE:
69 pfatal("ROOT INODE UNALLOCATED");
70 if (reply("ALLOCATE") == 0)
67 errexit("");
71 exit(EEXIT);
68 if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
72 if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
69 errexit("CANNOT ALLOCATE ROOT INODE\n");
73 errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
70 break;
71
72 case DCLEAR:
73 pfatal("DUPS/BAD IN ROOT INODE");
74 if (reply("REALLOCATE")) {
75 freeino(ROOTINO);
76 if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
74 break;
75
76 case DCLEAR:
77 pfatal("DUPS/BAD IN ROOT INODE");
78 if (reply("REALLOCATE")) {
79 freeino(ROOTINO);
80 if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
77 errexit("CANNOT ALLOCATE ROOT INODE\n");
81 errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
78 break;
79 }
80 if (reply("CONTINUE") == 0)
82 break;
83 }
84 if (reply("CONTINUE") == 0)
81 errexit("");
85 exit(EEXIT);
82 break;
83
84 case FSTATE:
85 case FCLEAR:
86 pfatal("ROOT INODE NOT DIRECTORY");
87 if (reply("REALLOCATE")) {
88 freeino(ROOTINO);
89 if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
86 break;
87
88 case FSTATE:
89 case FCLEAR:
90 pfatal("ROOT INODE NOT DIRECTORY");
91 if (reply("REALLOCATE")) {
92 freeino(ROOTINO);
93 if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO)
90 errexit("CANNOT ALLOCATE ROOT INODE\n");
94 errx(EEXIT, "CANNOT ALLOCATE ROOT INODE");
91 break;
92 }
93 if (reply("FIX") == 0)
95 break;
96 }
97 if (reply("FIX") == 0)
94 errexit("");
98 exit(EEXIT);
95 dp = ginode(ROOTINO);
96 dp->di_mode &= ~IFMT;
97 dp->di_mode |= IFDIR;
98 inodirty();
99 break;
100
101 case DSTATE:
102 break;
103
104 default:
99 dp = ginode(ROOTINO);
100 dp->di_mode &= ~IFMT;
101 dp->di_mode |= IFDIR;
102 inodirty();
103 break;
104
105 case DSTATE:
106 break;
107
108 default:
105 errexit("BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
109 errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]);
106 }
107 statemap[ROOTINO] = DFOUND;
110 }
111 statemap[ROOTINO] = DFOUND;
112 if (newinofmt) {
113 statemap[WINO] = FSTATE;
114 typemap[WINO] = DT_WHT;
115 }
108 /*
109 * Sort the directory list into disk block order.
110 */
111 qsort((char *)inpsort, (size_t)inplast, sizeof *inpsort, blksort);
112 /*
113 * Check the integrity of each directory.
114 */
116 /*
117 * Sort the directory list into disk block order.
118 */
119 qsort((char *)inpsort, (size_t)inplast, sizeof *inpsort, blksort);
120 /*
121 * Check the integrity of each directory.
122 */
115 bzero((char *)&curino, sizeof(struct inodesc));
123 memset(&curino, 0, sizeof(struct inodesc));
116 curino.id_type = DATA;
117 curino.id_func = pass2check;
118 dp = &dino;
119 inpend = &inpsort[inplast];
120 for (inpp = inpsort; inpp < inpend; inpp++) {
121 inp = *inpp;
122 if (inp->i_isize == 0)
123 continue;

--- 15 unchanged lines hidden (view full) ---

139 inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ);
140 if (preen || reply("ADJUST") == 1) {
141 dp = ginode(inp->i_number);
142 dp->di_size = roundup(inp->i_isize, DIRBLKSIZ);
143 inodirty();
144 dp = &dino;
145 }
146 }
124 curino.id_type = DATA;
125 curino.id_func = pass2check;
126 dp = &dino;
127 inpend = &inpsort[inplast];
128 for (inpp = inpsort; inpp < inpend; inpp++) {
129 inp = *inpp;
130 if (inp->i_isize == 0)
131 continue;

--- 15 unchanged lines hidden (view full) ---

147 inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ);
148 if (preen || reply("ADJUST") == 1) {
149 dp = ginode(inp->i_number);
150 dp->di_size = roundup(inp->i_isize, DIRBLKSIZ);
151 inodirty();
152 dp = &dino;
153 }
154 }
147 bzero((char *)&dino, sizeof(struct dinode));
155 memset(&dino, 0, sizeof(struct dinode));
148 dino.di_mode = IFDIR;
149 dp->di_size = inp->i_isize;
156 dino.di_mode = IFDIR;
157 dp->di_size = inp->i_isize;
150 bcopy((char *)&inp->i_blks[0], (char *)&dp->di_db[0],
151 (size_t)inp->i_numblks);
158 memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks);
152 curino.id_number = inp->i_number;
153 curino.id_parent = inp->i_parent;
154 (void)ckinode(dp, &curino);
155 }
156 /*
157 * Now that the parents of all directories have been found,
158 * make another pass to verify the value of `..'
159 */

--- 26 unchanged lines hidden (view full) ---

186 (void)changeino(inp->i_number, "..", inp->i_parent);
187 }
188 /*
189 * Mark all the directories that can be found from the root.
190 */
191 propagate();
192}
193
159 curino.id_number = inp->i_number;
160 curino.id_parent = inp->i_parent;
161 (void)ckinode(dp, &curino);
162 }
163 /*
164 * Now that the parents of all directories have been found,
165 * make another pass to verify the value of `..'
166 */

--- 26 unchanged lines hidden (view full) ---

193 (void)changeino(inp->i_number, "..", inp->i_parent);
194 }
195 /*
196 * Mark all the directories that can be found from the root.
197 */
198 propagate();
199}
200
194int
201static int
195pass2check(idesc)
196 struct inodesc *idesc;
197{
198 register struct direct *dirp = idesc->id_dirp;
199 register struct inoinfo *inp;
200 int n, entrysize, ret = 0;
201 struct dinode *dp;
202 char *errmsg;

--- 31 unchanged lines hidden (view full) ---

234 direrror(idesc->id_number, "MISSING '.'");
235 proto.d_ino = idesc->id_number;
236 if (newinofmt)
237 proto.d_type = DT_DIR;
238 else
239 proto.d_type = 0;
240 proto.d_namlen = 1;
241 (void)strcpy(proto.d_name, ".");
202pass2check(idesc)
203 struct inodesc *idesc;
204{
205 register struct direct *dirp = idesc->id_dirp;
206 register struct inoinfo *inp;
207 int n, entrysize, ret = 0;
208 struct dinode *dp;
209 char *errmsg;

--- 31 unchanged lines hidden (view full) ---

241 direrror(idesc->id_number, "MISSING '.'");
242 proto.d_ino = idesc->id_number;
243 if (newinofmt)
244 proto.d_type = DT_DIR;
245 else
246 proto.d_type = 0;
247 proto.d_namlen = 1;
248 (void)strcpy(proto.d_name, ".");
249# if BYTE_ORDER == LITTLE_ENDIAN
250 if (!newinofmt) {
251 u_char tmp;
252
253 tmp = proto.d_type;
254 proto.d_type = proto.d_namlen;
255 proto.d_namlen = tmp;
256 }
257# endif
242 entrysize = DIRSIZ(0, &proto);
243 if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
244 pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
245 dirp->d_name);
246 } else if (dirp->d_reclen < entrysize) {
247 pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
248 } else if (dirp->d_reclen < 2 * entrysize) {
249 proto.d_reclen = dirp->d_reclen;
258 entrysize = DIRSIZ(0, &proto);
259 if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
260 pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
261 dirp->d_name);
262 } else if (dirp->d_reclen < entrysize) {
263 pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
264 } else if (dirp->d_reclen < 2 * entrysize) {
265 proto.d_reclen = dirp->d_reclen;
250 bcopy((char *)&proto, (char *)dirp, (size_t)entrysize);
266 memmove(dirp, &proto, (size_t)entrysize);
251 if (reply("FIX") == 1)
252 ret |= ALTERED;
253 } else {
254 n = dirp->d_reclen - entrysize;
255 proto.d_reclen = entrysize;
267 if (reply("FIX") == 1)
268 ret |= ALTERED;
269 } else {
270 n = dirp->d_reclen - entrysize;
271 proto.d_reclen = entrysize;
256 bcopy((char *)&proto, (char *)dirp, (size_t)entrysize);
272 memmove(dirp, &proto, (size_t)entrysize);
257 idesc->id_entryno++;
258 lncntp[dirp->d_ino]--;
259 dirp = (struct direct *)((char *)(dirp) + entrysize);
273 idesc->id_entryno++;
274 lncntp[dirp->d_ino]--;
275 dirp = (struct direct *)((char *)(dirp) + entrysize);
260 bzero((char *)dirp, (size_t)n);
276 memset(dirp, 0, (size_t)n);
261 dirp->d_reclen = n;
262 if (reply("FIX") == 1)
263 ret |= ALTERED;
264 }
265chk1:
266 if (idesc->id_entryno > 1)
267 goto chk2;
268 inp = getinoinfo(idesc->id_number);
269 proto.d_ino = inp->i_parent;
270 if (newinofmt)
271 proto.d_type = DT_DIR;
272 else
273 proto.d_type = 0;
274 proto.d_namlen = 2;
275 (void)strcpy(proto.d_name, "..");
277 dirp->d_reclen = n;
278 if (reply("FIX") == 1)
279 ret |= ALTERED;
280 }
281chk1:
282 if (idesc->id_entryno > 1)
283 goto chk2;
284 inp = getinoinfo(idesc->id_number);
285 proto.d_ino = inp->i_parent;
286 if (newinofmt)
287 proto.d_type = DT_DIR;
288 else
289 proto.d_type = 0;
290 proto.d_namlen = 2;
291 (void)strcpy(proto.d_name, "..");
292# if BYTE_ORDER == LITTLE_ENDIAN
293 if (!newinofmt) {
294 u_char tmp;
295
296 tmp = proto.d_type;
297 proto.d_type = proto.d_namlen;
298 proto.d_namlen = tmp;
299 }
300# endif
276 entrysize = DIRSIZ(0, &proto);
277 if (idesc->id_entryno == 0) {
278 n = DIRSIZ(0, dirp);
279 if (dirp->d_reclen < n + entrysize)
280 goto chk2;
281 proto.d_reclen = dirp->d_reclen - n;
282 dirp->d_reclen = n;
283 idesc->id_entryno++;
284 lncntp[dirp->d_ino]--;
285 dirp = (struct direct *)((char *)(dirp) + n);
301 entrysize = DIRSIZ(0, &proto);
302 if (idesc->id_entryno == 0) {
303 n = DIRSIZ(0, dirp);
304 if (dirp->d_reclen < n + entrysize)
305 goto chk2;
306 proto.d_reclen = dirp->d_reclen - n;
307 dirp->d_reclen = n;
308 idesc->id_entryno++;
309 lncntp[dirp->d_ino]--;
310 dirp = (struct direct *)((char *)(dirp) + n);
286 bzero((char *)dirp, (size_t)proto.d_reclen);
311 memset(dirp, 0, (size_t)proto.d_reclen);
287 dirp->d_reclen = proto.d_reclen;
288 }
289 if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
290 inp->i_dotdot = dirp->d_ino;
291 if (newinofmt && dirp->d_type != DT_DIR) {
292 direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'");
293 dirp->d_type = DT_DIR;
294 if (reply("FIX") == 1)

--- 12 unchanged lines hidden (view full) ---

307 inp->i_dotdot = (ino_t)-1;
308 } else if (inp->i_parent != 0) {
309 /*
310 * We know the parent, so fix now.
311 */
312 inp->i_dotdot = inp->i_parent;
313 fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
314 proto.d_reclen = dirp->d_reclen;
312 dirp->d_reclen = proto.d_reclen;
313 }
314 if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
315 inp->i_dotdot = dirp->d_ino;
316 if (newinofmt && dirp->d_type != DT_DIR) {
317 direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'");
318 dirp->d_type = DT_DIR;
319 if (reply("FIX") == 1)

--- 12 unchanged lines hidden (view full) ---

332 inp->i_dotdot = (ino_t)-1;
333 } else if (inp->i_parent != 0) {
334 /*
335 * We know the parent, so fix now.
336 */
337 inp->i_dotdot = inp->i_parent;
338 fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
339 proto.d_reclen = dirp->d_reclen;
315 bcopy((char *)&proto, (char *)dirp, (size_t)entrysize);
340 memmove(dirp, &proto, (size_t)entrysize);
316 if (reply("FIX") == 1)
317 ret |= ALTERED;
318 }
319 idesc->id_entryno++;
320 if (dirp->d_ino != 0)
321 lncntp[dirp->d_ino]--;
322 return (ret|KEEPON);
323chk2:

--- 17 unchanged lines hidden (view full) ---

341 return (KEEPON | ret);
342 }
343 }
344 idesc->id_entryno++;
345 n = 0;
346 if (dirp->d_ino > maxino) {
347 fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE");
348 n = reply("REMOVE");
341 if (reply("FIX") == 1)
342 ret |= ALTERED;
343 }
344 idesc->id_entryno++;
345 if (dirp->d_ino != 0)
346 lncntp[dirp->d_ino]--;
347 return (ret|KEEPON);
348chk2:

--- 17 unchanged lines hidden (view full) ---

366 return (KEEPON | ret);
367 }
368 }
369 idesc->id_entryno++;
370 n = 0;
371 if (dirp->d_ino > maxino) {
372 fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE");
373 n = reply("REMOVE");
374 } else if (newinofmt &&
375 ((dirp->d_ino == WINO && dirp->d_type != DT_WHT) ||
376 (dirp->d_ino != WINO && dirp->d_type == DT_WHT))) {
377 fileerror(idesc->id_number, dirp->d_ino, "BAD WHITEOUT ENTRY");
378 dirp->d_ino = WINO;
379 dirp->d_type = DT_WHT;
380 if (reply("FIX") == 1)
381 ret |= ALTERED;
349 } else {
350again:
351 switch (statemap[dirp->d_ino]) {
352 case USTATE:
353 if (idesc->id_entryno <= 2)
354 break;
355 fileerror(idesc->id_number, dirp->d_ino, "UNALLOCATED");
356 n = reply("REMOVE");

--- 50 unchanged lines hidden (view full) ---

407 dirp->d_type = typemap[dirp->d_ino];
408 if (reply("FIX") == 1)
409 ret |= ALTERED;
410 }
411 lncntp[dirp->d_ino]--;
412 break;
413
414 default:
382 } else {
383again:
384 switch (statemap[dirp->d_ino]) {
385 case USTATE:
386 if (idesc->id_entryno <= 2)
387 break;
388 fileerror(idesc->id_number, dirp->d_ino, "UNALLOCATED");
389 n = reply("REMOVE");

--- 50 unchanged lines hidden (view full) ---

440 dirp->d_type = typemap[dirp->d_ino];
441 if (reply("FIX") == 1)
442 ret |= ALTERED;
443 }
444 lncntp[dirp->d_ino]--;
445 break;
446
447 default:
415 errexit("BAD STATE %d FOR INODE I=%d",
448 errx(EEXIT, "BAD STATE %d FOR INODE I=%d",
416 statemap[dirp->d_ino], dirp->d_ino);
417 }
418 }
419 if (n == 0)
420 return (ret|KEEPON);
421 dirp->d_ino = 0;
422 return (ret|KEEPON|ALTERED);
423}
424
425/*
426 * Routine to sort disk blocks.
427 */
449 statemap[dirp->d_ino], dirp->d_ino);
450 }
451 }
452 if (n == 0)
453 return (ret|KEEPON);
454 dirp->d_ino = 0;
455 return (ret|KEEPON|ALTERED);
456}
457
458/*
459 * Routine to sort disk blocks.
460 */
428int
429blksort(inpp1, inpp2)
430 struct inoinfo **inpp1, **inpp2;
461static int
462blksort(arg1, arg2)
463 const void *arg1, *arg2;
431{
432
464{
465
433 return ((*inpp1)->i_blks[0] - (*inpp2)->i_blks[0]);
466 return ((*(struct inoinfo **)arg1)->i_blks[0] -
467 (*(struct inoinfo **)arg2)->i_blks[0]);
434}
468}