0: unused 1: super block (size, ninodes) 2: log for transactions 32: array of inodes, packed into blocks 45: block in-use bitmap (0=free, 1=used) 46: file/dir content blocks end of disk
type (free, file, directory, device) nlink size addrs[12+1]
------------------------------------------------------ structinode { uint dev; // Device number uint inum; // Inode number int ref; // Reference count structsleeplocklock;// protects everything below here int valid; // inode has been read from disk?
short type; // copy of disk inode short major; short minor; short nlink; uint size; uint addrs[NDIRECT+1]; };
structdinode { short type; // File type short major; // Major device number (T_DEVICE only) short minor; // Minor device number (T_DEVICE only) short nlink; // Number of links to inode in file system uint size; // Size of file (bytes) uint addrs[NDIRECT+1]; // Data block addresses };
short = 4字节,uint = 8字节,正好64字节。
当执行一个echo hi > x ,可以简单追踪一下对于磁盘来说发生了什么,其实主要是三个步骤,分别是创建x这个文件、往x里面写入文件、更新对应的inode。具体步骤如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// create bwrite: block 33 by ialloc // allocate inode in inode block 33 bwrite: block 33 by iupdate // update inode (e.g., set nlink) bwrite: block 46 by writei // write directory entry, adding "x" by dirlink() bwrite: block 32 by iupdate // update directory inode, because inode may have changed bwrite: block 33 by iupdate // itrunc new inode (even though nothing changed) // write bwrite: block 45 by balloc // allocate a block in bitmap block 45 bwrite: block 595 by bzero // zero the allocated block (block 524) bwrite: block 595 by writei // write to it (hi) bwrite: block 33 by iupdate // update inode // write bwrite: block 595 by writei // write to it (\n) bwrite: block 33 by iupdate // update inode
// On-disk inode structure structdinode { short type; // File type short major; // Major device number (T_DEVICE only) short minor; // Minor device number (T_DEVICE only) short nlink; // Number of links to inode in file system uint size; // Size of file (bytes) uint addrs[NDIRECT+2]; // Data block addresses };
pthread_cond_wait(&cond, &mutex); // go to sleep on cond, releasing lock mutex, acquiring upon wake up pthread_cond_broadcast(&cond); // wake up every thread sleeping on cond
On most instructions a lock prefix must be explicitly used except for the xchg instruction where the lock prefix is implied if the instruction involves a memory address.
// Given a parent process's page table, copy // its memory into a child's page table. // Copies both the page table and the // physical memory. // returns 0 on success, -1 on failure. // frees any allocated pages on failure. int uvmcopy(pagetable_t old, pagetable_tnew, uint64 sz) { pte_t *pte; uint64 pa, i; uint flags;