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

📄 fsck1.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Hacks for version 1.6 */					#define INODES_PER_BLOCK V1_INODES_PER_BLOCK#define INODE_SIZE V1_INODE_SIZE#define WORDS_PER_BLOCK (BLOCK_SIZE / (int) sizeof(bitchunk_t))#define MAX_ZONES (V1_NR_DZONES+V1_INDIRECTS+(long)V1_INDIRECTS*V1_INDIRECTS)#define NR_DZONE_NUM V1_NR_DZONES#define NR_INDIRECTS V1_INDIRECTS#define NR_ZONE_NUMS V1_NR_TZONES#define ZONE_NUM_SIZE V1_ZONE_NUM_SIZE#define bit_nr u16_t	/* perhaps bit_t should be used, although slower */#define Bit_nr U16_t#define block_nr block_t#define d_inode d1_inode#define d_inum d_ino#define dir_struct struct direct#define i_mode d1_mode#define i_nlinks d1_nlinks#define i_size d1_size#define i_zone d1_zone#define zone_nr zone1_t#define Zone_nr Zone1_t/* fsck - file system checker		Author: Robbert van Renesse *//* Modified by Norbert Schlenker*   Removed vestiges of standalone/DOS versions:*     - various unused variables and buffers removed*     - now uses library functions rather than private internal routines*     - bytewise structure copies replaced by structure assignment*     - fixed one bug with 14 character file names*     - other small tweaks for speed** Modified by Lars Fredriksen at the request of Andy Tanenbaum, 90-03-10.*   Removed -m option, by which fsck could be told to make a file*   system on a 360K floppy.  The code had limited utility, was buggy,*   and failed due to a bug in the ACK C compiler.  Use mkfs instead!*/#include <sys/types.h>#include <sys/dir.h>#include <ctype.h>#include <errno.h>#include <fcntl.h>#include <limits.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <minix/config.h>#include <minix/const.h>#include <minix/type.h>#include "../../fs/const.h"#include "../../fs/inode.h"#include "../../fs/type.h"#include <minix/fslib.h>#undef printf			/* defined as printk in "../fs/const.h" */#include <stdio.h>#define BITSHIFT	  4	/* = log2(#bits(int)) */#define MAXPRINT	  8	/* max. number of error lines in chkmap */#define MAXDIRSIZE     5000	/* max. size of a reasonable directory */#define CINDIR		128	/* number of indirect zno's read at a time */#define CDIRECT		 16	/* number of dir entries read at a time */#define BITMASK		((1 << BITSHIFT) - 1)#define setbit(w, b)	(w[(b) >> BITSHIFT] |= 1 << ((b) & BITMASK))#define clrbit(w, b)	(w[(b) >> BITSHIFT] &= ~(1 << ((b) & BITMASK)))#define bitset(w, b)	(w[(b) >> BITSHIFT] & (1 << ((b) & BITMASK)))#define ZONE_CT 	360	/* default zones  (when making file system) */#define INODE_CT	 95	/* default inodes (when making file system) */#include "../../fs/super.h"struct super_block sb;#define STICKY_BIT	01000	/* not defined anywhere else *//* Ztob gives the block address of a zone * btoa gives the byte address of a block */#define ztob(z)		((block_nr) (z) << sb.s_log_zone_size)#define btoa(b)		((long) (b) * BLOCK_SIZE)#define SCALE		((int) ztob(1))	/* # blocks in a zone */#define FIRST		((zone_nr) sb.s_firstdatazone)	/* as the name says *//* # blocks of each type */#define N_SUPER		1#define N_IMAP		(sb.s_imap_blocks)#define N_ZMAP		(sb.s_zmap_blocks)#define N_ILIST		((sb.s_ninodes+INODES_PER_BLOCK-1) / INODES_PER_BLOCK)#define N_DATA		(sb.s_nzones - FIRST)/* Block address of each type */#define BLK_SUPER	(SUPER_BLOCK)#define BLK_IMAP	(BLK_SUPER + N_SUPER)#define BLK_ZMAP	(BLK_IMAP  + N_IMAP)#define BLK_ILIST	(BLK_ZMAP  + N_ZMAP)#define BLK_FIRST	ztob(FIRST)#define ZONE_SIZE	((int) ztob(BLOCK_SIZE))#define NLEVEL		(NR_ZONE_NUMS - NR_DZONE_NUM + 1)/* Byte address of a zone/of an inode */#define zaddr(z)	btoa(ztob(z))#define inoaddr(i)	((long) (i - 1) * INODE_SIZE + btoa(BLK_ILIST))#define INDCHUNK	(CINDIR * ZONE_NUM_SIZE)#define DIRCHUNK	(CDIRECT * DIR_ENTRY_SIZE)char *prog, *device;		/* program name (fsck), device name */int firstcnterr;		/* is this the first inode ref cnt error? */bitchunk_t *imap, *spec_imap;	/* inode bit maps */bitchunk_t *zmap, *spec_zmap;	/* zone bit maps */bitchunk_t *dirmap;		/* directory (inode) bit map */char rwbuf[BLOCK_SIZE];		/* one block buffer cache */block_nr thisblk;		/* block in buffer cache */char nullbuf[BLOCK_SIZE];	/* null buffer */nlink_t *count;			/* inode count */int changed;			/* has the diskette been written to? */struct stack {  dir_struct *st_dir;  struct stack *st_next;  char st_presence;} *ftop;int dev;			/* file descriptor of the device */#define DOT	1#define DOTDOT	2/* Counters for each type of inode/zone. */int nfreeinode, nregular, ndirectory, nblkspec, ncharspec, nbadinode;int npipe, nsyml, nfreezone, ztype[NLEVEL];int repair, automatic, listing, listsuper;	/* flags */int firstlist;			/* has the listing header been printed? */unsigned part_offset;		/* sector offset for this partition */char answer[] = "Answer questions with y or n.  Then hit RETURN";_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(void initvars, (void));_PROTOTYPE(void fatal, (char *s));_PROTOTYPE(int eoln, (int c));_PROTOTYPE(int yes, (char *question));_PROTOTYPE(int atoo, (char *s));_PROTOTYPE(int input, (char *buf, int size));_PROTOTYPE(char *alloc, (unsigned nelem, unsigned elsize));_PROTOTYPE(void printname, (char *s));_PROTOTYPE(void printrec, (struct stack *sp));_PROTOTYPE(void printpath, (int mode, int nlcr));_PROTOTYPE(void devopen, (void));_PROTOTYPE(void devclose, (void));_PROTOTYPE(void devio, (block_nr bno, int dir));_PROTOTYPE(void devread, (long offset, char *buf, int size));_PROTOTYPE(void devwrite, (long offset, char *buf, int size));_PROTOTYPE(void pr, (char *fmt, int cnt, char *s, char *p));_PROTOTYPE(bit_nr getnumber, (char *s));_PROTOTYPE(char **getlist, (char ***argv, char *type));_PROTOTYPE(void lsuper, (void));_PROTOTYPE(void getsuper, (void));_PROTOTYPE(void chksuper, (void));_PROTOTYPE(void lsi, (char **clist));_PROTOTYPE(bitchunk_t *allocbitmap, (int nblk));_PROTOTYPE(void loadbitmap, (bitchunk_t *bitmap, block_nr bno, int nblk));_PROTOTYPE(void dumpbitmap, (bitchunk_t *bitmap, block_nr bno, int nblk));_PROTOTYPE(void fillbitmap, (bitchunk_t *bitmap, Bit_nr lwb, Bit_nr upb, char **list));_PROTOTYPE(void freebitmap, (bitchunk_t *p));_PROTOTYPE(void getbitmaps, (void));_PROTOTYPE(void putbitmaps, (void));_PROTOTYPE(void chkword, (unsigned w1, unsigned w2, Bit_nr bit, char *type, int *n, int *report));_PROTOTYPE(void chkmap, (bitchunk_t *cmap, bitchunk_t *dmap, Bit_nr bit, block_nr blkno, int nblk, char *type));_PROTOTYPE(void chkilist, (void));_PROTOTYPE(void getcount, (void));_PROTOTYPE(void counterror, (Ino_t ino));_PROTOTYPE(void chkcount, (void));_PROTOTYPE(void freecount, (void));_PROTOTYPE(void printperm, (Mode_t mode, int shift, int special, int overlay));_PROTOTYPE(void list, (Ino_t ino, d_inode *ip));_PROTOTYPE(int Remove, (dir_struct *dp));_PROTOTYPE(void make_printable_name, (char *dst, char *src, int n));_PROTOTYPE(int chkdots, (Ino_t ino, off_t pos, dir_struct *dp, Ino_t exp));_PROTOTYPE(int chkname, (Ino_t ino, dir_struct *dp));_PROTOTYPE(int chkentry, (Ino_t ino, off_t pos, dir_struct *dp));_PROTOTYPE(int chkdirzone, (Ino_t ino, d_inode *ip, off_t pos, Zone_nr zno));_PROTOTYPE(void errzone, (char *mess, Zone_nr zno, int level, off_t pos));_PROTOTYPE(int markzone, (Ino_t ino, Zone_nr zno, int level, off_t pos));_PROTOTYPE(int chkindzone, (Ino_t ino, d_inode *ip, off_t *pos, Zone_nr zno, int level));_PROTOTYPE(off_t jump, (int level));_PROTOTYPE(int zonechk, (Ino_t ino, d_inode *ip, off_t *pos, Zone_nr zno, int level));_PROTOTYPE(int chkzones, (Ino_t ino, d_inode *ip, off_t *pos, zone_nr *zlist, int len, int level));_PROTOTYPE(int chkfile, (Ino_t ino, d_inode *ip));_PROTOTYPE(int chkdirectory, (Ino_t ino, d_inode *ip));_PROTOTYPE(int chklink, (Ino_t ino, d_inode *ip));_PROTOTYPE(int chkmode, (Ino_t ino, d_inode *ip));_PROTOTYPE(int chkinode, (Ino_t ino, d_inode *ip));_PROTOTYPE(int chkspecial, (Ino_t ino, d_inode *ip) );_PROTOTYPE(int descendtree, (dir_struct *dp));_PROTOTYPE(void chktree, (void));_PROTOTYPE(void printtotal, (void));_PROTOTYPE(void chkdev, (char *f, char **clist, char **ilist, char **zlist));/* Initialize the variables used by this program. */void initvars(){  register level;  nregular = ndirectory = nblkspec = ncharspec = nbadinode = npipe = nsyml = 0;  for (level = 0; level < NLEVEL; level++) ztype[level] = 0;  changed = 0;  thisblk = NO_BLOCK;  firstlist = 1;  firstcnterr = 1;}/* Print the string `s' and exit. */void fatal(s)char *s;{  printf("%s\nfatal\n", s);  exit(-1);}/* Test for end of line. */int eoln(c)int c;{  return(c == EOF || c == '\n' || c == '\r');}/* Ask a question and get the answer unless automatic is set. */int yes(question)char *question;{  register c, answer;  if (!repair) {	printf("\n");	return(0);  }  printf("%s? ", question);  if (automatic) {	printf("yes\n");	return(1);  }  fflush(stdout);  if ((c = answer = getchar()) == 'q' || c == 'Q') exit(1);  while (!eoln(c)) c = getchar();  return !(answer == 'n' || answer == 'N');}/* Convert string to integer.  Representation is octal. */int atoo(s)register char *s;{  register int n = 0;  while ('0' <= *s && *s < '8') {	n <<= 3;	n += *s++ - '0';  }  return n;}/* If repairing the file system, print a prompt and get a string from user. */int input(buf, size)char *buf;int size;{  register char *p = buf;  printf("\n");  if (repair) {	printf("--> ");	fflush(stdout);	while (--size) {		*p = getchar();		if (eoln(*p)) {			*p = 0;			return(p > buf);		}		p++;	}	*p = 0;	while (!eoln(getchar()));	return(1);  }  return(0);}/* Allocate some memory and zero it. */char *alloc(nelem, elsize)unsigned nelem, elsize;{  char *p;  if ((p = (char *) malloc((size_t)nelem * elsize)) == 0) fatal("out of memory");  memset(p, 0, (size_t)nelem * elsize);  return(p);}/* Print the name in a directory entry. */void printname(s)char *s;{  register n = NAME_MAX;  int c;  do {	if ((c = *s) == 0) break;	if (!isprint(c)) c = '?';	putchar(c);	s++;  } while (--n);}/* Print the pathname given by a linked list pointed to by `sp'.  The * names are in reverse order. */void printrec(sp)struct stack *sp;{  if (sp->st_next != 0) {	printrec(sp->st_next);	putchar('/');	printname(sp->st_dir->d_name);  }}/* Print the current pathname.  */void printpath(mode, nlcr)int mode;int nlcr;{  if (ftop->st_next == 0)	putchar('/');  else	printrec(ftop);  switch (mode) {      case 1:	printf(" (ino = %u, ", ftop->st_dir->d_inum);	break;      case 2:	printf(" (ino = %u)", ftop->st_dir->d_inum);	break;  }  if (nlcr) printf("\n");}/* Open the device.  */void devopen(){  if ((dev = open(device, repair ? O_RDWR : O_RDONLY)) < 0) {	perror(device);	fatal("");  }}/* Close the device. */void devclose(){  if (close(dev) != 0) {	perror("close");	fatal("");  }}/* Read or write a block. */void devio(bno, dir)block_nr bno;int dir;{  if (dir == READING && bno == thisblk) return;  thisblk = bno;  lseek(dev, (off_t) btoa(bno), SEEK_SET);  if (dir == READING) {	if (read(dev, rwbuf, BLOCK_SIZE) == BLOCK_SIZE)		return;  } else {	if (write(dev, rwbuf, BLOCK_SIZE) == BLOCK_SIZE)		return;  }  printf("%s: can't %s block %ld (error = 0x%x)\n", prog,         dir == READING ? "read" : "write", (long) bno, errno);  if (dir == READING) {	printf("Continuing with a zero-filled block.\n");	memset(rwbuf, 0, BLOCK_SIZE);	return;  }  fatal("");}/* Read `size' bytes from the disk starting at byte `offset'. */void devread(offset, buf, size)long offset;char *buf;int size;{  devio((block_nr) (offset / BLOCK_SIZE), READING);  memmove(buf, &rwbuf[(int) (offset % BLOCK_SIZE)], (size_t)size);}/* Write `size' bytes to the disk starting at byte `offset'. */void devwrite(offset, buf, size)long offset;char *buf;int size;{  if (!repair) fatal("internal error (devwrite)");  if (size != BLOCK_SIZE) devio((block_nr) (offset / BLOCK_SIZE), READING);  memmove(&rwbuf[(int) (offset % BLOCK_SIZE)], buf, (size_t)size);  devio((block_nr) (offset / BLOCK_SIZE), WRITING);  changed = 1;}/* Print a string with either a singular or a plural pronoun. */void pr(fmt, cnt, s, p)char *fmt, *s, *p;int cnt;{  printf(fmt, cnt, cnt == 1 ? s : p);}/* Convert string to number. */bit_nr getnumber(s)register char *s;{  register bit_nr n = 0;  if (s == NULL)	return NO_BIT;  while (isdigit(*s))	n = (n << 1) + (n << 3) + *s++ - '0';  return (*s == '\0') ? n : NO_BIT;}/* See if the list pointed to by `argv' contains numbers. */char **getlist(argv, type)char ***argv, *type;{  register char **list = *argv;  register empty = 1;  while (getnumber(**argv) != NO_BIT) {	(*argv)++;	empty = 0;  }  if (empty) {	printf("warning: no %s numbers given\n", type);	return(NULL);  }  return(list);}/* Make a listing of the super block.  If `repair' is set, ask the user * for changes. */void lsuper(){  char buf[80];  do {	printf("ninodes       = %u", sb.s_ninodes);	if (input(buf, 80)) sb.s_ninodes = atol(buf);	printf("nzones        = %u", sb.s_nzones);	if (input(buf, 80)) sb.s_nzones = atol(buf);	printf("imap_blocks   = %u", sb.s_imap_blocks);	if (input(buf, 80)) sb.s_imap_blocks = atol(buf);	printf("zmap_blocks   = %u", sb.s_zmap_blocks);	if (input(buf, 80)) sb.s_zmap_blocks = atol(buf);	printf("firstdatazone = %u", sb.s_firstdatazone);	if (input(buf, 80)) sb.s_firstdatazone = atol(buf);	printf("log_zone_size = %u", sb.s_log_zone_size);	if (input(buf, 80)) sb.s_log_zone_size = atol(buf);	printf("maxsize       = %lu", sb.s_max_size);	if (input(buf, 80)) sb.s_max_size = atol(buf);	if (yes("ok now")) {		devwrite(btoa(BLK_SUPER), (char *) &sb, sizeof(sb));		return;	}  } while (yes("Do you want to try again"));  if (repair) exit(0);}/* Get the super block from either disk or user.  Do some initial checks. */void getsuper(){  devread(btoa(BLK_SUPER), (char *) &sb, sizeof(sb));  if (listsuper) lsuper();  if (sb.s_magic == SUPER_V2) fatal("Cannot handle V2 file systems");  if (sb.s_magic != SUPER_MAGIC) fatal("bad magic number in super block");  if ((short) sb.s_ninodes <= 0) fatal("no inodes");  if (sb.s_nzones <= 2) fatal("no zones");  if ((short) sb.s_imap_blocks <= 0) fatal("no imap");  if ((short) sb.s_zmap_blocks <= 0) fatal("no zmap");

⌨️ 快捷键说明

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