pass2.c revision 23675
1251538Srpaulo/* 2251538Srpaulo * Copyright (c) 1980, 1986, 1993 3251538Srpaulo * The Regents of the University of California. All rights reserved. 4251538Srpaulo * 5264912Skevlo * Redistribution and use in source and binary forms, with or without 6292176Savos * modification, are permitted provided that the following conditions 7251538Srpaulo * are met: 8251538Srpaulo * 1. Redistributions of source code must retain the above copyright 9251538Srpaulo * notice, this list of conditions and the following disclaimer. 10251538Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 11251538Srpaulo * notice, this list of conditions and the following disclaimer in the 12251538Srpaulo * documentation and/or other materials provided with the distribution. 13251538Srpaulo * 3. All advertising materials mentioning features or use of this software 14251538Srpaulo * must display the following acknowledgement: 15251538Srpaulo * This product includes software developed by the University of 16251538Srpaulo * California, Berkeley and its contributors. 17251538Srpaulo * 4. Neither the name of the University nor the names of its contributors 18251538Srpaulo * may be used to endorse or promote products derived from this software 19251538Srpaulo * without specific prior written permission. 20251538Srpaulo * 21251538Srpaulo * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22251538Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23251538Srpaulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24251538Srpaulo * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25264912Skevlo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26251538Srpaulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27251538Srpaulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28288353Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29288353Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30251538Srpaulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31251538Srpaulo * SUCH DAMAGE. 32251538Srpaulo */ 33251538Srpaulo 34251538Srpaulo#ifndef lint 35291902Skevlostatic const char sccsid[] = "@(#)pass2.c 8.9 (Berkeley) 4/28/95"; 36251538Srpaulo#endif /* not lint */ 37251538Srpaulo 38251538Srpaulo#include <sys/param.h> 39251538Srpaulo#include <sys/time.h> 40251538Srpaulo 41251538Srpaulo#include <ufs/ufs/dinode.h> 42251538Srpaulo#include <ufs/ufs/dir.h> 43251538Srpaulo#include <ufs/ffs/fs.h> 44251538Srpaulo#include <stdio.h> 45251538Srpaulo#include <stdlib.h> 46251538Srpaulo#include <err.h> 47251538Srpaulo#include <string.h> 48251538Srpaulo 49251538Srpaulo#include "fsck.h" 50251538Srpaulo 51251538Srpaulo#define MINDIRSIZE (sizeof (struct dirtemplate)) 52251538Srpaulo 53251538Srpaulostatic int blksort __P((const void *, const void *)); 54257176Sglebiusstatic int pass2check __P((struct inodesc *)); 55251538Srpaulo 56251538Srpaulovoid 57251538Srpaulopass2() 58251538Srpaulo{ 59251538Srpaulo register struct dinode *dp; 60251538Srpaulo register struct inoinfo **inpp, *inp; 61251538Srpaulo struct inoinfo **inpend; 62251538Srpaulo struct inodesc curino; 63251538Srpaulo struct dinode dino; 64251538Srpaulo char pathbuf[MAXPATHLEN + 1]; 65251538Srpaulo 66251538Srpaulo switch (statemap[ROOTINO]) { 67251538Srpaulo 68288088Sadrian case USTATE: 69251538Srpaulo pfatal("ROOT INODE UNALLOCATED"); 70251538Srpaulo if (reply("ALLOCATE") == 0) 71251538Srpaulo exit(EEXIT); 72251538Srpaulo if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) 73251538Srpaulo errx(EEXIT, "CANNOT ALLOCATE ROOT INODE"); 74251538Srpaulo break; 75291902Skevlo 76251538Srpaulo case DCLEAR: 77251538Srpaulo pfatal("DUPS/BAD IN ROOT INODE"); 78251538Srpaulo if (reply("REALLOCATE")) { 79251538Srpaulo freeino(ROOTINO); 80251538Srpaulo if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) 81251538Srpaulo errx(EEXIT, "CANNOT ALLOCATE ROOT INODE"); 82289167Sadrian break; 83251538Srpaulo } 84251538Srpaulo if (reply("CONTINUE") == 0) 85251538Srpaulo exit(EEXIT); 86251538Srpaulo break; 87251538Srpaulo 88276701Shselasky case FSTATE: 89251538Srpaulo case FCLEAR: 90251538Srpaulo pfatal("ROOT INODE NOT DIRECTORY"); 91251538Srpaulo if (reply("REALLOCATE")) { 92288088Sadrian freeino(ROOTINO); 93251538Srpaulo if (allocdir(ROOTINO, ROOTINO, 0755) != ROOTINO) 94251538Srpaulo errx(EEXIT, "CANNOT ALLOCATE ROOT INODE"); 95251596Srpaulo break; 96251538Srpaulo } 97264912Skevlo if (reply("FIX") == 0) 98264912Skevlo exit(EEXIT); 99264912Skevlo dp = ginode(ROOTINO); 100251538Srpaulo dp->di_mode &= ~IFMT; 101251538Srpaulo dp->di_mode |= IFDIR; 102251538Srpaulo inodirty(); 103251538Srpaulo break; 104266721Skevlo 105251538Srpaulo case DSTATE: 106251538Srpaulo break; 107251538Srpaulo 108251538Srpaulo default: 109251538Srpaulo errx(EEXIT, "BAD STATE %d FOR ROOT INODE", statemap[ROOTINO]); 110251538Srpaulo } 111251538Srpaulo statemap[ROOTINO] = DFOUND; 112251538Srpaulo if (newinofmt) { 113251538Srpaulo statemap[WINO] = FSTATE; 114251538Srpaulo typemap[WINO] = DT_WHT; 115251538Srpaulo } 116251538Srpaulo /* 117251538Srpaulo * Sort the directory list into disk block order. 118251538Srpaulo */ 119251538Srpaulo qsort((char *)inpsort, (size_t)inplast, sizeof *inpsort, blksort); 120251538Srpaulo /* 121252196Skevlo * Check the integrity of each directory. 122251538Srpaulo */ 123251538Srpaulo memset(&curino, 0, sizeof(struct inodesc)); 124251538Srpaulo curino.id_type = DATA; 125251538Srpaulo curino.id_func = pass2check; 126251538Srpaulo dp = &dino; 127251538Srpaulo inpend = &inpsort[inplast]; 128251538Srpaulo for (inpp = inpsort; inpp < inpend; inpp++) { 129251538Srpaulo inp = *inpp; 130251538Srpaulo if (inp->i_isize == 0) 131251538Srpaulo continue; 132251538Srpaulo if (inp->i_isize < MINDIRSIZE) { 133251538Srpaulo direrror(inp->i_number, "DIRECTORY TOO SHORT"); 134251538Srpaulo inp->i_isize = roundup(MINDIRSIZE, DIRBLKSIZ); 135251538Srpaulo if (reply("FIX") == 1) { 136251538Srpaulo dp = ginode(inp->i_number); 137251538Srpaulo dp->di_size = inp->i_isize; 138251538Srpaulo inodirty(); 139251538Srpaulo dp = &dino; 140251538Srpaulo } 141251538Srpaulo } else if ((inp->i_isize & (DIRBLKSIZ - 1)) != 0) { 142251538Srpaulo getpathname(pathbuf, inp->i_number, inp->i_number); 143251538Srpaulo pwarn("DIRECTORY %s: LENGTH %d NOT MULTIPLE OF %d", 144251538Srpaulo pathbuf, inp->i_isize, DIRBLKSIZ); 145282119Skevlo if (preen) 146251538Srpaulo printf(" (ADJUSTED)\n"); 147251538Srpaulo inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ); 148251538Srpaulo if (preen || reply("ADJUST") == 1) { 149251538Srpaulo dp = ginode(inp->i_number); 150272410Shselasky dp->di_size = roundup(inp->i_isize, DIRBLKSIZ); 151251538Srpaulo inodirty(); 152251538Srpaulo dp = &dino; 153251538Srpaulo } 154251538Srpaulo } 155251538Srpaulo memset(&dino, 0, sizeof(struct dinode)); 156251538Srpaulo dino.di_mode = IFDIR; 157251538Srpaulo dp->di_size = inp->i_isize; 158251538Srpaulo memmove(&dp->di_db[0], &inp->i_blks[0], (size_t)inp->i_numblks); 159251538Srpaulo curino.id_number = inp->i_number; 160264912Skevlo curino.id_parent = inp->i_parent; 161273589Skevlo (void)ckinode(dp, &curino); 162270191Skevlo } 163273589Skevlo /* 164264912Skevlo * Now that the parents of all directories have been found, 165264912Skevlo * make another pass to verify the value of `..' 166264912Skevlo */ 167251538Srpaulo for (inpp = inpsort; inpp < inpend; inpp++) { 168251538Srpaulo inp = *inpp; 169251538Srpaulo if (inp->i_parent == 0 || inp->i_isize == 0) 170251538Srpaulo continue; 171251538Srpaulo if (statemap[inp->i_parent] == DFOUND && 172251538Srpaulo statemap[inp->i_number] == DSTATE) 173251538Srpaulo statemap[inp->i_number] = DFOUND; 174251538Srpaulo if (inp->i_dotdot == inp->i_parent || 175251538Srpaulo inp->i_dotdot == (ino_t)-1) 176251538Srpaulo continue; 177288353Sadrian if (inp->i_dotdot == 0) { 178287197Sglebius inp->i_dotdot = inp->i_parent; 179287197Sglebius fileerror(inp->i_parent, inp->i_number, "MISSING '..'"); 180251538Srpaulo if (reply("FIX") == 0) 181251538Srpaulo continue; 182251538Srpaulo (void)makeentry(inp->i_number, inp->i_parent, ".."); 183251538Srpaulo lncntp[inp->i_parent]--; 184251538Srpaulo continue; 185292207Savos } 186292207Savos fileerror(inp->i_parent, inp->i_number, 187292207Savos "BAD INODE NUMBER FOR '..'"); 188292207Savos if (reply("FIX") == 0) 189292207Savos continue; 190292167Savos lncntp[inp->i_dotdot]++; 191292167Savos lncntp[inp->i_parent]--; 192292207Savos inp->i_dotdot = inp->i_parent; 193292207Savos (void)changeino(inp->i_number, "..", inp->i_parent); 194289891Savos } 195289891Savos /* 196281069Srpaulo * Mark all the directories that can be found from the root. 197251538Srpaulo */ 198251538Srpaulo propagate(); 199251538Srpaulo} 200251538Srpaulo 201251538Srpaulostatic int 202289066Skevlopass2check(idesc) 203289066Skevlo struct inodesc *idesc; 204251538Srpaulo{ 205251538Srpaulo register struct direct *dirp = idesc->id_dirp; 206291698Savos register struct inoinfo *inp; 207251538Srpaulo int n, entrysize, ret = 0; 208291698Savos struct dinode *dp; 209291698Savos char *errmsg; 210291698Savos struct direct proto; 211291698Savos char namebuf[MAXPATHLEN + 1]; 212251538Srpaulo char pathbuf[MAXPATHLEN + 1]; 213251538Srpaulo 214251538Srpaulo /* 215251538Srpaulo * If converting, set directory entry type. 216281069Srpaulo */ 217251538Srpaulo if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) { 218292174Savos dirp->d_type = typemap[dirp->d_ino]; 219292174Savos ret |= ALTERED; 220292174Savos } 221264912Skevlo /* 222264912Skevlo * check for "." 223281069Srpaulo */ 224264912Skevlo if (idesc->id_entryno != 0) 225251538Srpaulo goto chk1; 226281069Srpaulo if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") == 0) { 227251538Srpaulo if (dirp->d_ino != idesc->id_number) { 228291264Savos direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'"); 229291264Savos dirp->d_ino = idesc->id_number; 230291264Savos if (reply("FIX") == 1) 231291264Savos ret |= ALTERED; 232291264Savos } 233291264Savos if (newinofmt && dirp->d_type != DT_DIR) { 234291264Savos direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'"); 235291264Savos dirp->d_type = DT_DIR; 236291264Savos if (reply("FIX") == 1) 237291698Savos ret |= ALTERED; 238251538Srpaulo } 239291264Savos goto chk1; 240291264Savos } 241251538Srpaulo direrror(idesc->id_number, "MISSING '.'"); 242290631Savos proto.d_ino = idesc->id_number; 243290631Savos if (newinofmt) 244290631Savos proto.d_type = DT_DIR; 245290631Savos else 246290631Savos proto.d_type = 0; 247290631Savos proto.d_namlen = 1; 248290631Savos (void)strcpy(proto.d_name, "."); 249292175Savos# if BYTE_ORDER == LITTLE_ENDIAN 250292175Savos if (!newinofmt) { 251292175Savos u_char tmp; 252292175Savos 253292175Savos tmp = proto.d_type; 254292175Savos proto.d_type = proto.d_namlen; 255292175Savos proto.d_namlen = tmp; 256292175Savos } 257292175Savos# endif 258292175Savos entrysize = DIRSIZ(0, &proto); 259292175Savos if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) { 260290651Savos pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n", 261290631Savos dirp->d_name); 262290631Savos } else if (dirp->d_reclen < entrysize) { 263292203Savos pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n"); 264251538Srpaulo } else if (dirp->d_reclen < 2 * entrysize) { 265289811Savos proto.d_reclen = dirp->d_reclen; 266290651Savos memmove(dirp, &proto, (size_t)entrysize); 267290651Savos if (reply("FIX") == 1) 268290651Savos ret |= ALTERED; 269281069Srpaulo } else { 270251538Srpaulo n = dirp->d_reclen - entrysize; 271251538Srpaulo proto.d_reclen = entrysize; 272251538Srpaulo memmove(dirp, &proto, (size_t)entrysize); 273251538Srpaulo idesc->id_entryno++; 274264912Skevlo lncntp[dirp->d_ino]--; 275290630Savos dirp = (struct direct *)((char *)(dirp) + entrysize); 276251538Srpaulo memset(dirp, 0, (size_t)n); 277251538Srpaulo dirp->d_reclen = n; 278292221Savos if (reply("FIX") == 1) 279292221Savos ret |= ALTERED; 280292221Savos } 281292221Savoschk1: 282290630Savos if (idesc->id_entryno > 1) 283290630Savos goto chk2; 284287197Sglebius inp = getinoinfo(idesc->id_number); 285287197Sglebius proto.d_ino = inp->i_parent; 286287197Sglebius if (newinofmt) 287264912Skevlo proto.d_type = DT_DIR; 288264912Skevlo else 289251538Srpaulo proto.d_type = 0; 290251538Srpaulo proto.d_namlen = 2; 291264912Skevlo (void)strcpy(proto.d_name, ".."); 292281069Srpaulo# if BYTE_ORDER == LITTLE_ENDIAN 293251538Srpaulo if (!newinofmt) { 294251538Srpaulo u_char tmp; 295291902Skevlo 296291698Savos tmp = proto.d_type; 297251538Srpaulo proto.d_type = proto.d_namlen; 298251538Srpaulo proto.d_namlen = tmp; 299251538Srpaulo } 300292175Savos# endif 301292175Savos entrysize = DIRSIZ(0, &proto); 302251538Srpaulo if (idesc->id_entryno == 0) { 303251538Srpaulo n = DIRSIZ(0, dirp); 304251538Srpaulo if (dirp->d_reclen < n + entrysize) 305281069Srpaulo goto chk2; 306251538Srpaulo proto.d_reclen = dirp->d_reclen - n; 307251538Srpaulo dirp->d_reclen = n; 308281069Srpaulo idesc->id_entryno++; 309251538Srpaulo lncntp[dirp->d_ino]--; 310264912Skevlo dirp = (struct direct *)((char *)(dirp) + n); 311281069Srpaulo memset(dirp, 0, (size_t)proto.d_reclen); 312264912Skevlo dirp->d_reclen = proto.d_reclen; 313251538Srpaulo } 314281069Srpaulo if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) { 315251538Srpaulo inp->i_dotdot = dirp->d_ino; 316290048Savos if (newinofmt && dirp->d_type != DT_DIR) { 317290048Savos direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'"); 318251538Srpaulo dirp->d_type = DT_DIR; 319251538Srpaulo if (reply("FIX") == 1) 320251538Srpaulo ret |= ALTERED; 321292014Savos } 322290564Savos goto chk2; 323290564Savos } 324289066Skevlo if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") != 0) { 325292167Savos fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); 326292167Savos pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n", 327292167Savos dirp->d_name); 328292167Savos inp->i_dotdot = (ino_t)-1; 329251538Srpaulo } else if (dirp->d_reclen < entrysize) { 330281069Srpaulo fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); 331251538Srpaulo pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '..'\n"); 332251538Srpaulo inp->i_dotdot = (ino_t)-1; 333251538Srpaulo } else if (inp->i_parent != 0) { 334291698Savos /* 335287197Sglebius * We know the parent, so fix now. 336251538Srpaulo */ 337251538Srpaulo inp->i_dotdot = inp->i_parent; 338251538Srpaulo fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); 339266472Shselasky proto.d_reclen = dirp->d_reclen; 340251538Srpaulo memmove(dirp, &proto, (size_t)entrysize); 341251538Srpaulo if (reply("FIX") == 1) 342251538Srpaulo ret |= ALTERED; 343251538Srpaulo } 344251538Srpaulo idesc->id_entryno++; 345251538Srpaulo if (dirp->d_ino != 0) 346251538Srpaulo lncntp[dirp->d_ino]--; 347251538Srpaulo return (ret|KEEPON); 348251538Srpaulochk2: 349251538Srpaulo if (dirp->d_ino == 0) 350251538Srpaulo return (ret|KEEPON); 351251538Srpaulo if (dirp->d_namlen <= 2 && 352251538Srpaulo dirp->d_name[0] == '.' && 353251538Srpaulo idesc->id_entryno >= 2) { 354251538Srpaulo if (dirp->d_namlen == 1) { 355251538Srpaulo direrror(idesc->id_number, "EXTRA '.' ENTRY"); 356251538Srpaulo dirp->d_ino = 0; 357251538Srpaulo if (reply("FIX") == 1) 358251538Srpaulo ret |= ALTERED; 359251538Srpaulo return (KEEPON | ret); 360251538Srpaulo } 361251538Srpaulo if (dirp->d_name[1] == '.') { 362251538Srpaulo direrror(idesc->id_number, "EXTRA '..' ENTRY"); 363251538Srpaulo dirp->d_ino = 0; 364251538Srpaulo if (reply("FIX") == 1) 365251538Srpaulo ret |= ALTERED; 366251538Srpaulo return (KEEPON | ret); 367251538Srpaulo } 368251538Srpaulo } 369251538Srpaulo idesc->id_entryno++; 370251538Srpaulo n = 0; 371251538Srpaulo if (dirp->d_ino > maxino) { 372251538Srpaulo fileerror(idesc->id_number, dirp->d_ino, "I OUT OF RANGE"); 373251538Srpaulo n = reply("REMOVE"); 374251538Srpaulo } else if (newinofmt && 375251538Srpaulo ((dirp->d_ino == WINO && dirp->d_type != DT_WHT) || 376251538Srpaulo (dirp->d_ino != WINO && dirp->d_type == DT_WHT))) { 377251538Srpaulo fileerror(idesc->id_number, dirp->d_ino, "BAD WHITEOUT ENTRY"); 378251538Srpaulo dirp->d_ino = WINO; 379251538Srpaulo dirp->d_type = DT_WHT; 380251538Srpaulo if (reply("FIX") == 1) 381251538Srpaulo ret |= ALTERED; 382251538Srpaulo } else { 383251538Srpauloagain: 384251538Srpaulo switch (statemap[dirp->d_ino]) { 385251538Srpaulo case USTATE: 386251538Srpaulo if (idesc->id_entryno <= 2) 387251538Srpaulo break; 388251538Srpaulo fileerror(idesc->id_number, dirp->d_ino, "UNALLOCATED"); 389251538Srpaulo n = reply("REMOVE"); 390251538Srpaulo break; 391251538Srpaulo 392251538Srpaulo case DCLEAR: 393251538Srpaulo case FCLEAR: 394251538Srpaulo if (idesc->id_entryno <= 2) 395251538Srpaulo break; 396251538Srpaulo if (statemap[dirp->d_ino] == FCLEAR) 397251538Srpaulo errmsg = "DUP/BAD"; 398251538Srpaulo else if (!preen) 399251538Srpaulo errmsg = "ZERO LENGTH DIRECTORY"; 400251538Srpaulo else { 401251538Srpaulo n = 1; 402251538Srpaulo break; 403251538Srpaulo } 404251538Srpaulo fileerror(idesc->id_number, dirp->d_ino, errmsg); 405251538Srpaulo if ((n = reply("REMOVE")) == 1) 406251538Srpaulo break; 407251538Srpaulo dp = ginode(dirp->d_ino); 408251538Srpaulo statemap[dirp->d_ino] = 409251538Srpaulo (dp->di_mode & IFMT) == IFDIR ? DSTATE : FSTATE; 410251538Srpaulo lncntp[dirp->d_ino] = dp->di_nlink; 411292014Savos goto again; 412292014Savos 413292014Savos case DSTATE: 414292014Savos if (statemap[idesc->id_number] == DFOUND) 415292014Savos statemap[dirp->d_ino] = DFOUND; 416292014Savos /* fall through */ 417292014Savos 418292014Savos case DFOUND: 419292014Savos inp = getinoinfo(dirp->d_ino); 420292014Savos if (inp->i_parent != 0 && idesc->id_entryno > 2) { 421251538Srpaulo getpathname(pathbuf, idesc->id_number, 422251538Srpaulo idesc->id_number); 423251538Srpaulo getpathname(namebuf, dirp->d_ino, dirp->d_ino); 424251538Srpaulo pwarn("%s %s %s\n", pathbuf, 425251538Srpaulo "IS AN EXTRANEOUS HARD LINK TO DIRECTORY", 426251538Srpaulo namebuf); 427251538Srpaulo if (preen) 428251538Srpaulo printf(" (IGNORED)\n"); 429251538Srpaulo else if ((n = reply("REMOVE")) == 1) 430251538Srpaulo break; 431251538Srpaulo } 432251538Srpaulo if (idesc->id_entryno > 2) 433251538Srpaulo inp->i_parent = idesc->id_number; 434251538Srpaulo /* fall through */ 435251538Srpaulo 436251538Srpaulo case FSTATE: 437251538Srpaulo if (newinofmt && dirp->d_type != typemap[dirp->d_ino]) { 438251538Srpaulo fileerror(idesc->id_number, dirp->d_ino, 439251538Srpaulo "BAD TYPE VALUE"); 440251538Srpaulo dirp->d_type = typemap[dirp->d_ino]; 441287197Sglebius if (reply("FIX") == 1) 442293339Savos ret |= ALTERED; 443251538Srpaulo } 444251538Srpaulo lncntp[dirp->d_ino]--; 445251538Srpaulo break; 446251538Srpaulo 447251538Srpaulo default: 448264912Skevlo errx(EEXIT, "BAD STATE %d FOR INODE I=%d", 449264912Skevlo statemap[dirp->d_ino], dirp->d_ino); 450251538Srpaulo } 451251538Srpaulo } 452251538Srpaulo if (n == 0) 453292174Savos return (ret|KEEPON); 454292167Savos dirp->d_ino = 0; 455251538Srpaulo return (ret|KEEPON|ALTERED); 456287197Sglebius} 457251538Srpaulo 458291902Skevlo/* 459291902Skevlo * Routine to sort disk blocks. 460291902Skevlo */ 461251538Srpaulostatic int 462251538Srpauloblksort(arg1, arg2) 463251538Srpaulo const void *arg1, *arg2; 464251538Srpaulo{ 465251538Srpaulo 466251538Srpaulo return ((*(struct inoinfo **)arg1)->i_blks[0] - 467251538Srpaulo (*(struct inoinfo **)arg2)->i_blks[0]); 468251538Srpaulo} 469251538Srpaulo