📄 mkfs.c
字号:
long file_time(f)int f;{#ifdef UNIX struct stat statbuf; fstat(f, &statbuf); return(statbuf.st_mtime);#else /* fstat not supported by DOS */ return(0L);#endif}void pexit(s)char *s;{ fprintf(stderr, "%s: %s\n", progname, s); if (lct != 0) fprintf(stderr, "Line %d being processed when error detected.\n", lct); flush(); exit(2);}void copy(from, to, count)char *from, *to;int count;{ while (count--) *to++ = *from++;}void print_fs(){ int i, j; ino_t k; d1_inode inode1[V1_INODES_PER_BLOCK]; d2_inode inode2[V2_INODES_PER_BLOCK]; unsigned short usbuf[BLOCK_SIZE / sizeof(unsigned short)]; block_t b, inode_limit; struct direct dir[NR_DIR_ENTRIES]; get_block((block_t) 1, (char *) usbuf); printf("\nSuperblock: "); for (i = 0; i < 8; i++) printf("%06o ", usbuf[i]); get_block((block_t) 2, (char *) usbuf); printf("...\nInode map: "); for (i = 0; i < 9; i++) printf("%06o ", usbuf[i]); get_block((block_t) 3, (char *) usbuf); printf("...\nZone map: "); for (i = 0; i < 9; i++) printf("%06o ", usbuf[i]); printf("...\n"); k = 0; for (b = inode_offset; k < nrinodes; b++) { if (fs_version == 1) { get_block(b, (char *) inode1); } else { get_block(b, (char *) inode2); } for (i = 0; i < inodes_per_block; i++) { k = inodes_per_block * (int) (b - inode_offset) + i + 1; /* Lint but OK */ if (k > nrinodes) break; if (fs_version == 1) { if (inode1[i].d1_mode != 0) { printf("Inode %2d: mode=", k); printf("%06o", inode1[i].d1_mode); printf(" uid=%2d gid=%2d size=", inode1[i].d1_uid, inode1[i].d1_gid); printf("%6ld", inode1[i].d1_size); printf(" zone[0]=%d\n", inode1[i].d1_zone[0]); } if ((inode1[i].d1_mode & I_TYPE) == I_DIRECTORY) { /* This is a directory */ get_block(inode1[i].d1_zone[0], (char *) dir); for (j = 0; j < NR_DIR_ENTRIES; j++) if (dir[j].d_ino) printf("\tInode %2d: %s\n", dir[j].d_ino, dir[j].d_name); } } else { if (inode2[i].d2_mode != 0) { printf("Inode %2d: mode=", k); printf("%06o", inode2[i].d2_mode); printf(" uid=%2d gid=%2d size=", inode2[i].d2_uid, inode2[i].d2_gid); printf("%6ld", inode2[i].d2_size); printf(" zone[0]=%ld\n", inode2[i].d2_zone[0]); } if ((inode2[i].d2_mode & I_TYPE) == I_DIRECTORY) { /* This is a directory */ get_block(inode2[i].d2_zone[0], (char *) dir); for (j = 0; j < NR_DIR_ENTRIES; j++) if (dir[j].d_ino) printf("\tInode %2d: %s\n", dir[j].d_ino, dir[j].d_name); } } } } printf("%d inodes used. %d zones used.\n", next_inode - 1, next_zone);}int read_and_set(n)block_t n;{/* The first time a block is read, it returns all 0s, unless there has * been a write. This routine checks to see if a block has been accessed. */ int w, s, mask, r; if (sizeof(char *) == 2 && n >= MAX_INIT) pexit("can't initialize past 128M"); w = n / 8; s = n % 8; mask = 1 << s; r = (umap[w] & mask ? 1 : 0); umap[w] |= mask; return(r);}void usage(){ fprintf(stderr, "Usage: %s [-1dlot] [-b blocks] [-i inodes] special [proto]\n", progname); exit(1);}/*================================================================ * get_block & put_block for MS-DOS *===============================================================*/#ifdef DOS/* * These are the get_block and put_block routines * when compiling & running mkfs.c under MS-DOS. * * It requires the (asembler) routines absread & abswrite * from the file diskio.asm. Since these routines just do * as they are told (read & write the sector specified), * a local cache is used to minimize the i/o-overhead for * frequently used blocks. * * The global variable "file" determines whether the output * is to a disk-device or to a binary file. */#define PH_SECTSIZE 512 /* size of a physical disk-sector */char *derrtab[14] = { "no error", "disk is read-only", "unknown unit", "device not ready", "bad command", "data error", "internal error: bad request structure length", "seek error", "unknown media type", "sector not found", "printer out of paper (?)", "write fault", "read error", "general error"};#define CACHE_SIZE 20 /* 20 block-buffers */struct cache { char blockbuf[BLOCK_SIZE]; block_t blocknum; int dirty; int usecnt;} cache[CACHE_SIZE];void special(string)char *string;{ if (string[1] == ':' && string[2] == 0) { /* Format: d: or d:fname */ disk = (string[0] & ~32) - 'A'; if (disk > 1 && !override) /* safety precaution */ pexit("Bad drive specifier for special"); } else { file = 1; if ((fd = creat(string, BWRITE)) == 0) pexit("Can't open special file"); }}void get_block(n, buf)block_t n;char buf[BLOCK_SIZE];{ /* Get a block to the user */ struct cache *bp, *fp; /* First access returns a zero block */ if (read_and_set(n) == 0) { copy(zero, buf, BLOCK_SIZE); return; } /* Look for block in cache */ fp = 0; for (bp = cache; bp < &cache[CACHE_SIZE]; bp++) { if (bp->blocknum == n) { copy(bp, buf, BLOCK_SIZE); bp->usecnt++; return; } /* Remember clean block */ if (bp->dirty == 0) if (fp) { if (fp->usecnt > bp->usecnt) fp = bp; } else fp = bp; } /* Block not in cache, get it */ if (!fp) { /* No clean buf, flush one */ for (bp = cache, fp = cache; bp < &cache[CACHE_SIZE]; bp++) if (fp->usecnt > bp->usecnt) fp = bp; mx_write(fp->blocknum, fp); } mx_read(n, fp); fp->dirty = 0; fp->usecnt = 0; fp->blocknum = n; copy(fp, buf, BLOCK_SIZE);}void put_block(n, buf)block_t n;char buf[BLOCK_SIZE];{ /* Accept block from user */ struct cache *fp, *bp; (void) read_and_set(n); /* Look for block in cache */ fp = 0; for (bp = cache; bp < &cache[CACHE_SIZE]; bp++) { if (bp->blocknum == n) { copy(buf, bp, BLOCK_SIZE); bp->dirty = 1; return; } /* Remember clean block */ if (bp->dirty == 0) if (fp) { if (fp->usecnt > bp->usecnt) fp = bp; } else fp = bp; } /* Block not in cache */ if (!fp) { /* No clean buf, flush one */ for (bp = cache, fp = cache; bp < &cache[CACHE_SIZE]; bp++) if (fp->usecnt > bp->usecnt) fp = bp; mx_write(fp->blocknum, fp); } fp->dirty = 1; fp->usecnt = 1; fp->blocknum = n; copy(buf, fp, BLOCK_SIZE);}void cache_init(){ struct cache *bp; for (bp = cache; bp < &cache[CACHE_SIZE]; bp++) bp->blocknum = -1;}void flush(){ /* Flush all dirty blocks to disk */ struct cache *bp; for (bp = cache; bp < &cache[CACHE_SIZE]; bp++) if (bp->dirty) { mx_write(bp->blocknum, bp); bp->dirty = 0; }}/*================================================================== * hard read & write etc. *=================================================================*/#define MAX_RETRIES 5void mx_read(blocknr, buf)int blocknr;char buf[BLOCK_SIZE];{ /* Read the requested MINIX-block in core */ char (*bp)[PH_SECTSIZE]; int sectnum, retries, err; if (file) { lseek(fd, (off_t) blocknr * BLOCK_SIZE, 0); if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) pexit("mx_read: error reading file"); } else { sectnum = blocknr * (BLOCK_SIZE / PH_SECTSIZE); for (bp = buf; bp < &buf[BLOCK_SIZE]; bp++) { retries = MAX_RETRIES; do err = absread(disk, sectnum, bp); while (err && --retries); if (retries) { sectnum++; } else { dexit("mx_read", sectnum, err); } } }}void mx_write(blocknr, buf)int blocknr;char buf[BLOCK_SIZE];{ /* Write the MINIX-block to disk */ char (*bp)[PH_SECTSIZE]; int retries, sectnum, err; if (file) { lseek(fd, blocknr * BLOCK_SIZE, 0); if (write(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) { pexit("mx_write: error writing file"); } } else { sectnum = blocknr * (BLOCK_SIZE / PH_SECTSIZE); for (bp = buf; bp < &buf[BLOCK_SIZE]; bp++) { retries = MAX_RETRIES; do { err = abswrite(disk, sectnum, bp); } while (err && --retries); if (retries) { sectnum++; } else { dexit("mx_write", sectnum, err); } } }}void dexit(s, sectnum, err)int sectnum, err;char *s;{ printf("Error: %s, sector: %d, code: %d, meaning: %s\n", s, sectnum, err, derrtab[err]); exit(2);}#endif/*================================================================ * get_block & put_block for UNIX *===============================================================*/#ifdef UNIXvoid special(string)char *string;{ fd = creat(string, 0777); close(fd); fd = open(string, O_RDWR); if (fd < 0) pexit("Can't open special file");#if (MACHINE == ATARI) { struct stat statbuf; if (fstat(fd, &statbuf) < 0) return; isdev = (statbuf.st_mode & S_IFMT) == S_IFCHR || (statbuf.st_mode & S_IFMT) == S_IFBLK ; }#endif}void get_block(n, buf)block_t n;char buf[BLOCK_SIZE];{/* Read a block. */ int k; /* First access returns a zero block */ if (read_and_set(n) == 0) { copy(zero, buf, BLOCK_SIZE); return; } lseek(fd, (off_t) n * BLOCK_SIZE, SEEK_SET); k = read(fd, buf, BLOCK_SIZE); if (k != BLOCK_SIZE) { pexit("get_block couldn't read"); }}void put_block(n, buf)block_t n;char buf[BLOCK_SIZE];{/* Write a block. */ (void) read_and_set(n); /* XXX - check other lseeks too. */ if (lseek(fd, (off_t) n * BLOCK_SIZE, SEEK_SET) == (off_t) -1) { pexit("put_block couldn't seek"); } if (write(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) { pexit("put_block couldn't write"); }}/* Dummy routines to keep source file clean from #ifdefs */void flush(){ return;}void cache_init(){ return;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -