⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsck.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  count[dp->d_inum]++;  if (strcmp(dp->d_name, ".") == 0) {	ftop->st_presence |= DOT;	return(chkdots(ino, pos, dp, ino));  }  if (strcmp(dp->d_name, "..") == 0) {	ftop->st_presence |= DOTDOT;	return(chkdots(ino, pos, dp, ino == ROOT_INODE ? ino :			ftop->st_next->st_dir->d_inum));  }  if (!chkname(ino, dp)) return(0);  if (bitset(dirmap, (bit_nr) dp->d_inum)) {	printf("link to directory discovered in ");	printpath(1, 0);	printf("name = '");	printname(dp->d_name);	printf("', dir ino = %u)", dp->d_inum);	return !Remove(dp);  }  return(descendtree(dp));}/* Check a zone of a directory by checking all the entries in the zone. * The zone is split up into chunks to not allocate too much stack. */int chkdirzone(ino, ip, pos, zno)ino_t ino;d_inode *ip;off_t pos;zone_nr zno;{  dir_struct dirblk[CDIRECT];  register dir_struct *dp;  register n = SCALE * (NR_DIR_ENTRIES / CDIRECT), dirty;  register long offset = zaddr(zno);  register off_t size = 0;  do {	devread(offset, (char *) dirblk, DIRCHUNK);	dirty = 0;	for (dp = dirblk; dp < &dirblk[CDIRECT]; dp++) {		if (dp->d_inum != NO_ENTRY && !chkentry(ino, pos, dp))			dirty = 1;		pos += DIR_ENTRY_SIZE;		if (dp->d_inum != NO_ENTRY) size = pos;	}	if (dirty) devwrite(offset, (char *) dirblk, DIRCHUNK);	offset += DIRCHUNK;  } while (--n);  if (size > ip->i_size) {	printf("size not updated of directory ");	printpath(2, 0);	if (yes(". extend")) {		setbit(spec_imap, (bit_nr) ino);		ip->i_size = size;		devwrite(inoaddr(ino), (char *) ip, INODE_SIZE);	}  }  return(1);}/* There is something wrong with the given zone.  Print some details. */void errzone(mess, zno, level, pos)char *mess;zone_nr zno;int level;off_t pos;{  printf("%s zone in ", mess);  printpath(1, 0);  printf("zno = %ld, type = ", zno);  switch (level) {      case 0:	printf("DATA");	break;      case 1:	printf("SINGLE INDIRECT");	break;      case 2:	printf("DOUBLE INDIRECT");	break;      default:	printf("VERY INDIRECT");  }  printf(", pos = %ld)\n", pos);}/* Found the given zone in the given inode.  Check it, and if ok, mark it * in the zone bitmap. */int markzone(zno, level, pos)zone_nr zno;int level;off_t pos;{  register bit_nr bit = (bit_nr) zno - FIRST + 1;  ztype[level]++;  if (zno < FIRST || zno >= sb.s_zones) {	errzone("out-of-range", zno, level, pos);	return(0);  }  if (bitset(zmap, bit)) {	setbit(spec_zmap, bit);	errzone("duplicate", zno, level, pos);	return(0);  }  nfreezone--;  if (bitset(spec_zmap, bit)) errzone("found", zno, level, pos);  setbit(zmap, bit);  return(1);}/* Check an indirect zone by checking all of its entries. * The zone is split up into chunks to not allocate too much stack. */int chkindzone(ino, ip, pos, zno, level)ino_t ino;d_inode *ip;off_t *pos;zone_nr zno;int level;{  zone_nr indirect[CINDIR];  register n = NR_INDIRECTS / CINDIR;  register long offset = zaddr(zno);  do {	devread(offset, (char *) indirect, INDCHUNK);	if (!chkzones(ino, ip, pos, indirect, CINDIR, level - 1)) return(0);	offset += INDCHUNK;  } while (--n && *pos < ip->i_size);  return(1);}/* Return the size of a gap in the file, represented by a null zone number * at some level of indirection. */off_t jump(level)int level;{  off_t power = ZONE_SIZE;  if (level != 0) do		power *= NR_INDIRECTS;	while (--level);  return(power);}/* Check a zone, which may be either a normal data zone, a directory zone, * or an indirect zone. */int zonechk(ino, ip, pos, zno, level)ino_t ino;d_inode *ip;off_t *pos;zone_nr zno;int level;{  if (level == 0) {	if ((ip->i_mode & I_TYPE) == I_DIRECTORY &&	    !chkdirzone(ino, ip, *pos, zno))		return(0);	*pos += ZONE_SIZE;	return(1);  } else	return chkindzone(ino, ip, pos, zno, level);}/* Check a list of zones given by `zlist'. */int chkzones(ino, ip, pos, zlist, len, level)ino_t ino;d_inode *ip;off_t *pos;zone_nr *zlist;int len;int level;{  register ok = 1, i;  /* The check on the position in the next loop is commented out, since FS   * now requires valid zone numbers in each level that is necessary and FS   * always deleted all the zones in the double indirect block.   */  for (i = 0; i < len /* && *pos < ip->i_size */ ; i++)	if (zlist[i] == NO_ZONE)		*pos += jump(level);	else if (!markzone(zlist[i], level, *pos)) {		*pos += jump(level);		ok = 0;	} else if (!zonechk(ino, ip, pos, zlist[i], level))		ok = 0;  return(ok);}/* Check a file or a directory. */int chkfile(ino, ip)ino_t ino;d_inode *ip;{  register ok, i, level;  off_t pos = 0;  ok = chkzones(ino, ip, &pos, &ip->i_zone[0], NR_DZONE_NUM, 0);  for (i = NR_DZONE_NUM, level = 1; i < NR_ZONE_NUMS; i++, level++)	ok &= chkzones(ino, ip, &pos, &ip->i_zone[i], 1, level);  return(ok);}/* Check a directory by checking the contents.  Check if . and .. are present. */int chkdirectory(ino, ip)ino_t ino;d_inode *ip;{  register ok;  setbit(dirmap, (bit_nr) ino);  if (ip->i_size > MAXDIRSIZE) {	printf("warning: huge directory: ");	printpath(2, 1);  }  ok = chkfile(ino, ip);  if (!(ftop->st_presence & DOT)) {	printf(". missing in ");	printpath(2, 1);	ok = 0;  }  if (!(ftop->st_presence & DOTDOT)) {	printf(".. missing in ");	printpath(2, 1);	ok = 0;  }  return(ok);}#ifdef I_SYMBOLIC_LINK/* Check the validity of a symbolic link. */int chklink(ino, ip)ino_t ino;d_inode *ip;{  int ok;  ok = chkfile(ino, ip);  if (ip->i_size <= 0 || ip->i_size > BLOCK_SIZE) {	if (ip->i_size == 0)		printf("empty symbolic link ");	else		printf("symbolic link too large (size %ld) ", ip->i_size);	printpath(2, 1);	ok = 0;  }  return(ok);}#endif/* Check the validity of a special file. */int chkspecial(ino, ip)ino_t ino;d_inode *ip;{  int i, ok;  ok = 1;  if ((dev_t) ip->i_zone[0] == NO_DEV) {	printf("illegal device number %ld for special file ", ip->i_zone[0]);	printpath(2, 1);	ok = 0;  }  /* FS will not use the remaining "zone numbers" but 1.6.11++ will panic if   * they are nonzero, since this should not happen.   */  for (i = 1; i < NR_ZONE_NUMS; i++)	if (ip->i_zone[i] != NO_ZONE) {		printf("nonzero zone number %ld for special file ",		       ip->i_zone[i]);		printpath(2, 1);		ok = 0;	}  return(ok);}/* Check the mode and contents of an inode. */int chkmode(ino, ip)ino_t ino;d_inode *ip;{  switch (ip->i_mode & I_TYPE) {      case I_REGULAR:	nregular++;	return chkfile(ino, ip);      case I_DIRECTORY:	ndirectory++;	return chkdirectory(ino, ip);      case I_BLOCK_SPECIAL:	nblkspec++;	return chkspecial(ino, ip);      case I_CHAR_SPECIAL:	ncharspec++;	return chkspecial(ino, ip);      case I_NAMED_PIPE:	npipe++;	return chkfile(ino, ip);#ifdef I_SYMBOLIC_LINK      case I_SYMBOLIC_LINK:	nsyml++;	return chklink(ino, ip);#endif      default:	nbadinode++;	printf("bad mode of ");	printpath(1, 0);	printf("mode = %o)", ip->i_mode);	return(0);  }}/* Check an inode. */int chkinode(ino, ip)ino_t ino;d_inode *ip;{  if (ino == ROOT_INODE && (ip->i_mode & I_TYPE) != I_DIRECTORY) {	printf("root inode is not a directory ");	printf("(ino = %u, mode = %o)\n", ino, ip->i_mode);	fatal("");  }  if (ip->i_nlinks == 0) {	printf("link count zero of ");	printpath(2, 0);	return(0);  }  nfreeinode--;  setbit(imap, (bit_nr) ino);  if ((unsigned) ip->i_nlinks > LINK_MAX) {	printf("link count too big in ");	printpath(1, 0);	printf("cnt = %u)\n", (unsigned) ip->i_nlinks);	count[ino] -= LINK_MAX;	setbit(spec_imap, (bit_nr) ino);  } else {	count[ino] -= (unsigned) ip->i_nlinks;  }  return chkmode(ino, ip);}/* Check the directory entry pointed to by dp, by checking the inode. */int descendtree(dp)dir_struct *dp;{  d_inode inode;  register ino_t ino = dp->d_inum;  register visited;  struct stack stk;  stk.st_dir = dp;  stk.st_next = ftop;  ftop = &stk;  if (bitset(spec_imap, (bit_nr) ino)) {	printf("found inode %u: ", ino);	printpath(0, 1);  }  visited = bitset(imap, (bit_nr) ino);  if (!visited || listing) {	devread(inoaddr(ino), (char *) &inode, INODE_SIZE);	if (listing) list(ino, &inode);	if (!visited && !chkinode(ino, &inode)) {		setbit(spec_imap, (bit_nr) ino);		if (yes("remove")) {			count[ino] += inode.i_nlinks - 1;			clrbit(imap, (bit_nr) ino);			devwrite(inoaddr(ino), nullbuf, INODE_SIZE);			memset((void *) dp, 0, sizeof(dir_struct));			ftop = ftop->st_next;			return(0);		}	}  }  ftop = ftop->st_next;  return(1);}/* Check the file system tree. */void chktree(){  dir_struct dir;  nfreeinode = sb.s_ninodes;  nfreezone = N_DATA;  dir.d_inum = ROOT_INODE;  dir.d_name[0] = 0;  if (!descendtree(&dir)) fatal("bad root inode");  putchar('\n');}/* Print the totals of all the objects found. */void printtotal(){  printf("blocksize = %5d        ", BLOCK_SIZE);  printf("zonesize  = %5d\n", ZONE_SIZE);  printf("\n");  pr("%6u    Regular file%s\n", nregular, "", "s");  pr("%6u    Director%s\n", ndirectory, "y", "ies");  pr("%6u    Block special file%s\n", nblkspec, "", "s");  pr("%6u    Character special file%s\n", ncharspec, "", "s");  if (nbadinode != 0) pr("%6u    Bad inode%s\n", nbadinode, "", "s");  pr("%6u    Free inode%s\n", nfreeinode, "", "s");  pr("%6u    Named pipe%s\n", npipe, "", "s");  pr("%6u    Symbolic link%s\n", nsyml, "", "s");/* Don't print some fields.  printf("\n");  pr("%6u    Data zone%s\n",		  ztype[0],	 "",   "s");  pr("%6u    Single indirect zone%s\n",	  ztype[1],	 "",   "s");  pr("%6u    Double indirect zone%s\n",	  ztype[2],	 "",   "s");*/  lpr("%6ld    Free zone%s\n", nfreezone, "", "s");}/* Check the device which name is given by `f'.  The inodes listed by `clist' * should be listed separately, and the inodes listed by `ilist' and the zones * listed by `zlist' should be watched for while checking the file system. */void chkdev(f, clist, ilist, zlist)char *f, **clist, **ilist, **zlist;{  if (automatic) repair = 1;  device = f;  initvars();  devopen();  getsuper();  chksuper();  lsi(clist);  getbitmaps();  fillbitmap(spec_imap, (bit_nr) 1, (bit_nr) sb.s_ninodes + 1, ilist);  fillbitmap(spec_zmap, (bit_nr) FIRST, (bit_nr) sb.s_zones, zlist);  getcount();  chktree();  chkmap(zmap, spec_zmap, (bit_nr) FIRST - 1, BLK_ZMAP, N_ZMAP, "zone");  chkcount();  chkmap(imap, spec_imap, (bit_nr) 0, BLK_IMAP, N_IMAP, "inode");  chkilist();  printtotal();  putbitmaps();  freecount();  devclose();  if (changed) printf("----- FILE SYSTEM HAS BEEN MODIFIED -----\n\n");}int main(argc, argv)int argc;char **argv;{  register char **clist = 0, **ilist = 0, **zlist = 0;  register devgiven = 0;  register char *arg;  if ((1 << BITSHIFT) != 8 * sizeof(bitchunk_t)) {	printf("Fsck was compiled with the wrong BITSHIFT!\n");	exit(1);  }  sync();  prog = *argv++;  while ((arg = *argv++) != 0)	if (arg[0] == '-' && arg[1] != 0 && arg[2] == 0) switch (arg[1]) {		    case 'a':	automatic ^= 1;	break;		    case 'c':			clist = getlist(&argv, "inode");			break;		    case 'i':			ilist = getlist(&argv, "inode");			break;		    case 'z':			zlist = getlist(&argv, "zone");			break;		    case 'r':	repair ^= 1;	break;		    case 'l':	listing ^= 1;	break;		    case 's':	listsuper ^= 1;	break;		    default:			printf("%s: unknown flag '%s'\n", prog, arg);		}	else {		chkdev(arg, clist, ilist, zlist);		clist = 0;		ilist = 0;		zlist = 0;		devgiven = 1;	}  if (!devgiven) {	printf("Usage: fsck [-acilrsz] file\n");	exit(1);  }  return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -