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

时间:2017-07-08 21:30:00

标签: c linux filesystems system-calls

最近我遇到了这个练习:

  

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

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

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

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

现在,跳过 draw 部分(我意识到这会很难回答),我想了解lseekwrite的工作原理inode和索引块(无论它们是什么)。

我试图确定lseek计算正确的inode(因为块大小已知),但仍然不知道它实际上是如何工作的。

1 个答案:

答案 0 :(得分:2)

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

  • inodes 表示磁盘上的真实文件。通过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路径访问磁盘上的文件。