# 文件系统及存储系统介绍
<!-- 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}]"}