diff options
author | Robert Morris <[email protected]> | 2019-06-11 09:57:14 -0400 |
---|---|---|
committer | Robert Morris <[email protected]> | 2019-06-11 09:57:14 -0400 |
commit | 5753553213df8f9de851adb68377db43faecb91f (patch) | |
tree | 3b629ff54897fca414146677532cb459a2ed11ba /mkfs.c | |
parent | 91ba81110acd3163f7de3580b677eece0c57f5e7 (diff) | |
download | xv6-labs-5753553213df8f9de851adb68377db43faecb91f.tar.gz xv6-labs-5753553213df8f9de851adb68377db43faecb91f.tar.bz2 xv6-labs-5753553213df8f9de851adb68377db43faecb91f.zip |
separate source into kernel/ user/ mkfs/
Diffstat (limited to 'mkfs.c')
-rw-r--r-- | mkfs.c | 298 |
1 files changed, 0 insertions, 298 deletions
@@ -1,298 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <assert.h> - -#define stat xv6_stat // avoid clash with host struct stat -#include "types.h" -#include "fs.h" -#include "stat.h" -#include "param.h" - -#ifndef static_assert -#define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0) -#endif - -#define NINODES 200 - -// Disk layout: -// [ boot block | sb block | log | inode blocks | free bit map | data blocks ] - -int nbitmap = FSSIZE/(BSIZE*8) + 1; -int ninodeblocks = NINODES / IPB + 1; -int nlog = LOGSIZE; -int nmeta; // Number of meta blocks (boot, sb, nlog, inode, bitmap) -int nblocks; // Number of data blocks - -int fsfd; -struct superblock sb; -char zeroes[BSIZE]; -uint freeinode = 1; -uint freeblock; - - -void balloc(int); -void wsect(uint, void*); -void winode(uint, struct dinode*); -void rinode(uint inum, struct dinode *ip); -void rsect(uint sec, void *buf); -uint ialloc(ushort type); -void iappend(uint inum, void *p, int n); - -// convert to intel byte order -ushort -xshort(ushort x) -{ - ushort y; - uchar *a = (uchar*)&y; - a[0] = x; - a[1] = x >> 8; - return y; -} - -uint -xint(uint x) -{ - uint y; - uchar *a = (uchar*)&y; - a[0] = x; - a[1] = x >> 8; - a[2] = x >> 16; - a[3] = x >> 24; - return y; -} - -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.magic = FSMAGIC; - 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); -} - -void -wsect(uint sec, void *buf) -{ - if(lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE){ - perror("lseek"); - exit(1); - } - if(write(fsfd, buf, BSIZE) != BSIZE){ - perror("write"); - exit(1); - } -} - -void -winode(uint inum, struct dinode *ip) -{ - char buf[BSIZE]; - uint bn; - struct dinode *dip; - - bn = IBLOCK(inum, sb); - rsect(bn, buf); - dip = ((struct dinode*)buf) + (inum % IPB); - *dip = *ip; - wsect(bn, buf); -} - -void -rinode(uint inum, struct dinode *ip) -{ - char buf[BSIZE]; - uint bn; - struct dinode *dip; - - bn = IBLOCK(inum, sb); - rsect(bn, buf); - dip = ((struct dinode*)buf) + (inum % IPB); - *ip = *dip; -} - -void -rsect(uint sec, void *buf) -{ - if(lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE){ - perror("lseek"); - exit(1); - } - if(read(fsfd, buf, BSIZE) != BSIZE){ - perror("read"); - exit(1); - } -} - -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); - winode(inum, &din); - return inum; -} - -void -balloc(int used) -{ - uchar buf[BSIZE]; - int i; - - printf("balloc: first %d blocks have been allocated\n", used); - assert(used < BSIZE*8); - bzero(buf, BSIZE); - for(i = 0; i < used; i++){ - buf[i/8] = buf[i/8] | (0x1 << (i%8)); - } - printf("balloc: write bitmap block at sector %d\n", sb.bmapstart); - wsect(sb.bmapstart, buf); -} - -#define min(a, b) ((a) < (b) ? (a) : (b)) - -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); -} |