# 文件系统及存储系统介绍 <!-- Put the link to this slide here so people can follow --> slide: https://hackmd.io/@uxqdsRWJSAeXND27CY28vw/B18PGCKBX#/ --- 大纲: * 文件和目录的组织方式 * 一个简单文件系统的实现 * Log-structured File System * Brief on SSD * Brief on NFS & AFS * LSM-Tree (if time permits) --- ## 文件和目录的组织方式 * 文件系统接口(interface) * 系统调用 * man * strace --- ### open: 创建文件描述符 ```c int fd = open("/path/to/dir/filename.txt", O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); ``` * 0: stdin * 1: stdout * 2: stderr ---- ```c // Per-process state struct proc { uint sz; // Size of process memory (bytes) pde_t* pgdir; // Page table char *kstack; // Bottom of kernel stack for this process enum procstate state; // Process state int pid; // Process ID struct proc *parent; // Parent process struct trapframe *tf; // Trap frame for current syscall struct context *context; // swtch() here to run process void *chan; // If non-zero, sleeping on chan int killed; // If non-zero, have been killed struct file *ofile[NOFILE]; // Open files struct inode *cwd; // Current directory char name[16]; // Process name (debugging) }; ``` ---- ### read/write: 通过文件描述符读写文件 ```c char buf[4096]; int num_bytes_read = read(fd, buf, 4096); int numb_bytes_write = write(fd, buf, strlen(buf)); ``` strace 看一眼 ---- ### lseek: 非顺序读写 ```c off_t lseek(int fildes, off_t offset, int whence); ``` whence 有几个可能 * `SEEK_SET` * `SEEK_CUR` * `SEEK_END` ---- ```c struct file { enum { FD_NONE, FD_PIPE, FD_INODE } type; int ref; // reference count char readable; char writable; struct pipe *pipe; struct inode *ip; uint off; }; ``` ---- ### Open file table, ftable ```c struct file *ofile[NOFILE]; // Open files ``` ```c struct { struct spinlock lock; struct file file[NFILE]; } ftable; ``` ---- ### fork/dup: 文件描述符管理 ```c int main(int argc, char*argv[]) { int fd = open("file.txt", O_RDONLY); assert(fd >= 0); int rc = fork(); if (rc == 0) { rc = lseek(fd, 10, SEEK_SET); printf("child: offset %d\n", rc); } else if (rc > 0) { (void) wait(NULL); printf("parent: offset %d\n",(int) lseek(fd, 0, SEEK_CUR)); } return 0; } ``` ---- ```text prompt> ./fork-seek child: offset 10 parent: offset 10 prompt> ``` ---- #### reference count * file->ref = 0, remove from ftable * fork/dup, ref++ ```c int new_fd = dup(fd); dup2(fd, 1); ``` ---- #### input/output redirection ```bash ls existing-file non-existing-file > tmp1 2>&1 ``` ---- #### fsync: 刷缓存到磁盘 * dirty buffer * `fsync(fd)` * write barrier ---- #### rename: 重命名文件 ```c int rename(char* oldname, char* newname); ``` * Atomicity! ```c int fd = open("foo.txt.tmp", O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR); write(fd, buffer, size); // write out new version of file fsync(fd); close(fd); rename("foo.txt.tmp", "foo.txt"); ``` ---- #### mkdir: 创建文件夹 `strace mkdir foo` * `.` * `..` ```c struct dirent { ushort inum; char name[DIRSIZ]; }; ``` ---- #### rmdir: 删除文件夹 only blank dir ---- #### unlink: 删除文件 `strace rm tmp.txt` 可以看到 ```c unlink("tmp.txt") ``` ---- #### inode ```c // in-memory copy of an inode struct inode { uint dev; // Device number uint inum; // Inode number int ref; // Reference count struct sleeplock lock; // 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]; }; ``` ---- #### ln: file link * `ln file1 file2` * `stat file` ---- #### mount: 挂载文件系统 Everything is a file * `/proc` * `/dev/shm` * 我挂我自己 --- ## 一个简单文件系统的实现 VSFS * 持久性 * 一致性 --- ### 空间管理 * FS 的核心是 inode ####
{"metaMigratedAt":"2023-06-14T17:35:51.843Z","metaMigratedFrom":"YAML","title":"Talk slides template","breaks":true,"description":"View the slide with \"Slide Mode\".","contributors":"[{\"id\":\"bb1a9db1-1589-4807-9734-3dbb098dbcbf\",\"add\":23979,\"del\":19955}]"}
    266 views