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

标签 c linux filesystems system-calls

最近我遇到了这个练习:

Given this sequence of system calls in a Linux C language program:

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

draw the file system data structures and disk blocks that are modified by these operations, considering a 4 KByte block size, and index block pointers of 4 bytes.

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

现在,跳过 draw 部分(我意识到这很难回答),我想了解如何 lseekwrite 根据 inode 和索引 block (无论它们是什么)工作。

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

最佳答案

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

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

以下是 file 结构的片段:

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 提供的通用实现。

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

关于c - Linux 系统调用如何与文件系统交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44990909/

相关文章:

c - 关于宏

c - bash 管道中的 u3-tool 不起作用 | C中的段错误

c - 如何以编程方式确定驱动器的空间/大小?在 LInux 和 Windows 中

java - 适用于 Windows 的内存文件系统

c - 以两种不同的方式在升序数组中搜索值

c++ - 固定大小缓冲区中的树实现

c++ - 嵌入式 C - 我应该使用哪种类型的错误代码?签名与未签名

用于每月归档的 Linux Bash

hadoop - 文件大小不正确的文件系统镜像

macos - 操作系统: modifying files with proper rights