最近我遇到了这个练习:
给出一个在Linux C语言程序中的系统调用序列:
fd = open("f123", O_RDWRT | O_CREAT, 0777);
lseek(fd, 0x1000000L, 0);
write(fd, &fd, sizeof(int));
请绘制修改这些操作的文件系统数据结构和磁盘块,考虑4 KByte块大小和4字节的索引块指针。关于第一个系统调用(open),我已经了解了它的工作原理并将其示意如下:
![open system call](https://istack.dev59.com/YXRcM.webp)
最近我遇到了这个练习:
给出一个在Linux C语言程序中的系统调用序列:
fd = open("f123", O_RDWRT | O_CREAT, 0777);
lseek(fd, 0x1000000L, 0);
write(fd, &fd, sizeof(int));
文件
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 *);
}
open()
创建文件对象,其他系统调用如lseek()
只需获取file
对象(通过Fd),并调用操作列表中相应的函数,如write()
将调用f->f_op->write(f, ...)
,然后文件系统可以沿着file -> d_entry -> inode
路径访问磁盘上的文件。
open()
函数确定inode节点,其他函数使用该信息。您需要一个打开的文件描述符表和一个打开的文件描述符表(这可能是您所说的“文件表”的意思,但我不确定)。描述符(与描述符相对)保存寻址偏移量(文件中的当前位置)。通常,多个描述符可以引用单个描述符 - 这些描述符不必全部在同一进程中,尽管在您的示例代码中,只涉及一个进程。 - Jonathan Lefflerlseek()
不会搜索正确的块;它也不需要。下一个 I/O 操作(与移动操作相对)需要跟踪块。例如,您可以寻找远超当前文件结尾的位置。接下来会发生什么取决于您是读取(EOF)还是写入(新材料被写入,并且任何跳过的块都被视为所有字节为零;包含当前 EOF 的最后一个块的尾部和当前块的开头可能需要强制清零)。您不能从开头使用负偏移量,但除此之外,lseek()
成功(受类型限制)。 - Jonathan Leffler