Annotation of src/sbin/fsck_lfs/pass2.c, Revision 1.33
1.33 ! dholland 1: /* $NetBSD: pass2.c,v 1.32 2015/09/15 15:02:25 dholland Exp $ */
1.1 perseant 2:
3: /*
4: * Copyright (c) 1980, 1986, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
1.10 agc 15: * 3. Neither the name of the University nor the names of its contributors
1.1 perseant 16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
31:
1.7 perseant 32: #include <sys/types.h>
1.1 perseant 33: #include <sys/param.h>
34: #include <sys/time.h>
1.7 perseant 35: #include <sys/mount.h>
36: #include <sys/buf.h>
37:
1.1 perseant 38: #include <ufs/lfs/lfs.h>
1.26 dholland 39: #include <ufs/lfs/lfs_accessors.h>
1.23 dholland 40: #include <ufs/lfs/lfs_inode.h>
1.1 perseant 41:
1.7 perseant 42: #include <err.h>
1.1 perseant 43: #include <stdio.h>
44: #include <stdlib.h>
45: #include <string.h>
46:
1.7 perseant 47: #include "bufcache.h"
48: #include "vnode.h"
1.15 christos 49: #include "lfs_user.h"
1.7 perseant 50:
1.1 perseant 51: #include "fsck.h"
52: #include "fsutil.h"
53: #include "extern.h"
54:
1.21 dholland 55: #define MINDIRSIZE (sizeof (struct lfs_dirtemplate))
1.1 perseant 56:
1.7 perseant 57: static int pass2check(struct inodesc *);
58: static int blksort(const void *, const void *);
1.1 perseant 59:
60: void
1.11 xtraeme 61: pass2(void)
1.1 perseant 62: {
1.26 dholland 63: union lfs_dinode *dp;
1.7 perseant 64: struct uvnode *vp;
65: struct inoinfo **inpp, *inp;
1.1 perseant 66: struct inoinfo **inpend;
1.7 perseant 67: struct inodesc curino;
1.26 dholland 68: union lfs_dinode dino;
1.7 perseant 69: char pathbuf[MAXPATHLEN + 1];
1.26 dholland 70: uint16_t mode;
71: unsigned ii;
1.1 perseant 72:
1.19 dholland 73: switch (statemap[ULFS_ROOTINO]) {
1.1 perseant 74:
75: case USTATE:
76: pfatal("ROOT INODE UNALLOCATED");
77: if (reply("ALLOCATE") == 0)
1.17 christos 78: err(EEXIT, "%s", "");
1.19 dholland 79: if (allocdir(ULFS_ROOTINO, ULFS_ROOTINO, 0755) != ULFS_ROOTINO)
1.25 christos 80: err(EEXIT, "CANNOT ALLOCATE ROOT INODE");
1.1 perseant 81: break;
82:
83: case DCLEAR:
84: pfatal("DUPS/BAD IN ROOT INODE");
85: if (reply("REALLOCATE")) {
1.19 dholland 86: freeino(ULFS_ROOTINO);
87: if (allocdir(ULFS_ROOTINO, ULFS_ROOTINO, 0755) != ULFS_ROOTINO)
1.24 christos 88: err(EEXIT, "CANNOT ALLOCATE ROOT INODE");
1.1 perseant 89: break;
90: }
91: if (reply("CONTINUE") == 0)
1.17 christos 92: err(EEXIT, "%s", "");
1.1 perseant 93: break;
94:
95: case FSTATE:
96: case FCLEAR:
97: pfatal("ROOT INODE NOT DIRECTORY");
98: if (reply("REALLOCATE")) {
1.19 dholland 99: freeino(ULFS_ROOTINO);
100: if (allocdir(ULFS_ROOTINO, ULFS_ROOTINO, 0755) != ULFS_ROOTINO)
1.24 christos 101: err(EEXIT, "CANNOT ALLOCATE ROOT INODE");
1.1 perseant 102: break;
103: }
104: if (reply("FIX") == 0)
1.17 christos 105: errx(EEXIT, "%s", "");
1.19 dholland 106: vp = vget(fs, ULFS_ROOTINO);
1.7 perseant 107: dp = VTOD(vp);
1.26 dholland 108: mode = lfs_dino_getmode(fs, dp);
109: mode &= ~LFS_IFMT;
110: mode |= LFS_IFDIR;
111: lfs_dino_setmode(fs, dp, mode);
1.7 perseant 112: inodirty(VTOI(vp));
1.1 perseant 113: break;
114:
115: case DSTATE:
116: break;
117:
118: default:
1.24 christos 119: errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ULFS_ROOTINO]);
1.1 perseant 120: }
1.19 dholland 121: statemap[ULFS_WINO] = FSTATE;
1.21 dholland 122: typemap[ULFS_WINO] = LFS_DT_WHT;
1.1 perseant 123: /*
124: * Sort the directory list into disk block order.
125: */
1.7 perseant 126: qsort((char *) inpsort, (size_t) inplast, sizeof *inpsort, blksort);
1.1 perseant 127: /*
128: * Check the integrity of each directory.
129: */
130: memset(&curino, 0, sizeof(struct inodesc));
131: curino.id_type = DATA;
132: curino.id_func = pass2check;
133: inpend = &inpsort[inplast];
134: for (inpp = inpsort; inpp < inpend; inpp++) {
135: inp = *inpp;
136: if (inp->i_isize == 0)
137: continue;
138: if (inp->i_isize < MINDIRSIZE) {
139: direrror(inp->i_number, "DIRECTORY TOO SHORT");
1.22 dholland 140: inp->i_isize = roundup(MINDIRSIZE, LFS_DIRBLKSIZ);
1.1 perseant 141: if (reply("FIX") == 1) {
1.7 perseant 142: vp = vget(fs, inp->i_number);
143: dp = VTOD(vp);
1.26 dholland 144: lfs_dino_setsize(fs, dp, inp->i_isize);
1.7 perseant 145: inodirty(VTOI(vp));
1.1 perseant 146: }
1.22 dholland 147: } else if ((inp->i_isize & (LFS_DIRBLKSIZ - 1)) != 0) {
1.9 itojun 148: getpathname(pathbuf, sizeof(pathbuf), inp->i_number,
149: inp->i_number);
1.2 nathanw 150: pwarn("DIRECTORY %s: LENGTH %lu NOT MULTIPLE OF %d",
1.22 dholland 151: pathbuf, (unsigned long) inp->i_isize, LFS_DIRBLKSIZ);
1.1 perseant 152: if (preen)
153: printf(" (ADJUSTED)\n");
1.22 dholland 154: inp->i_isize = roundup(inp->i_isize, LFS_DIRBLKSIZ);
1.1 perseant 155: if (preen || reply("ADJUST") == 1) {
1.7 perseant 156: vp = vget(fs, inp->i_number);
157: dp = VTOD(vp);
1.26 dholland 158: lfs_dino_setsize(fs, dp, inp->i_isize);
1.7 perseant 159: inodirty(VTOI(vp));
1.1 perseant 160: }
161: }
1.26 dholland 162: memset(&dino, 0, sizeof(dino));
163: lfs_dino_setmode(fs, &dino, LFS_IFDIR);
164: lfs_dino_setsize(fs, &dino, inp->i_isize);
165: for (ii = 0; ii < inp->i_numblks / sizeof(inp->i_blks[0]) &&
166: ii < ULFS_NDADDR; ii++) {
167: lfs_dino_setdb(fs, &dino, ii, inp->i_blks[ii]);
168: }
169: for (; ii < inp->i_numblks / sizeof(inp->i_blks[0]); ii++) {
170: lfs_dino_setib(fs, &dino, ii - ULFS_NDADDR,
171: inp->i_blks[ii]);
172: }
1.1 perseant 173: curino.id_number = inp->i_number;
174: curino.id_parent = inp->i_parent;
1.7 perseant 175: (void) ckinode(&dino, &curino);
1.1 perseant 176: }
177: /*
178: * Now that the parents of all directories have been found,
179: * make another pass to verify the value of `..'
180: */
181: for (inpp = inpsort; inpp < inpend; inpp++) {
182: inp = *inpp;
183: if (inp->i_parent == 0 || inp->i_isize == 0)
184: continue;
185: if (inp->i_dotdot == inp->i_parent ||
1.7 perseant 186: inp->i_dotdot == (ino_t) - 1)
1.1 perseant 187: continue;
188: if (inp->i_dotdot == 0) {
189: inp->i_dotdot = inp->i_parent;
190: fileerror(inp->i_parent, inp->i_number, "MISSING '..'");
191: if (reply("FIX") == 0)
192: continue;
1.7 perseant 193: (void) makeentry(inp->i_number, inp->i_parent, "..");
1.1 perseant 194: lncntp[inp->i_parent]--;
195: continue;
196: }
197: fileerror(inp->i_parent, inp->i_number,
1.7 perseant 198: "BAD INODE NUMBER FOR '..'");
1.1 perseant 199: if (reply("FIX") == 0)
200: continue;
201: lncntp[inp->i_dotdot]++;
202: lncntp[inp->i_parent]--;
203: inp->i_dotdot = inp->i_parent;
1.7 perseant 204: (void) changeino(inp->i_number, "..", inp->i_parent);
1.1 perseant 205: }
206: /*
207: * Mark all the directories that can be found from the root.
208: */
209: propagate();
210: }
211:
212: static int
1.4 perseant 213: pass2check(struct inodesc * idesc)
1.1 perseant 214: {
1.32 dholland 215: struct lfs_dirheader *dirp = idesc->id_dirp;
1.12 perry 216: struct inoinfo *inp;
1.7 perseant 217: int n, entrysize, ret = 0;
1.26 dholland 218: union lfs_dinode *dp;
1.14 christos 219: const char *errmsg;
1.32 dholland 220: struct lfs_dirheader proto;
1.7 perseant 221: char namebuf[MAXPATHLEN + 1];
222: char pathbuf[MAXPATHLEN + 1];
1.1 perseant 223:
224: /*
225: * check for "."
226: */
227: if (idesc->id_entryno != 0)
228: goto chk1;
1.31 dholland 229: if (lfs_dir_getino(fs, dirp) != 0 && strcmp(lfs_dir_nameptr(fs, dirp), ".") == 0) {
1.28 dholland 230: if (lfs_dir_getino(fs, dirp) != idesc->id_number) {
1.1 perseant 231: direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'");
1.27 dholland 232: if (reply("FIX") == 1) {
1.28 dholland 233: lfs_dir_setino(fs, dirp, idesc->id_number);
1.1 perseant 234: ret |= ALTERED;
1.27 dholland 235: }
1.1 perseant 236: }
1.27 dholland 237: if (lfs_dir_gettype(fs, dirp) != LFS_DT_DIR) {
1.1 perseant 238: direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'");
1.27 dholland 239: if (reply("FIX") == 1) {
240: lfs_dir_settype(fs, dirp, LFS_DT_DIR);
1.1 perseant 241: ret |= ALTERED;
1.27 dholland 242: }
1.1 perseant 243: }
244: goto chk1;
245: }
246: direrror(idesc->id_number, "MISSING '.'");
1.28 dholland 247: lfs_dir_setino(fs, &proto, idesc->id_number);
1.27 dholland 248: lfs_dir_settype(fs, &proto, LFS_DT_DIR);
249: lfs_dir_setnamlen(fs, &proto, 1);
1.33 ! dholland 250: entrysize = LFS_DIRECTSIZ(fs, 1);
1.29 dholland 251: lfs_dir_setreclen(fs, &proto, entrysize);
1.31 dholland 252: if (lfs_dir_getino(fs, dirp) != 0 && strcmp(lfs_dir_nameptr(fs, dirp), "..") != 0) {
1.1 perseant 253: pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
1.31 dholland 254: lfs_dir_nameptr(fs, dirp));
1.28 dholland 255: } else if (lfs_dir_getreclen(fs, dirp) < entrysize) {
1.1 perseant 256: pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
1.28 dholland 257: } else if (lfs_dir_getreclen(fs, dirp) < 2 * entrysize) {
1.29 dholland 258: /* convert this entry to a . entry */
1.28 dholland 259: lfs_dir_setreclen(fs, &proto, lfs_dir_getreclen(fs, dirp));
1.29 dholland 260: memcpy(dirp, &proto, sizeof(proto));
1.31 dholland 261: lfs_copydirname(fs, lfs_dir_nameptr(fs, dirp), ".", 1,
1.30 dholland 262: lfs_dir_getreclen(fs, dirp));
1.1 perseant 263: if (reply("FIX") == 1)
264: ret |= ALTERED;
265: } else {
1.29 dholland 266: /* split this entry and use the beginning for the . entry */
1.28 dholland 267: n = lfs_dir_getreclen(fs, dirp) - entrysize;
1.29 dholland 268: memcpy(dirp, &proto, sizeof(proto));
1.31 dholland 269: lfs_copydirname(fs, lfs_dir_nameptr(fs, dirp), ".", 1,
1.30 dholland 270: lfs_dir_getreclen(fs, dirp));
1.1 perseant 271: idesc->id_entryno++;
1.28 dholland 272: lncntp[lfs_dir_getino(fs, dirp)]--;
1.29 dholland 273: dirp = LFS_NEXTDIR(fs, dirp);
1.7 perseant 274: memset(dirp, 0, (size_t) n);
1.28 dholland 275: lfs_dir_setreclen(fs, dirp, n);
1.1 perseant 276: if (reply("FIX") == 1)
277: ret |= ALTERED;
278: }
279: chk1:
280: if (idesc->id_entryno > 1)
281: goto chk2;
282: inp = getinoinfo(idesc->id_number);
1.28 dholland 283: lfs_dir_setino(fs, &proto, inp->i_parent);
1.27 dholland 284: lfs_dir_settype(fs, &proto, LFS_DT_DIR);
285: lfs_dir_setnamlen(fs, &proto, 2);
1.33 ! dholland 286: entrysize = LFS_DIRECTSIZ(fs, 2);
1.29 dholland 287: lfs_dir_setreclen(fs, &proto, entrysize);
1.1 perseant 288: if (idesc->id_entryno == 0) {
1.27 dholland 289: n = LFS_DIRSIZ(fs, dirp);
1.28 dholland 290: if (lfs_dir_getreclen(fs, dirp) < n + entrysize)
1.1 perseant 291: goto chk2;
1.28 dholland 292: lfs_dir_setreclen(fs, &proto, lfs_dir_getreclen(fs, dirp) - n);
293: lfs_dir_setreclen(fs, dirp, n);
1.1 perseant 294: idesc->id_entryno++;
1.28 dholland 295: lncntp[lfs_dir_getino(fs, dirp)]--;
1.32 dholland 296: dirp = (struct lfs_dirheader *) ((char *) (dirp) + n);
1.28 dholland 297: memset(dirp, 0, lfs_dir_getreclen(fs, &proto));
298: lfs_dir_setreclen(fs, dirp, lfs_dir_getreclen(fs, &proto));
1.1 perseant 299: }
1.31 dholland 300: if (lfs_dir_getino(fs, dirp) != 0 && strcmp(lfs_dir_nameptr(fs, dirp), "..") == 0) {
1.28 dholland 301: inp->i_dotdot = lfs_dir_getino(fs, dirp);
1.27 dholland 302: if (lfs_dir_gettype(fs, dirp) != LFS_DT_DIR) {
1.1 perseant 303: direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'");
1.27 dholland 304: lfs_dir_settype(fs, dirp, LFS_DT_DIR);
1.1 perseant 305: if (reply("FIX") == 1)
306: ret |= ALTERED;
307: }
308: goto chk2;
309: }
1.31 dholland 310: if (lfs_dir_getino(fs, dirp) != 0 && strcmp(lfs_dir_nameptr(fs, dirp), ".") != 0) {
1.1 perseant 311: fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
312: pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
1.31 dholland 313: lfs_dir_nameptr(fs, dirp));
1.7 perseant 314: inp->i_dotdot = (ino_t) - 1;
1.28 dholland 315: } else if (lfs_dir_getreclen(fs, dirp) < entrysize) {
1.1 perseant 316: fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
317: pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n");
1.7 perseant 318: inp->i_dotdot = (ino_t) - 1;
1.1 perseant 319: } else if (inp->i_parent != 0) {
320: /*
321: * We know the parent, so fix now.
322: */
323: inp->i_dotdot = inp->i_parent;
324: fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
1.28 dholland 325: lfs_dir_setreclen(fs, &proto, lfs_dir_getreclen(fs, dirp));
1.7 perseant 326: memcpy(dirp, &proto, (size_t) entrysize);
1.31 dholland 327: lfs_copydirname(fs, lfs_dir_nameptr(fs, dirp), "..", 2,
1.30 dholland 328: lfs_dir_getreclen(fs, dirp));
1.1 perseant 329: if (reply("FIX") == 1)
330: ret |= ALTERED;
331: }
332: idesc->id_entryno++;
1.28 dholland 333: if (lfs_dir_getino(fs, dirp) != 0)
334: lncntp[lfs_dir_getino(fs, dirp)]--;
1.4 perseant 335: return (ret | KEEPON);
1.1 perseant 336: chk2:
1.28 dholland 337: if (lfs_dir_getino(fs, dirp) == 0)
1.4 perseant 338: return (ret | KEEPON);
1.27 dholland 339: if (lfs_dir_getnamlen(fs, dirp) <= 2 &&
1.31 dholland 340: lfs_dir_nameptr(fs, dirp)[0] == '.' &&
1.1 perseant 341: idesc->id_entryno >= 2) {
1.27 dholland 342: if (lfs_dir_getnamlen(fs, dirp) == 1) {
1.1 perseant 343: direrror(idesc->id_number, "EXTRA '.' ENTRY");
1.27 dholland 344: if (reply("FIX") == 1) {
1.28 dholland 345: lfs_dir_setino(fs, dirp, 0);
1.1 perseant 346: ret |= ALTERED;
1.27 dholland 347: }
1.1 perseant 348: return (KEEPON | ret);
349: }
1.31 dholland 350: if (lfs_dir_nameptr(fs, dirp)[1] == '.') {
1.1 perseant 351: direrror(idesc->id_number, "EXTRA '..' ENTRY");
1.27 dholland 352: if (reply("FIX") == 1) {
1.28 dholland 353: lfs_dir_setino(fs, dirp, 0);
1.1 perseant 354: ret |= ALTERED;
1.27 dholland 355: }
1.1 perseant 356: return (KEEPON | ret);
357: }
358: }
359: idesc->id_entryno++;
360: n = 0;
1.28 dholland 361: if (lfs_dir_getino(fs, dirp) >= maxino) {
362: fileerror(idesc->id_number, lfs_dir_getino(fs, dirp), "I OUT OF RANGE");
1.1 perseant 363: n = reply("REMOVE");
1.28 dholland 364: } else if (lfs_dir_getino(fs, dirp) == LFS_IFILE_INUM &&
1.19 dholland 365: idesc->id_number == ULFS_ROOTINO) {
1.27 dholland 366: if (lfs_dir_gettype(fs, dirp) != LFS_DT_REG) {
1.28 dholland 367: fileerror(idesc->id_number, lfs_dir_getino(fs, dirp),
1.7 perseant 368: "BAD TYPE FOR IFILE");
1.27 dholland 369: if (reply("FIX") == 1) {
370: lfs_dir_settype(fs, dirp, LFS_DT_REG);
1.4 perseant 371: ret |= ALTERED;
1.27 dholland 372: }
1.4 perseant 373: }
1.28 dholland 374: } else if (((lfs_dir_getino(fs, dirp) == ULFS_WINO && lfs_dir_gettype(fs, dirp) != LFS_DT_WHT) ||
375: (lfs_dir_getino(fs, dirp) != ULFS_WINO && lfs_dir_gettype(fs, dirp) == LFS_DT_WHT))) {
376: fileerror(idesc->id_number, lfs_dir_getino(fs, dirp), "BAD WHITEOUT ENTRY");
1.27 dholland 377: if (reply("FIX") == 1) {
1.28 dholland 378: lfs_dir_setino(fs, dirp, ULFS_WINO);
1.27 dholland 379: lfs_dir_settype(fs, dirp, LFS_DT_WHT);
1.1 perseant 380: ret |= ALTERED;
1.27 dholland 381: }
1.1 perseant 382: } else {
383: again:
1.28 dholland 384: switch (statemap[lfs_dir_getino(fs, dirp)]) {
1.1 perseant 385: case USTATE:
386: if (idesc->id_entryno <= 2)
387: break;
1.28 dholland 388: fileerror(idesc->id_number, lfs_dir_getino(fs, dirp),
389: "UNALLOCATED");
1.1 perseant 390: n = reply("REMOVE");
391: break;
392:
393: case DCLEAR:
394: case FCLEAR:
395: if (idesc->id_entryno <= 2)
396: break;
1.28 dholland 397: if (statemap[lfs_dir_getino(fs, dirp)] == FCLEAR)
1.1 perseant 398: errmsg = "DUP/BAD";
399: else if (!preen)
400: errmsg = "ZERO LENGTH DIRECTORY";
401: else {
402: n = 1;
403: break;
404: }
1.28 dholland 405: fileerror(idesc->id_number, lfs_dir_getino(fs, dirp), errmsg);
1.1 perseant 406: if ((n = reply("REMOVE")) == 1)
407: break;
1.28 dholland 408: dp = ginode(lfs_dir_getino(fs, dirp));
409: statemap[lfs_dir_getino(fs, dirp)] =
1.26 dholland 410: (lfs_dino_getmode(fs, dp) & LFS_IFMT) == LFS_IFDIR ? DSTATE : FSTATE;
1.28 dholland 411: lncntp[lfs_dir_getino(fs, dirp)] = lfs_dino_getnlink(fs, dp);
1.1 perseant 412: goto again;
413:
414: case DSTATE:
415: case DFOUND:
1.28 dholland 416: inp = getinoinfo(lfs_dir_getino(fs, dirp));
1.1 perseant 417: if (inp->i_parent != 0 && idesc->id_entryno > 2) {
1.9 itojun 418: getpathname(pathbuf, sizeof(pathbuf),
419: idesc->id_number, idesc->id_number);
420: getpathname(namebuf, sizeof(namebuf),
1.28 dholland 421: lfs_dir_getino(fs, dirp),
422: lfs_dir_getino(fs, dirp));
1.1 perseant 423: pwarn("%s %s %s\n", pathbuf,
1.7 perseant 424: "IS AN EXTRANEOUS HARD LINK TO DIRECTORY",
425: namebuf);
1.1 perseant 426: if (preen)
427: printf(" (IGNORED)\n");
428: else if ((n = reply("REMOVE")) == 1)
429: break;
430: }
431: if (idesc->id_entryno > 2)
432: inp->i_parent = idesc->id_number;
433: /* fall through */
434:
435: case FSTATE:
1.28 dholland 436: if (lfs_dir_gettype(fs, dirp) != typemap[lfs_dir_getino(fs, dirp)]) {
437: fileerror(idesc->id_number,
438: lfs_dir_getino(fs, dirp),
1.7 perseant 439: "BAD TYPE VALUE");
1.13 perseant 440: if (debug)
441: pwarn("dir has %d, typemap has %d\n",
1.28 dholland 442: lfs_dir_gettype(fs, dirp), typemap[lfs_dir_getino(fs, dirp)]);
443: lfs_dir_settype(fs, dirp, typemap[lfs_dir_getino(fs, dirp)]);
1.1 perseant 444: if (reply("FIX") == 1)
445: ret |= ALTERED;
446: }
1.28 dholland 447: lncntp[lfs_dir_getino(fs, dirp)]--;
1.1 perseant 448: break;
449:
450: default:
1.28 dholland 451: errx(EEXIT, "BAD STATE %d FOR INODE I=%ju",
452: statemap[lfs_dir_getino(fs, dirp)],
453: (uintmax_t)lfs_dir_getino(fs, dirp));
1.1 perseant 454: }
455: }
456: if (n == 0)
1.4 perseant 457: return (ret | KEEPON);
1.28 dholland 458: lfs_dir_setino(fs, dirp, 0);
1.4 perseant 459: return (ret | KEEPON | ALTERED);
1.1 perseant 460: }
461: /*
462: * Routine to sort disk blocks.
463: */
464: static int
1.4 perseant 465: blksort(const void *inpp1, const void *inpp2)
1.1 perseant 466: {
1.14 christos 467: return ((*(const struct inoinfo *const *) inpp1)->i_blks[0] -
468: (*(const struct inoinfo *const *) inpp2)->i_blks[0]);
1.1 perseant 469: }
CVSweb <webmaster@jp.NetBSD.org>