📄 fsck.minix.c
字号:
if (!S_ISDIR (inode->i_mode) && !S_ISREG (inode->i_mode) && !S_ISLNK (inode->i_mode)) return; for (i = 0; i < 7; i++) add_zone2 (i + inode->i_zone, &changed); add_zone_ind2 (7 + inode->i_zone, &changed); add_zone_dind2 (8 + inode->i_zone, &changed); add_zone_tind2 (9 + inode->i_zone, &changed);}static voidcheck_file(struct minix_inode * dir, unsigned int offset) { static char blk[BLOCK_SIZE]; struct minix_inode * inode; int ino; char * name; int block; block = map_block(dir,offset/BLOCK_SIZE); read_block(block, blk); name = blk + (offset % BLOCK_SIZE) + 2; ino = * (unsigned short *) (name-2); if (ino > INODES) { get_current_name(); printf(_("The directory '%s' contains a bad inode number " "for file '%.*s'."), current_name, namelen, name); if (ask(_(" Remove"),1)) { *(unsigned short *)(name-2) = 0; write_block(block, blk); } ino = 0; } if (name_depth < MAX_DEPTH) strncpy (name_list[name_depth], name, namelen); name_depth++; inode = get_inode(ino); name_depth--; if (!offset) { if (!inode || strcmp(".",name)) { get_current_name(); printf(_("`%s': bad directory: '.' isn't first\n"), current_name); errors_uncorrected = 1; } else return; } if (offset == dirsize) { if (!inode || strcmp("..",name)) { get_current_name(); printf(_("`%s': bad directory: '..' isn't second\n"), current_name); errors_uncorrected = 1; } else return; } if (!inode) return; if (name_depth < MAX_DEPTH) strncpy(name_list[name_depth], name, namelen); name_depth++; if (list) { if (verbose) printf("%6d %07o %3d ", ino, inode->i_mode, inode->i_nlinks); get_current_name(); printf("%s", current_name); if (S_ISDIR(inode->i_mode)) printf(":\n"); else printf("\n"); } check_zones(ino); if (inode && S_ISDIR(inode->i_mode)) recursive_check(ino); name_depth--; return;}static voidcheck_file2 (struct minix2_inode *dir, unsigned int offset) { static char blk[BLOCK_SIZE]; struct minix2_inode *inode; int ino; char *name; int block; block = map_block2 (dir, offset / BLOCK_SIZE); read_block (block, blk); name = blk + (offset % BLOCK_SIZE) + 2; ino = *(unsigned short *) (name - 2); if (ino > INODES) { get_current_name(); printf(_("The directory '%s' contains a bad inode number " "for file '%.*s'."), current_name, namelen, name); if (ask (_(" Remove"), 1)) { *(unsigned short *) (name - 2) = 0; write_block (block, blk); } ino = 0; } if (name_depth < MAX_DEPTH) strncpy (name_list[name_depth], name, namelen); name_depth++; inode = get_inode2 (ino); name_depth--; if (!offset) { if (!inode || strcmp (".", name)) { get_current_name (); printf (_("%s: bad directory: '.' isn't first\n"), current_name); errors_uncorrected = 1; } else return; } if (offset == dirsize) { if (!inode || strcmp ("..", name)) { get_current_name (); printf (_("%s: bad directory: '..' isn't second\n"), current_name); errors_uncorrected = 1; } else return; } if (!inode) return; name_depth++; if (list) { if (verbose) printf ("%6d %07o %3d ", ino, inode->i_mode, inode->i_nlinks); get_current_name (); printf("%s", current_name); if (S_ISDIR (inode->i_mode)) printf (":\n"); else printf ("\n"); } check_zones2 (ino); if (inode && S_ISDIR (inode->i_mode)) recursive_check2 (ino); name_depth--; return;}static voidrecursive_check(unsigned int ino) { struct minix_inode * dir; unsigned int offset; dir = Inode + ino; if (!S_ISDIR(dir->i_mode)) die(_("internal error")); if (dir->i_size < 2 * dirsize) { get_current_name(); printf(_("%s: bad directory: size < 32"), current_name); errors_uncorrected = 1; } for (offset = 0 ; offset < dir->i_size ; offset += dirsize) check_file(dir,offset);}static voidrecursive_check2 (unsigned int ino) { struct minix2_inode *dir; unsigned int offset; dir = Inode2 + ino; if (!S_ISDIR (dir->i_mode)) die ("internal error"); if (dir->i_size < 2 * dirsize) { get_current_name (); printf (_("%s: bad directory: size < 32"), current_name); errors_uncorrected = 1; } for (offset = 0; offset < dir->i_size; offset += dirsize) check_file2 (dir, offset);}static intbad_zone(int i) { char buffer[1024]; if (BLOCK_SIZE*i != lseek(IN, BLOCK_SIZE*i, SEEK_SET)) die(_("seek failed in bad_zone")); return (BLOCK_SIZE != read(IN, buffer, BLOCK_SIZE));}static voidcheck_counts(void) { int i; for (i=1 ; i <= INODES ; i++) { if (!inode_in_use(i) && Inode[i].i_mode && warn_mode) { printf(_("Inode %d mode not cleared."),i); if (ask(_("Clear"),1)) { Inode[i].i_mode = 0; changed = 1; } } if (!inode_count[i]) { if (!inode_in_use(i)) continue; printf(_("Inode %d not used, marked used in the bitmap."),i); if (ask(_("Clear"),1)) unmark_inode(i); continue; } if (!inode_in_use(i)) { printf(_("Inode %d used, marked unused in the bitmap."), i); if (ask("Set",1)) mark_inode(i); } if (Inode[i].i_nlinks != inode_count[i]) { printf(_("Inode %d (mode = %07o), i_nlinks=%d, counted=%d."), i,Inode[i].i_mode,Inode[i].i_nlinks,inode_count[i]); if (ask(_("Set i_nlinks to count"),1)) { Inode[i].i_nlinks=inode_count[i]; changed=1; } } } for (i=FIRSTZONE ; i < ZONES ; i++) { if (zone_in_use(i) == zone_count[i]) continue; if (!zone_count[i]) { if (bad_zone(i)) continue; printf(_("Zone %d: marked in use, no file uses it."),i); if (ask(_("Unmark"),1)) unmark_zone(i); continue; } if (zone_in_use(i)) printf(_("Zone %d: in use, counted=%d\n"), i, zone_count[i]); else printf(_("Zone %d: not in use, counted=%d\n"), i, zone_count[i]); }}static voidcheck_counts2 (void) { int i; for (i = 1; i <= INODES; i++) { if (!inode_in_use (i) && Inode2[i].i_mode && warn_mode) { printf (_("Inode %d mode not cleared."), i); if (ask (_("Clear"), 1)) { Inode2[i].i_mode = 0; changed = 1; } } if (!inode_count[i]) { if (!inode_in_use (i)) continue; printf (_("Inode %d not used, marked used in the bitmap."), i); if (ask (_("Clear"), 1)) unmark_inode (i); continue; } if (!inode_in_use (i)) { printf (_("Inode %d used, marked unused in the bitmap."), i); if (ask (_("Set"), 1)) mark_inode (i); } if (Inode2[i].i_nlinks != inode_count[i]) { printf (_("Inode %d (mode = %07o), i_nlinks=%d, counted=%d."), i, Inode2[i].i_mode, Inode2[i].i_nlinks, inode_count[i]); if (ask (_("Set i_nlinks to count"), 1)) { Inode2[i].i_nlinks = inode_count[i]; changed = 1; } } } for (i = FIRSTZONE; i < ZONES; i++) { if (zone_in_use (i) == zone_count[i]) continue; if (!zone_count[i]) { if (bad_zone (i)) continue; printf (_("Zone %d: marked in use, no file uses it."), i); if (ask (_("Unmark"), 1)) unmark_zone (i); continue; } if (zone_in_use (i)) printf (_("Zone %d: in use, counted=%d\n"), i, zone_count[i]); else printf (_("Zone %d: not in use, counted=%d\n"), i, zone_count[i]); }}static voidcheck(void) { memset(inode_count,0,(INODES + 1) * sizeof(*inode_count)); memset(zone_count,0,ZONES*sizeof(*zone_count)); check_zones(ROOT_INO); recursive_check(ROOT_INO); check_counts();}static voidcheck2 (void) { memset (inode_count, 0, (INODES + 1) * sizeof (*inode_count)); memset (zone_count, 0, ZONES * sizeof (*zone_count)); check_zones2 (ROOT_INO); recursive_check2 (ROOT_INO); check_counts2 ();}intmain(int argc, char ** argv) { struct termios tmp; int count; int retcode = 0; char *p; program_name = (argc && *argv) ? argv[0] : "fsck.minix"; if ((p = strrchr(program_name, '/')) != NULL) program_name = p+1; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); if (argc == 2 && (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) { printf(_("%s from %s\n"), program_name, util_linux_version); exit(0); } if (INODE_SIZE * MINIX_INODES_PER_BLOCK != BLOCK_SIZE) die(_("bad inode size")); if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE) die(_("bad v2 inode size")); while (argc-- > 1) { argv++; if (argv[0][0] != '-') { if (device_name) usage(); else device_name = argv[0]; } else while (*++argv[0]) switch (argv[0][0]) { case 'l': list=1; break; case 'a': automatic=1; repair=1; break; case 'r': automatic=0; repair=1; break; case 'v': verbose=1; break; case 's': show=1; break; case 'm': warn_mode=1; break; case 'f': force=1; break; default: usage(); } } if (!device_name) usage(); check_mount(); /* trying to check a mounted filesystem? */ if (repair && !automatic) { if (!isatty(0) || !isatty(1)) die(_("need terminal for interactive repairs")); } IN = open(device_name,repair?O_RDWR:O_RDONLY); if (IN < 0) die(_("unable to open '%s'")); for (count=0 ; count<3 ; count++) sync(); read_superblock(); /* * Determine whether or not we should continue with the checking. * This is based on the status of the filesystem valid and error * flags and whether or not the -f switch was specified on the * command line. */ if ( !(Super.s_state & MINIX_ERROR_FS) && (Super.s_state & MINIX_VALID_FS) && !force ) { if (repair) printf(_("%s is clean, no check.\n"), device_name); return retcode; } else if (force) printf(_("Forcing filesystem check on %s.\n"), device_name); else if (repair) printf(_("Filesystem on %s is dirty, needs checking.\n"),\ device_name); read_tables(); if (repair && !automatic) { tcgetattr(0,&termios); tmp = termios; tmp.c_lflag &= ~(ICANON|ECHO); tcsetattr(0,TCSANOW,&tmp); termios_set = 1; } if (version2) { check_root2 (); check2 (); } else { check_root(); check(); } if (verbose) { int i, free; for (i=1,free=0 ; i <= INODES ; i++) if (!inode_in_use(i)) free++; printf(_("\n%6ld inodes used (%ld%%)\n"),(INODES-free), 100*(INODES-free)/INODES); for (i=FIRSTZONE,free=0 ; i < ZONES ; i++) if (!zone_in_use(i)) free++; printf(_("%6ld zones used (%ld%%)\n"),(ZONES-free), 100*(ZONES-free)/ZONES); printf(_("\n%6d regular files\n" "%6d directories\n" "%6d character device files\n" "%6d block device files\n" "%6d links\n" "%6d symbolic links\n" "------\n" "%6d files\n"), regular,directory,chardev,blockdev, links-2*directory+1,symlinks,total-2*directory+1); } if (changed) { write_tables(); printf(_( "----------------------------\n" "FILE SYSTEM HAS BEEN CHANGED\n" "----------------------------\n")); for (count=0 ; count<3 ; count++) sync(); } else if ( repair ) write_super_block(); if (repair && !automatic) tcsetattr(0,TCSANOW,&termios); if (changed) retcode += 3; if (errors_uncorrected) retcode += 4; return retcode;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -