Linux系统调用如何与文件系统交互

最近我面对这个运动:

在Linux C语言程序中给出这一系列的系统调用:

fd = open("f123", O_RDWRT | O_CREAT, 0777); lseek(fd, 0x1000000L, 0); write(fd, &fd, sizeof(int)); 

绘制由这些操作修改的文件系统数据结构和磁盘块 (考虑4 KB的块大小)以及4个字节的索引块指针。

对于第一个系统调用( open ),我意识到它是如何工作的,并以这种方式进行模式化: 打开系统调用

现在,跳过绘制部分(我意识到这将使难以回答),我想了解如何使用inode和索引块(不pipe它们是什么)。

我试图找出lseek计算正确的inode(因为块大小是已知的),但仍然没有线索如何实际工作。

在Linux中,这些系统调用与虚拟文件系统(VFS)交互。 VFS建立在真实文件系统的抽象上,它定义了一些有用的数据结构来组织文件系统。

  • inode代表磁盘上的真实文件。 通过inode结构不仅可以访问inode块,还可以访问磁盘上的数据块。
  • 目录条目表示路径的一部分。 d_entry并不总是指向磁盘上的真实文件。 如果引用了磁盘上的目录,则会有一个指向目录文件的inode结构体的指针。
  • 文件表示由进程打开的文件。 在结构中还有一个指向它的d_entry的指针。

这里是来自file struct的片段:

 struct file { // ... other attributes struct path f_path; #define f_dentry f_path.dentry #define f_vfsmnt f_path.mnt const struct file_operations *f_op; }; struct file_operations { // ... other operations struct module *owner; loff_t (*llseek) (struct file *, loff_t, int); ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); } 

这些对象都有一个操作列表字段。 VFS定义了这些操作,下层文件系统实现这些操作或使用VFS提供的一般实现。

syscall open()创建文件对象,像lseek()这样的其他系统调用只需获取file对象(通过Fd)并调用操作列表中相应的函数,就像write()将调用f->f_op->write(f, ...) ,那么文件系统可能会遵循file -> d_entry -> inode路径来访问磁盘上的文件。