int common_check() { int pcount=1; int error; int try=0; struct stat stbuf; char *dirstr; if ( chkoptions.optimizetc == 1 ){ printf( "Phase %i : Running optimize on the databases. ",pcount); tc_defrag(); pcount++; } error=dbstat("/lost+found",&stbuf); if ( error == -ENOENT ) { lost_mkdir("/lost+found"); error=dbstat("/lost+found",&stbuf); } while ( !S_ISDIR(stbuf.st_mode)) { show_progress(); printf("Someone silly (YOU) created lost+found as a regular file.\n"); dirstr=as_sprintf("/lost+found_%i",try); error=dbstat(dirstr,&stbuf); if ( -ENOENT == error ) { lost_mkdir(dirstr); error=dbstat(dirstr,&stbuf); free(dirstr); break; } free(dirstr); try++; if ( try > 3 ) { printf("Stupidity count overflow.\n"); exit(EXIT_USAGE); } } lafinode=stbuf.st_ino; printf( "%c \nPhase %u : Check directory structure.\n",BACKSPACE,pcount); check_directory_structure(); pcount++; printf( "%cPhase %u : Check for orphaned inodes.\n",BACKSPACE, pcount); check_inodes(); pcount++; return(pcount); } void lessfsck_tc() { int pcount=common_check(); printf("%cPhase %u : Check for orphaned data blocks.\n",BACKSPACE,pcount); check_orphaned_data_blocks(); pcount++; }
/************************************************************************* * MAIN ENTRY POINT FOR THE FILE-SYSTEM CHECKER * * - The different passes of the checking process ... * * Parameter : full = TRUE : Full check incl. directory tree scan * FALSE: only check_unique() then full check if * any errors occurred * Return : FALSE, if a fatal error-condition occurred * *************************************************************************/ word fscheck ( word full ) { struct buf *bpar, *bp; /* used for check_inodes() */ struct dir_elem root_de; /* For fatal error handling. This longjmp - */ /* location is used, if bread() to fixed block- */ /* numbers (like 1,2,3) fails or memory alloca- */ /* operations do not succeed. */ if ( setjmp ( term_jmp ) != 0 ) { IOdebug ("%sCHECKER INTERRUPTED DUE TO A FATAL ERROR CONDITION!", S_FATAL); IOdebug ("%s(Especially block-read and memory allocation operations)", S_FATAL); finish_checker (); return FALSE; } if ( ! init_checker () ) /* Basic initialization */ return FALSE; /*--------------- The four steps of the checking process ---------------*/ IOdebug ( "%sSTEP 1 : CHECKING BASIC DATA STRUCTURES", S_INFO ); unique_err = 0; if ( ! check_unique () ) /* Basic tests on superblock */ { /* and other unique structures */ IOdebug ("%sDURING BASIC DATA STRUCTURE CHECK", S_FATAL); finish_checker (); return FALSE; } if ( !full && !unique_err ) { finish_checker (); /* Finish checking, tidy up and */ /* unlock the server's ports */ return TRUE; /* Terminate checker process */ } IOdebug ( "%sSTEP 2 : TRAVERSING THE DIRECTORY TREE (INODE-CHECK)", S_INFO); bpar = bread ( 0, 1, 1, SAVEA ); /* Get sum-block with root-dir */ /* if read fails jmp to term_jmp */ /* Start from the file-server's */ /* root position */ memcpy ( &root_de, &bpar->b_un.b_sum->root_dir, sizeof (struct dir_elem) ); brelse ( bpar->b_tbp, TAIL ); /* Release summary block */ /* Up from this point, we get a */ /* Work on the directory tree */ if ( ! check_inodes ( &root_de , 1, 0 ) ) { IOdebug ("%sDURING SIMPLE OBJECT (INODE) CHECK", S_FATAL); finish_checker (); return FALSE; } /* Work on the bit-maps */ IOdebug ( "%sSTEP 3 : MAKE BLOCK-BASED CONNECTIVITY CHECKS", S_INFO); if ( ! check_blocks () ) { IOdebug ("%sDURING BIT-MAP AND CONNECTIVITY CHECK", S_FATAL); finish_checker (); return FALSE; } actual_path[0] = '\0'; /* Perform some final tidy-up */ /* operations */ IOdebug ("%sSTEP 4 : TIDYUP EVERYTHING AND CORRECT SUMMARY INFORMATIONS", S_INFO); if ( ! tidy_update () ) { IOdebug ("%sDURING TIDY UP OPERATION", S_FATAL); finish_checker (); return FALSE; } finish_checker (); /* Finish checking, tidy up and */ /* unlock the server's ports */ return TRUE; /* Terminate checker process */ }