📄 mkfs.c
字号:
if (*p == 'd') { /* This is a directory. */ z = alloc_zone(); /* zone for new directory */ add_zone(n, z, 32L, current_time); enter_dir(n, ".", n); enter_dir(n, "..", parent); incr_link(parent); incr_link(n); eat_dir(n); } else if (*p == 'b' || *p == 'c') { /* Special file. */ maj = atoi(token[4]); min = atoi(token[5]); size = 0; if (token[6]) size = atoi(token[6]); size = BLOCK_SIZE * size; add_zone(n, (zone_t) ((maj << 8) | min), size, current_time); } else { /* Regular file. Go read it. */ if ((f = open(token[4], O_RDONLY)) < 0) { fprintf(stderr, "%s: Can't open %s: %s\n", progname, token[4], strerror(errno)); } else eat_file(n, f); } }}/*================================================================ * eat_file - copy file to MINIX *===============================================================*//* Zonesize >= blocksize */void eat_file(inode, f)ino_t inode;int f;{ int ct, i, j, k; zone_t z; char buf[BLOCK_SIZE]; long timeval; do { for (i = 0, j = 0; i < zone_size; i++, j += ct) { for (k = 0; k < BLOCK_SIZE; k++) buf[k] = 0; if ((ct = read(f, buf, BLOCK_SIZE)) > 0) { if (i == 0) z = alloc_zone(); put_block((z << zone_shift) + i, buf); } } timeval = (dflag ? current_time : file_time(f)); if (ct) add_zone(inode, z, (long) j, timeval); } while (ct == BLOCK_SIZE); close(f);}/*================================================================ * directory & inode management assist group *===============================================================*/void enter_dir(parent, name, child)ino_t parent, child;char *name;{ /* Enter child in parent directory */ /* Works for dir > 1 block and zone > block */ int i, j, k, l, off; block_t b; zone_t z; char *p1, *p2; struct direct dir_entry[NR_DIR_ENTRIES]; d1_inode ino1[V1_INODES_PER_BLOCK]; d2_inode ino2[V2_INODES_PER_BLOCK]; int nr_dzones; b = ((parent - 1) / inodes_per_block) + inode_offset; off = (parent - 1) % inodes_per_block; if (fs_version == 1) { get_block(b, (char *) ino1); nr_dzones = V1_NR_DZONES; } else { get_block(b, (char *) ino2); nr_dzones = V2_NR_DZONES; } for (k = 0; k < nr_dzones; k++) { if (fs_version == 1) { z = ino1[off].d1_zone[k]; if (z == 0) { z = alloc_zone(); ino1[off].d1_zone[k] = z; } } else { z = ino2[off].d2_zone[k]; if (z == 0) { z = alloc_zone(); ino2[off].d2_zone[k] = z; } } for (l = 0; l < zone_size; l++) { get_block((z << zone_shift) + l, (char *) dir_entry); for (i = 0; i < NR_DIR_ENTRIES; i++) { if (dir_entry[i].d_ino == 0) { dir_entry[i].d_ino = child; p1 = name; p2 = dir_entry[i].d_name; j = 14; while (j--) { *p2++ = *p1; if (*p1 != 0) p1++; } put_block((z << zone_shift) + l, (char *) dir_entry); if (fs_version == 1) { put_block(b, (char *) ino1); } else { put_block(b, (char *) ino2); } return; } } } } printf("Directory-inode %d beyond direct blocks. Could not enter %s\n", parent, name); pexit("Halt");}void add_zone(n, z, bytes, cur_time)ino_t n;zone_t z;long bytes, cur_time;{ if (fs_version == 1) { add_z_1(n, z, bytes, cur_time); } else { add_z_2(n, z, bytes, cur_time); }}void add_z_1(n, z, bytes, cur_time)ino_t n;zone_t z;long bytes, cur_time;{ /* Add zone z to inode n. The file has grown by 'bytes' bytes. */ int off, i; block_t b; zone_t indir; zone1_t blk[V1_INDIRECTS]; d1_inode *p; d1_inode inode[V1_INODES_PER_BLOCK]; b = ((n - 1) / V1_INODES_PER_BLOCK) + inode_offset; off = (n - 1) % V1_INODES_PER_BLOCK; get_block(b, (char *) inode); p = &inode[off]; p->d1_size += bytes; p->d1_mtime = cur_time; for (i = 0; i < V1_NR_DZONES; i++) if (p->d1_zone[i] == 0) { p->d1_zone[i] = (zone1_t) z; put_block(b, (char *) inode); return; } put_block(b, (char *) inode); /* File has grown beyond a small file. */ if (p->d1_zone[V1_NR_DZONES] == 0) p->d1_zone[V1_NR_DZONES] = (zone1_t) alloc_zone(); indir = p->d1_zone[V1_NR_DZONES]; put_block(b, (char *) inode); b = indir << zone_shift; get_block(b, (char *) blk); for (i = 0; i < V1_INDIRECTS; i++) if (blk[i] == 0) { blk[i] = (zone1_t) z; put_block(b, (char *) blk); return; } pexit("File has grown beyond single indirect");}void add_z_2(n, z, bytes, cur_time)ino_t n;zone_t z;long bytes, cur_time;{ /* Add zone z to inode n. The file has grown by 'bytes' bytes. */ int off, i; block_t b; zone_t indir; zone_t blk[V2_INDIRECTS]; d2_inode *p; d2_inode inode[V2_INODES_PER_BLOCK]; b = ((n - 1) / V2_INODES_PER_BLOCK) + inode_offset; off = (n - 1) % V2_INODES_PER_BLOCK; get_block(b, (char *) inode); p = &inode[off]; p->d2_size += bytes; p->d2_mtime = cur_time; for (i = 0; i < V2_NR_DZONES; i++) if (p->d2_zone[i] == 0) { p->d2_zone[i] = z; put_block(b, (char *) inode); return; } put_block(b, (char *) inode); /* File has grown beyond a small file. */ if (p->d2_zone[V2_NR_DZONES] == 0) p->d2_zone[V2_NR_DZONES] = alloc_zone(); indir = p->d2_zone[V2_NR_DZONES]; put_block(b, (char *) inode); b = indir << zone_shift; get_block(b, (char *) blk); for (i = 0; i < V2_INDIRECTS; i++) if (blk[i] == 0) { blk[i] = z; put_block(b, (char *) blk); return; } pexit("File has grown beyond single indirect");}void incr_link(n)ino_t n;{ /* Increment the link count to inode n */ int off; block_t b; b = ((n - 1) / inodes_per_block) + inode_offset; off = (n - 1) % inodes_per_block; if (fs_version == 1) { d1_inode inode1[V1_INODES_PER_BLOCK]; get_block(b, (char *) inode1); inode1[off].d1_nlinks++; put_block(b, (char *) inode1); } else { d2_inode inode2[V2_INODES_PER_BLOCK]; get_block(b, (char *) inode2); inode2[off].d2_nlinks++; put_block(b, (char *) inode2); }}void incr_size(n, count)ino_t n;long count;{ /* Increment the file-size in inode n */ block_t b; int off; b = ((n - 1) / inodes_per_block) + inode_offset; off = (n - 1) % inodes_per_block; if (fs_version == 1) { d1_inode inode1[V1_INODES_PER_BLOCK]; get_block(b, (char *) inode1); inode1[off].d1_size += count; put_block(b, (char *) inode1); } else { d2_inode inode2[V2_INODES_PER_BLOCK]; get_block(b, (char *) inode2); inode2[off].d2_size += count; put_block(b, (char *) inode2); }}/*================================================================ * allocation assist group *===============================================================*/PRIVATE ino_t alloc_inode(mode, usrid, grpid)int mode, usrid, grpid;{ ino_t num; int off; block_t b; num = next_inode++; if (num > nrinodes) pexit("File system does not have enough inodes"); b = ((num - 1) / inodes_per_block) + inode_offset; off = (num - 1) % inodes_per_block; if (fs_version == 1) { d1_inode inode1[V1_INODES_PER_BLOCK]; get_block(b, (char *) inode1); inode1[off].d1_mode = mode; inode1[off].d1_uid = usrid; inode1[off].d1_gid = grpid; put_block(b, (char *) inode1); } else { d2_inode inode2[V2_INODES_PER_BLOCK]; get_block(b, (char *) inode2); inode2[off].d2_mode = mode; inode2[off].d2_uid = usrid; inode2[off].d2_gid = grpid; put_block(b, (char *) inode2); } /* Set the bit in the bit map. */ /* DEBUG FIXME. This assumes the bit is in the first inode map block. */ insert_bit((block_t) INODE_MAP, (int) num); return(num);}PRIVATE zone_t alloc_zone(){ /* Allocate a new zone */ /* Works for zone > block */ block_t b; int i; zone_t z; z = next_zone++; b = z << zone_shift; if ((b + zone_size) > nrblocks) pexit("File system not big enough for all the files"); for (i = 0; i < zone_size; i++) put_block(b + i, zero); /* give an empty zone */ /* DEBUG FIXME. This assumes the bit is in the first zone map block. */ insert_bit(zone_map, (int) (z - zoff)); /* lint, NOT OK because * z hasn't been broken * up into block + * offset yet. */ return(z);}void insert_bit(block, bit)block_t block;int bit;{ /* Insert 'count' bits in the bitmap */ int w, s; short buf[BLOCK_SIZE / sizeof(short)]; if (block < 0) pexit("insert_bit called with negative argument"); get_block(block, (char *) buf); w = bit / (8 * sizeof(short)); s = bit % (8 * sizeof(short)); buf[w] |= (1 << s); put_block(block, (char *) buf);}/*================================================================ * proto-file processing assist group *===============================================================*/int mode_con(p)char *p;{ /* Convert string to mode */ int o1, o2, o3, mode; char c1, c2, c3; c1 = *p++; c2 = *p++; c3 = *p++; o1 = *p++ - '0'; o2 = *p++ - '0'; o3 = *p++ - '0'; mode = (o1 << 6) | (o2 << 3) | o3; if (c1 == 'd') mode += I_DIRECTORY; if (c1 == 'b') mode += I_BLOCK_SPECIAL; if (c1 == 'c') mode += I_CHAR_SPECIAL; if (c1 == '-') mode += I_REGULAR; if (c2 == 'u') mode += I_SET_UID_BIT; if (c3 == 'g') mode += I_SET_GID_BIT; return(mode);}void getline(line, parse)char *parse[MAX_TOKENS];char line[LINE_LEN];{ /* Read a line and break it up in tokens */ int k; char c, *p; int d; for (k = 0; k < MAX_TOKENS; k++) parse[k] = 0; for (k = 0; k < LINE_LEN; k++) line[k] = 0; k = 0; parse[0] = 0; p = line; while (1) { if (++k > LINE_LEN) pexit("Line too long"); d = fgetc(proto); if (d == EOF) pexit("Unexpected end-of-file"); *p = d; if (*p == '\n') lct++; if (*p == ' ' || *p == '\t') *p = 0; if (*p == '\n') { *p++ = 0; *p = '\n'; break; } p++; } k = 0; p = line; lastp = line; while (1) { c = *p++; if (c == '\n') return; if (c == 0) continue; parse[k++] = p - 1; do { c = *p++; } while (c != 0 && c != '\n'); }}/*================================================================ * other stuff *===============================================================*/void check_mtab(devname)char *devname; /* /dev/hd1 or whatever */{/* Check to see if the special file named in s is mounted. */ int n; char special[PATH_MAX + 1], mounted_on[PATH_MAX + 1], version[10], rw_flag[10]; if (load_mtab("mkfs") < 0) return; while (1) { n = get_mtab_entry(special, mounted_on, version, rw_flag); if (n < 0) return; if (strcmp(devname, special) == 0) { /* Can't mkfs on top of a mounted file system. */ fprintf(stderr, "%s: %s is mounted on %s\n", progname, devname, mounted_on); exit(1); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -