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

📄 fsck1.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
  if ((short) sb.s_firstdatazone <= 1) fatal("first data zone too small");  if ((short) sb.s_log_zone_size < 0) fatal("zone size < block size");  if (sb.s_max_size <= 0) fatal("max. file size <= 0");}/* Check the super block for reasonable contents. */void chksuper(){  register n;  register off_t maxsize;  n = bitmapsize((bit_t) sb.s_ninodes + 1);  if (sb.s_magic != SUPER_MAGIC) fatal("bad magic number in super block");  if ((short) sb.s_imap_blocks < n) fatal("too few imap blocks");  if (sb.s_imap_blocks != n) {	pr("warning: expected %d imap_block%s", n, "", "s");	printf(" instead of %d\n", sb.s_imap_blocks);  }  n = bitmapsize((bit_t) sb.s_nzones);  if ((short) sb.s_zmap_blocks < n) fatal("too few zmap blocks");  if (sb.s_zmap_blocks != n) {	pr("warning: expected %d zmap_block%s", n, "", "s");	printf(" instead of %d\n", sb.s_zmap_blocks);  }  if (sb.s_firstdatazone >= sb.s_nzones)	fatal("first data zone too large");  if ((unsigned short) sb.s_log_zone_size >= 8 * sizeof(block_nr))	fatal("log_zone_size too large");  if (sb.s_log_zone_size > 8) printf("warning: large log_zone_size (%d)\n",	       sb.s_log_zone_size);  n = (BLK_ILIST + N_ILIST + SCALE - 1) >> sb.s_log_zone_size;  if ((short) sb.s_firstdatazone < n) fatal("first data zone too small");  if (sb.s_firstdatazone != n) {	printf("warning: expected first data zone to be %d ", n);	printf("instead of %u\n", sb.s_firstdatazone);  }  maxsize = MAX_FILE_POS;  if (((maxsize - 1) >> sb.s_log_zone_size) / BLOCK_SIZE >= MAX_ZONES)	maxsize = ((long) MAX_ZONES * BLOCK_SIZE) << sb.s_log_zone_size;  if (sb.s_max_size != maxsize) {	printf("warning: expected max size to be %ld ", maxsize);	printf("instead of %ld\n", sb.s_max_size);  }}/* Make a listing of the inodes given by `clist'.  If `repair' is set, ask * the user for changes. */void lsi(clist)char **clist;{  register bit_nr bit;  register ino_t ino;  d_inode inode, *ip = &inode;  char buf[80];  if (clist == 0) return;  while ((bit = getnumber(*clist++)) != NO_BIT) {	setbit(spec_imap, bit);	ino = bit;	do {		devread(inoaddr(ino), (char *) ip, INODE_SIZE);		printf("inode %u:\n", ino);		printf("    mode   = %06o", ip->i_mode);		if (input(buf, 80)) ip->i_mode = atoo(buf);		printf("    nlinks = %6u", ip->i_nlinks);		if (input(buf, 80)) ip->i_nlinks = atol(buf);		printf("    size   = %6ld", ip->i_size);		if (input(buf, 80)) ip->i_size = atol(buf);		if (yes("Write this back")) {			devwrite(inoaddr(ino), (char *) ip, INODE_SIZE);			break;		}	} while (yes("Do you want to change it again"));  }}/* Allocate `nblk' blocks worth of bitmap. */bitchunk_t *allocbitmap(nblk)int nblk;{  register bitchunk_t *bitmap;  bitmap = (bitchunk_t *) alloc(nblk, BLOCK_SIZE);  *bitmap |= 1;  return(bitmap);}/* Load the bitmap starting at block `bno' from disk. */void loadbitmap(bitmap, bno, nblk)bitchunk_t *bitmap;block_nr bno;int nblk;{  register i;  register bitchunk_t *p;  p = bitmap;  for (i = 0; i < nblk; i++, bno++, p += WORDS_PER_BLOCK)	devread(btoa(bno), (char *) p, BLOCK_SIZE);  *bitmap |= 1;}/* Write the bitmap starting at block `bno' to disk. */void dumpbitmap(bitmap, bno, nblk)bitchunk_t *bitmap;block_nr bno;int nblk;{  register i;  register bitchunk_t *p = bitmap;  for (i = 0; i < nblk; i++, bno++, p += WORDS_PER_BLOCK)	devwrite(btoa(bno), (char *) p, BLOCK_SIZE);}/* Set the bits given by `list' in the bitmap. */void fillbitmap(bitmap, lwb, upb, list)bitchunk_t *bitmap;bit_nr lwb, upb;char **list;{  register bit_nr bit;  if (list == 0) return;  while ((bit = getnumber(*list++)) != NO_BIT)	if (bit < lwb || bit >= upb) {		if (bitmap == spec_imap)			printf("inode number %u ", bit);		else			printf("zone number %u ", bit);		printf("out of range (ignored)\n");	} else		setbit(bitmap, bit - lwb + 1);}/* Deallocate the bitmap `p'. */void freebitmap(p)bitchunk_t *p;{  free((char *) p);}/* Get all the bitmaps used by this program. */void getbitmaps(){  imap = allocbitmap(N_IMAP);  zmap = allocbitmap(N_ZMAP);  spec_imap = allocbitmap(N_IMAP);  spec_zmap = allocbitmap(N_ZMAP);  dirmap = allocbitmap(N_IMAP);}/* Release all the space taken by the bitmaps. */void putbitmaps(){  freebitmap(imap);  freebitmap(zmap);  freebitmap(spec_imap);  freebitmap(spec_zmap);  freebitmap(dirmap);}/* `w1' and `w2' are differing words from two bitmaps that should be * identical.  Print what's the matter with them. */void chkword(w1, w2, bit, type, n, report)unsigned w1, w2;char *type;bit_nr bit;int *n, *report;{  for (; (w1 | w2); w1 >>= 1, w2 >>= 1, bit++)	if ((w1 ^ w2) & 1 && ++(*n) % MAXPRINT == 0 && *report &&	    (!repair || automatic || yes("stop this listing")))		*report = 0;	else if (*report)		if ((w1 & 1) && !(w2 & 1))			printf("%s %u is missing\n", type, bit);		else if (!(w1 & 1) && (w2 & 1))			printf("%s %u is not free\n", type, bit);}/* Check if the given (correct) bitmap is identical with the one that is * on the disk.  If not, ask if the disk should be repaired. */void chkmap(cmap, dmap, bit, blkno, nblk, type)bitchunk_t *cmap, *dmap;bit_nr bit;block_nr blkno;int nblk;char *type;{  register bitchunk_t *p = dmap, *q = cmap;  int report = 1, nerr = 0;  int w = nblk * WORDS_PER_BLOCK;  printf("Checking %s map\n", type);  loadbitmap(dmap, blkno, nblk);  do {	if (*p != *q) chkword(*p, *q, bit, type, &nerr, &report);	p++;	q++;	bit += 8 * sizeof(bitchunk_t);  } while (--w > 0);  if ((!repair || automatic) && !report) printf("etc. ");  if (nerr > MAXPRINT || nerr > 10) printf("%d errors found. ", nerr);  if (nerr != 0 && yes("install a new map")) dumpbitmap(cmap, blkno, nblk);  if (nerr > 0) printf("\n");}/* See if the inodes that aren't allocated are cleared. */void chkilist(){  register ino_t ino = 1;  mode_t mode;  printf("Checking inode list\n");  do	if (!bitset(imap, (bit_nr) ino)) {		devread(inoaddr(ino), (char *) &mode, sizeof(mode));		if (mode != I_NOT_ALLOC) {			printf("mode inode %u not cleared", ino);			if (yes(". clear")) devwrite(inoaddr(ino), nullbuf,					 INODE_SIZE);		}	}  while (++ino <= sb.s_ninodes);  printf("\n");}/* Allocate an array to maintain the inode reference counts in. */void getcount(){  count = (nlink_t *) alloc(sb.s_ninodes + 1, sizeof(nlink_t));}/* The reference count for inode `ino' is wrong.  Ask if it should be adjusted. */void counterror(ino)ino_t ino;{  d_inode inode;  if (firstcnterr) {	printf("INODE NLINK COUNT\n");	firstcnterr = 0;  }  devread(inoaddr(ino), (char *) &inode, INODE_SIZE);  count[ino] += inode.i_nlinks;  printf("%5u %5u %5u", ino, (unsigned) inode.i_nlinks, count[ino]);  if (yes(" adjust")) {	if ((inode.i_nlinks = count[ino]) == 0) {		fatal("internal error (counterror)");/* This would be a patch		inode.i_mode = I_NOT_ALLOC;		clrbit(imap, (bit_nr) ino);*/	}	devwrite(inoaddr(ino), (char *) &inode, INODE_SIZE);  }}/* Check if the reference count of the inodes are correct.  The array `count' * is maintained as follows:  an entry indexed by the inode number is * incremented each time a link is found; when the inode is read the link * count in there is substracted from the corresponding entry in `count'. * Thus, when the whole file system has been traversed, all the entries * should be zero. */void chkcount(){  register ino_t ino;  for (ino = 1; ino <= sb.s_ninodes; ino++)	if (count[ino] != 0) counterror(ino);  if (!firstcnterr) printf("\n");}/* Deallocate the `count' array. */void freecount(){  free((char *) count);}/* Print the inode permission bits given by mode and shift. */void printperm(mode, shift, special, overlay)mode_t mode;int shift;int special;int overlay;{  if (mode >> shift & R_BIT)	putchar('r');  else	putchar('-');  if (mode >> shift & W_BIT)	putchar('w');  else	putchar('-');  if (mode & special)	putchar(overlay);  else	if (mode >> shift & X_BIT)		putchar('x');	else		putchar('-');}/* List the given inode. */void list(ino, ip)ino_t ino;d_inode *ip;{  if (firstlist) {	firstlist = 0;	printf(" inode permission link   size name\n");  }  printf("%6u ", ino);  switch (ip->i_mode & I_TYPE) {      case I_REGULAR:		putchar('-');	break;      case I_DIRECTORY:		putchar('d');	break;      case I_CHAR_SPECIAL:	putchar('c');	break;      case I_BLOCK_SPECIAL:	putchar('b');	break;      case I_NAMED_PIPE:	putchar('p');	break;#ifdef I_SYMBOLIC_LINK      case I_SYMBOLIC_LINK:	putchar('l');	break;#endif      default:			putchar('?');}  printperm(ip->i_mode, 6, I_SET_UID_BIT, 's');  printperm(ip->i_mode, 3, I_SET_GID_BIT, 's');  printperm(ip->i_mode, 0, STICKY_BIT, 't');  printf(" %3u ", ip->i_nlinks);  switch (ip->i_mode & I_TYPE) {      case I_CHAR_SPECIAL:      case I_BLOCK_SPECIAL:	printf("  %2x,%2x ", (dev_t) ip->i_zone[0] >> MAJOR & 0xFF,	       (dev_t) ip->i_zone[0] >> MINOR & 0xFF);	break;      default:	printf("%7ld ", ip->i_size);  }  printpath(0, 1);}/* Remove an entry from a directory if ok with the user. * Don't name the function remove() - that is owned by ANSI, and chaos results * when it is a macro. */int Remove(dp)dir_struct *dp;{  setbit(spec_imap, (bit_nr) dp->d_inum);  if (yes(". remove entry")) {	count[dp->d_inum]--;	memset((void *) dp, 0, sizeof(dir_struct));	return(1);  }  return(0);}/* Convert string so that embedded control characters are printable. */void make_printable_name(dst, src, n)register char *dst;register char *src;register int n;{  register int c;  while (--n >= 0 && (c = *src++) != '\0') {	if (isprint(c) && c != '\\')		*dst++ = c;	else {		*dst++ = '\\';		switch (c) {		      case '\\':			*dst++ = '\\'; break;		      case '\b':			*dst++ = 'b'; break;		      case '\f':			*dst++ = 'f'; break;		      case '\n':			*dst++ = 'n'; break;		      case '\r':			*dst++ = 'r'; break;		      case '\t':			*dst++ = 't'; break;		      default:			*dst++ = '0' + ((c >> 6) & 03);			*dst++ = '0' + ((c >> 3) & 07);			*dst++ = '0' + (c & 07);		}	}  }  *dst = '\0';}/* See if the `.' or `..' entry is as expected. */int chkdots(ino, pos, dp, exp)ino_t ino, exp;off_t pos;dir_struct *dp;{  char printable_name[4 * NAME_MAX + 1];  if (dp->d_inum != exp) {	make_printable_name(printable_name, dp->d_name, sizeof(dp->d_name));	printf("bad %s in ", printable_name);	printpath(1, 0);	printf("%s is linked to %u ", printable_name, dp->d_inum);	printf("instead of %u)", exp);	setbit(spec_imap, (bit_nr) ino);	setbit(spec_imap, (bit_nr) dp->d_inum);	setbit(spec_imap, (bit_nr) exp);	if (yes(". repair")) {		count[dp->d_inum]--;		dp->d_inum = exp;		count[exp]++;		return(0);	}  } else if (pos != (dp->d_name[1] ? DIR_ENTRY_SIZE : 0)) {	make_printable_name(printable_name, dp->d_name, sizeof(dp->d_name));	printf("warning: %s has offset %ld in ", printable_name, pos);	printpath(1, 0);	printf("%s is linked to %u)\n", printable_name, dp->d_inum);	setbit(spec_imap, (bit_nr) ino);	setbit(spec_imap, (bit_nr) dp->d_inum);	setbit(spec_imap, (bit_nr) exp);  }  return(1);}/* Check the name in a directory entry. */int chkname(ino, dp)ino_t ino;dir_struct *dp;{  register n = NAME_MAX + 1;  register char *p = dp->d_name;  if (*p == '\0') {	printf("null name found in ");	printpath(0, 0);	setbit(spec_imap, (bit_nr) ino);	if (Remove(dp)) return(0);  }  while (*p != '\0' && --n != 0)	if (*p++ == '/') {		printf("found a '/' in entry of directory ");		printpath(1, 0);		setbit(spec_imap, (bit_nr) ino);		printf("entry = '");		printname(dp->d_name);		printf("')");		if (Remove(dp)) return(0);		break;	}  return(1);}/* Check a directory entry.  Here the routine `descendtree' is called * recursively to check the file or directory pointed to by the entry. */int chkentry(ino, pos, dp)ino_t ino;off_t pos;dir_struct *dp;{  if (dp->d_inum < ROOT_INODE || dp->d_inum > sb.s_ninodes) {	printf("bad inode found in directory ");	printpath(1, 0);	printf("ino found = %u, ", dp->d_inum);	printf("name = '");	printname(dp->d_name);	printf("')");	if (yes(". remove entry")) {		memset((void *) dp, 0, sizeof(dir_struct));		return(0);	}	return(1);  }  if ((unsigned) count[dp->d_inum] == LINK_MAX) {	printf("too many links to ino %u\n", dp->d_inum);	printf("discovered at entry '");	printname(dp->d_name);	printf("' in directory ");	printpath(0, 1);	if (Remove(dp)) return(0);  }  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;

⌨️ 快捷键说明

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