uint ialloc(ushort type) { uint inum = freeinode++; struct dinode din; bzero(&din, sizeof(din)); din.type = xshort(type); din.nlink = xshort(1); din.size = xint(0); time_t totalTime; struct tm * date; time(&totalTime); date = gmtime(&totalTime); din.second = date->tm_sec; din.minute = date->tm_min; din.hour = date->tm_hour; din.day = date->tm_mday; din.month = date->tm_mon; din.year = date->tm_year; winode(inum, &din); return inum; }
void iappend(uint inum, void *xp, int n) { char *p = (char *)xp; uint fbn, off, n1; struct dinode din; char buf[512]; uint indirect[NINDIRECT]; uint x; rinode(inum, &din); off = xint(din.size); while (n > 0) { fbn = off / 512; assert(fbn < MAXFILE); if (fbn < NDIRECT) { if (xint(din.addrs[fbn]) == 0) { din.addrs[fbn] = xint(freeblock++); usedblocks++; } x = xint(din.addrs[fbn]); } else { if (xint(din.addrs[NDIRECT]) == 0) { // printf("allocate indirect block\n"); din.addrs[NDIRECT] = xint(freeblock++); usedblocks++; } // printf("read indirect block\n"); rsect(xint(din.addrs[NDIRECT]), (char *)indirect); if (indirect[fbn - NDIRECT] == 0) { indirect[fbn - NDIRECT] = xint(freeblock++); usedblocks++; wsect(xint(din.addrs[NDIRECT]), (char *)indirect); } x = xint(indirect[fbn - NDIRECT]); } n1 = min(n, (fbn + 1) * 512 - off); rsect(x, buf); memcpy(buf + off - (fbn * 512), p, n1); wsect(x, buf); n -= n1; off += n1; p += n1; } din.size = xint(off); winode(inum, &din); }
uint ialloc(ushort type) { uint inum = freeinode++; struct dinode din; memset(&din, 0, sizeof(din)); din.type = xshort(type); din.nlink = xshort(1); din.size = xint(0); winode(inum, &din); return inum; }
uint ialloc(ushort type) { uint inum = freeinode++; struct dinode din; bzero(&din, sizeof(din)); din.type = xshort(type); din.nlink = xshort(1); din.logical_size = xint(0); winode(inum, &din); return inum; }
void iappend(uint inum, void *xp, int n) { char *p = (char*)xp; uint fbn, off, n1; struct dinode din; char buf[BSIZE]; uint indirect[NINDIRECT]; uint x; rinode(inum, &din); off = xint(din.size); // printf("append inum %d at off %d sz %d\n", inum, off, n); while(n > 0){ fbn = off / BSIZE; assert(fbn < MAXFILE); if(fbn < NDIRECT){ if(xint(din.addrs[fbn]) == 0){ din.addrs[fbn] = xint(freeblock++); } x = xint(din.addrs[fbn]); } else { if(xint(din.addrs[NDIRECT]) == 0){ din.addrs[NDIRECT] = xint(freeblock++); } rsect(xint(din.addrs[NDIRECT]), (char*)indirect); if(indirect[fbn - NDIRECT] == 0){ indirect[fbn - NDIRECT] = xint(freeblock++); wsect(xint(din.addrs[NDIRECT]), (char*)indirect); } x = xint(indirect[fbn-NDIRECT]); } n1 = min(n, (fbn + 1) * BSIZE - off); rsect(x, buf); bcopy(p, buf + off - (fbn * BSIZE), n1); wsect(x, buf); n -= n1; off += n1; p += n1; } din.size = xint(off); winode(inum, &din); }
uint ialloc(ushort type) { uint inum = freeinode++; struct dinode din; bzero(&din, sizeof(din)); din.type = xshort(type); din.nlink = xshort(1); din.size = xint(0); // Set notable defaults din.ownerId = xshort(0); din.groupId = xshort(100); din.mode = xint(0x0755); winode(inum, &din); return inum; }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off; struct dirent de; char buf[512]; struct dinode din; if(argc < 2){ fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((512 % sizeof(struct dinode)) == 0); assert((512 % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } sb.size = xint(size); sb.nblocks = xint(nblocks); // so whole disk is size sectors sb.ninodes = xint(ninodes); bitblocks = size/(512*8) + 1; usedblocks = ninodes / IPB + 3 + bitblocks; freeblock = usedblocks; printf("used %d (bit %d ninode %zu) free %u total %d\n", usedblocks, bitblocks, ninodes/IPB + 1, freeblock, nblocks+usedblocks); assert(nblocks + usedblocks == size); for(i = 0; i < nblocks + usedblocks; i++) wsect(i, zeroes); wsect(1, &sb); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); for(i = 2; i < argc; i++){ assert(index(argv[i], '/') == 0); if((fd = open(argv[i], 0)) < 0){ perror(argv[i]); exit(1); } // Skip leading _ in name when writing to file system. // The binaries are named _rm, _cat, etc. to keep the // build operating system from trying to execute them // in place of system binaries like rm and cat. if(argv[i][0] == '_') ++argv[i]; inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, argv[i], DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) iappend(inum, buf, cc); close(fd); } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(usedblocks); exit(0); }
int add_dir(DIR *cur_dir, int cur_inode, int parent_inode) { int r; int child_inode; int cur_fd, child_fd; struct xv6_dirent de; struct dinode din; struct dirent dir_buf; struct dirent *entry; struct stat st; int bytes_read; char buf[BLOCK_SIZE]; int off; bzero(&de, sizeof(de)); de.inum = xshort(cur_inode); strcpy(de.name, "."); iappend(cur_inode, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(parent_inode); strcpy(de.name, ".."); iappend(cur_inode, &de, sizeof(de)); if (cur_dir == NULL) { return 0; } cur_fd = dirfd(cur_dir); if (cur_fd == -1){ perror("add_dir"); exit(EXIT_FAILURE); } if (fchdir(cur_fd) != 0){ perror("add_dir"); return -1; } while (true) { r = readdir_r(cur_dir, &dir_buf, &entry); if (r != 0) { perror("add_dir"); return -1; } if (entry == NULL) break; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; printf("%s\n", entry->d_name); child_fd = open(entry->d_name, O_RDONLY); if (child_fd == -1) { perror("open"); return -1; } r = fstat(child_fd, &st); if (r != 0) { perror("stat"); return -1; } if (S_ISDIR(st.st_mode)) { child_inode = ialloc(T_DIR); r = add_dir(fdopendir(child_fd), child_inode, cur_inode); if (r != 0) return r; if (fchdir(cur_fd) != 0) { perror("chdir"); return -1; } } else { bytes_read = 0; child_inode = ialloc(T_FILE); bzero(&de, sizeof(de)); while((bytes_read = read(child_fd, buf, sizeof(buf))) > 0) { iappend(child_inode, buf, bytes_read); } } close(child_fd); de.inum = xshort(child_inode); strncpy(de.name, entry->d_name, DIRSIZ); iappend(cur_inode, &de, sizeof(de)); } // fix size of inode cur_dir rinode(cur_inode, &din); off = xint(din.logical_size); off = ((off/BSIZE) + 1) * BSIZE; din.logical_size = xint(off); winode(cur_inode, &din); return 0; }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off; struct dirent de; char buf[512]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc < 2){ fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((512 % sizeof(struct dinode)) == 0); assert((512 % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } sb.size = xint(size); sb.nblocks = xint(nblocks); // so whole disk is size sectors sb.ninodes = xint(ninodes); sb.nlog = xint(nlog); bitblocks = size/(512*8) + 1; usedblocks = ninodes / IPB + 3 + bitblocks; freeblock = usedblocks; printf("used %d (bit %d ninode %zu) free %u log %u total %d\n", usedblocks, bitblocks, ninodes/IPB + 1, freeblock, nlog, nblocks+usedblocks+nlog); assert(nblocks + usedblocks + nlog == size); for(i = 0; i < nblocks + usedblocks + nlog; i++) wsect(i, zeroes); memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); for(i = 2; i < argc; i++){ char *name = argv[i]; if (!strncmp(name, "fs/", 3)) name += 3; assert(index(name, '/') == 0); if((fd = open(argv[i], 0)) < 0){ perror(argv[i]); exit(1); } inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, name, DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) iappend(inum, buf, cc); close(fd); } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(usedblocks); exit(0); }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off; struct dirent de; char buf[BSIZE]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc < 2){ fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((BSIZE % sizeof(struct dinode)) == 0); assert((BSIZE % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } // 1 fs block = 1 disk sector nmeta = 2 + nlog + ninodeblocks + nbitmap; nblocks = FSSIZE - nmeta; sb.size = xint(FSSIZE); sb.nblocks = xint(nblocks); sb.ninodes = xint(NINODES); sb.nlog = xint(nlog); sb.logstart = xint(2); sb.inodestart = xint(2+nlog); sb.bmapstart = xint(2+nlog+ninodeblocks); printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n", nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE); freeblock = nmeta; // the first free block that we can allocate for(i = 0; i < FSSIZE; i++) wsect(i, zeroes); memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); for(i = 2; i < argc; i++){ assert(index(argv[i], '/') == 0); if((fd = open(argv[i], 0)) < 0){ perror(argv[i]); exit(1); } // Skip leading _ in name when writing to file system. // The binaries are named _rm, _cat, etc. to keep the // build operating system from trying to execute them // in place of system binaries like rm and cat. if(argv[i][0] == '_') ++argv[i]; inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, argv[i], DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) iappend(inum, buf, cc); close(fd); } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(freeblock); exit(0); }
int main(int argc, char *argv[]) { int i, cc, fd; uint rootino, inum, off, bin_inum, tests_inum, sbin_inum; //dir_inum struct dirent de; char buf[BSIZE]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc < 2) { fprintf(stderr, "Usage: mkfs fs.img files...\n"); exit(1); } assert((BSIZE % sizeof(struct dinode)) == 0); assert((BSIZE % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666); if(fsfd < 0) { perror(argv[1]); exit(1); } // 1 fs block = 1 disk sector nmeta = 2 + nlog + ninodeblocks + nbitmap; nblocks = FSSIZE - nmeta; sb.size = xint(FSSIZE); sb.nblocks = xint(nblocks); sb.ninodes = xint(NINODES); sb.nlog = xint(nlog); sb.logstart = xint(2); sb.inodestart = xint(2 + nlog); sb.bmapstart = xint(2 + nlog + ninodeblocks); printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n", nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE); freeblock = nmeta; // the first free block that we can allocate for(i = 0; i < FSSIZE; i++) { wsect(i, zeroes); } memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(rootino, &de, sizeof(de)); // create /bin folder bin_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(bin_inum); strcpy(de.name, "bin"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(bin_inum); strcpy(de.name, "."); iappend(bin_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(bin_inum, &de, sizeof(de)); // create /dev folder inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(inum); strcpy(de.name, "dev"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(inum); strcpy(de.name, "."); iappend(inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(inum, &de, sizeof(de)); // create /sbin folder sbin_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(sbin_inum); strcpy(de.name, "sbin"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(sbin_inum); strcpy(de.name, "."); iappend(sbin_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(sbin_inum, &de, sizeof(de)); // create /tests folder tests_inum = ialloc(T_DIR); bzero(&de, sizeof(de)); de.inum = xshort(tests_inum); strcpy(de.name, "tests"); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(tests_inum); strcpy(de.name, "."); iappend(tests_inum, &de, sizeof(de)); bzero(&de, sizeof(de)); de.inum = xshort(rootino); strcpy(de.name, ".."); iappend(tests_inum, &de, sizeof(de)); for(i = 2; i < argc; i++) { printf("argv[i]: %s and index: %s\n", argv[i], index(argv[i], '/')); //assert(index(argv[i], '/') == 0); if((fd = open(argv[i], 0)) < 0) { perror(argv[i]); exit(1); } if(index(argv[i], '/') != 0) { char foldername[256]; char *progname = malloc(sizeof(char) * 256); strcpy(progname, skipelem(argv[i], foldername)); if(progname[0] == '_') { progname++; } if(strcmp(foldername, "bin") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(bin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "tests") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(tests_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "sbin") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(sbin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "docs") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else if(strcmp(foldername, "shell") == 0) { inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, progname, DIRSIZ); iappend(bin_inum, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } else { printf("\nERROR: Found folder other than bin and tests: %s\n", foldername); exit(1); } } else { // Skip leading _ in name when writing to file system. // The binaries are named _rm, _cat, etc. to keep the // build operating system from trying to execute them // in place of system binaries like rm and cat. if(argv[i][0] == '_') { ++argv[i]; } inum = ialloc(T_FILE); bzero(&de, sizeof(de)); de.inum = xshort(inum); strncpy(de.name, argv[i], DIRSIZ); iappend(rootino, &de, sizeof(de)); while((cc = read(fd, buf, sizeof(buf))) > 0) { iappend(inum, buf, cc); } close(fd); } } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off / BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(freeblock); exit(0); }
void iappend(uint inum, void *xp, int n) { char *p = (char*)xp; uint fbn, off, n1; struct dinode din; char buf[512]; uint indirect[512]; uint x; rinode(inum, &din); int temp_fbn, d1, d2, k1, k2, k3, a1, a2, a3; off = xint(din.size); while(n > 0){ //printf("%d\n", n); fbn = off / 512; //assert(fbn < MAXFILE); if(fbn < NDIRECT){ //printf("hjw 1 %d\n", n); if(xint(din.addrs[fbn]) == 0){ din.addrs[fbn] = xint(freeblock++); usedblocks++; } x = xint(din.addrs[fbn]); } else { temp_fbn = fbn; temp_fbn -= NDIRECT; d1 = temp_fbn / 128; k1 = temp_fbn % 128; d2 = d1 / 128; k2 = d1 % 128; //d3 = d2 / 128; k3 = d2 % 128; if((a1 = din.addrs[NDIRECT]) == 0) { a1 = din.addrs[NDIRECT] = xint(freeblock++); usedblocks ++; } rsect(xint(a1), (char*)indirect); if((a2 = indirect[k3]) == 0) { a2 = indirect[k3] = xint(freeblock++); usedblocks ++; wsect(xint(a1), (char*)indirect); } rsect(xint(a2), (char*)indirect); if((a3 = indirect[k2]) == 0) { a3 = indirect[k2] = xint(freeblock++); usedblocks ++; wsect(xint(a2), (char*)indirect); } rsect(xint(a3), (char*)indirect); if((x = indirect[k1]) == 0) { x = indirect[k1] = xint(freeblock++); usedblocks ++; wsect(xint(a3), (char*)indirect); } x = xint(x); //printf("%d--", fbn); } //printf("%d\n", x); n1 = min(n, (fbn + 1) * 512 - off); rsect(x, buf); //printf("hjw 2 %d %d %d %d\n", n, off - (fbn * 512), n1, sizeof(p)); bcopy(p, buf + off - (fbn * 512), n1); // printf("hjw 3 %d\n", n); wsect(x, buf); n -= n1; off += n1; p += n1; } din.size = xint(off); winode(inum, &din); }
int main(int argc, char *argv[]) { int i; uint rootino, off; struct dirent de; char buf[512]; struct dinode din; static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); if(argc != 3) { fprintf(stderr, "Usage: mkfs.xv6 <image name> <test|release>\n"); exit(1); } assert((512 % sizeof(struct dinode)) == 0); assert((512 % sizeof(struct dirent)) == 0); fsfd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666); if(fsfd < 0){ perror(argv[1]); exit(1); } sb.size = xint(size); sb.nblocks = xint(nblocks); // so whole disk is size sectors sb.ninodes = xint(ninodes); sb.nlog = xint(nlog); bitblocks = size/(512*8) + 1; usedblocks = ninodes / IPB + 3 + bitblocks; freeblock = usedblocks; if (0) { printf("used %d (bit %d ninode %zu) free %u log %u total %d\n", usedblocks, bitblocks, ninodes/IPB + 1, freeblock, nlog, nblocks+usedblocks+nlog); } assert(nblocks + usedblocks + nlog == size); for(i = 0; i < nblocks + usedblocks + nlog; i++) wsect(i, zeroes); memset(buf, 0, sizeof(buf)); memmove(buf, &sb, sizeof(sb)); wsect(1, buf); rootino = ialloc(T_DIR); assert(rootino == ROOTINO); bzero(&de, sizeof(de)); de.d_ino = xshort(rootino); strcpy(de.d_name, "."); iappend(rootino, &de, sizeof(de)); bzero(&de, sizeof(de)); de.d_ino = xshort(rootino); strcpy(de.d_name, ".."); iappend(rootino, &de, sizeof(de)); if (!strcmp(argv[2], "release")) { create_fhs(rootino, "coreutils/init"); } else if (!strcmp(argv[2], "test")) { create_fhs(rootino, "tests/init"); create_tests(rootino); } // fix size of root inode dir rinode(rootino, &din); off = xint(din.size); off = ((off/BSIZE) + 1) * BSIZE; din.size = xint(off); winode(rootino, &din); balloc(usedblocks); exit(0); }