Can please summarize the events/steps that happen when I try to execute a read()/write() system call. How does the kernel know which file system to issue these commands.
可以总结一下我尝试执行read()/ write()系统调用时发生的事件/步骤。内核如何知道发出这些命令的文件系统。
Lets say a process calls write(). Then It will call sys_write().
让我们说一个进程调用write()。然后它将调用sys_write()。
Now probably, since sys_write() is executed on behalf of the current process, it can access the struct task_struct and hence it can access the struct files_struct and struct fs_struct which contains file system information.
现在可能,因为sys_write()是代表当前进程执行的,所以它可以访问struct task_struct,因此它可以访问包含文件系统信息的struct files_struct和struct fs_struct。
But after that I am not seeing, how this fs_struct is helping to identify the file system.
但之后我没有看到,这个fs_struct如何帮助识别文件系统。
Edit: Now that Alex has described the flow...I have still doubt how the read/write are getting routed to a FS, since the VFS does not do it, then it must be happening somewhere else, Also how is the underlying block device and then finally the hardware protocol PCI/USB getting attached.
编辑:既然Alex已经描述了流程......我仍然怀疑读/写如何被路由到FS,因为VFS没有这样做,那么它必须在其他地方发生,另外底层是怎么回事设备然后最终硬件协议PCI / USB附加。
A simple flow chart involving actual data structures would be helpful
涉及实际数据结构的简单流程图会很有帮助
Please help.
请帮忙。
2 个解决方案
#1
13
This answer is based on kernel version 4.0. I traced out some of the code which handles a read
syscall. I recommend you clone the Linux source repo and follow along in the source code.
这个答案基于内核版本4.0。我找出了一些处理读取系统调用的代码。我建议您克隆Linux源代码库并在源代码中进行操作。
- Syscall handler for
read
, atfs/read_write.c:620
is called. It receives a file descriptor (integer) as an argument, and callsfdget_pos
to convert it to astruct fd
. - 调用Syscall处理程序,在fs / read_write.c:620处调用。它接收文件描述符(整数)作为参数,并调用fdget_pos将其转换为struct fd。
-
fdget_pos
calls__fdget_pos
calls__fdget
calls__fget_light
.__fget_light
usescurrent->files
, the file descriptor table for the current process, to look up thestruct file
which corresponds to the passed file descriptor number. - fdget_pos调用__fdget_pos调用__fdget调用__fget_light。 __fget_light使用current-> files(当前进程的文件描述符表)来查找与传递的文件描述符号对应的struct文件。
- Back in the syscall handler, the file struct is passed to
vfs_read
, atfs/read_write.c:478
. - 回到syscall处理程序,文件结构传递给vfs_read,位于fs / read_write.c:478。
-
vfs_read
calls__vfs_read
, which callsfile->f_op->read
. From here on, you are in filesystem-specific code. - vfs_read调用__vfs_read,调用file-> f_op-> read。从此处开始,您将使用特定于文件系统的代码。
So the VFS doesn't really bother "identifying" the filesystem which a file lives on; it simply uses the table of "file operation" function pointers which is stored in its struct file
. When that struct file
is initialized, it is given the correct f_op
function pointer table which implements all the filesystem-specific operations for its filesystem.
所以VFS并不真正打扰“识别”文件所在的文件系统;它只是使用存储在其struct文件中的“文件操作”函数指针表。初始化该结构文件时,会为其提供正确的f_op函数指针表,该表实现其文件系统的所有特定于文件系统的操作。
#2
0
Each filesystem registers itself to VFS. When a filesystem is mounted, its superblock is read and VFS superblock is populated with this information. Function pointer table for this filesystem is also populated at this time. when file->f_op->read call happens, registered function from the filesystem is actually called. You can refer to text in http://www.science.unitn.it/~fiorella/guidelinux/tlk/node102.html
每个文件系统都将自己注册到VFS。安装文件系统时,将读取其超级块,并使用此信息填充VFS超级块。此时还会填充此文件系统的函数指针表。当file-> f_op->读取调用发生时,实际调用文件系统中的注册函数。您可以参考http://www.science.unitn.it/~fiorella/guidelinux/tlk/node102.html中的文字。
#1
13
This answer is based on kernel version 4.0. I traced out some of the code which handles a read
syscall. I recommend you clone the Linux source repo and follow along in the source code.
这个答案基于内核版本4.0。我找出了一些处理读取系统调用的代码。我建议您克隆Linux源代码库并在源代码中进行操作。
- Syscall handler for
read
, atfs/read_write.c:620
is called. It receives a file descriptor (integer) as an argument, and callsfdget_pos
to convert it to astruct fd
. - 调用Syscall处理程序,在fs / read_write.c:620处调用。它接收文件描述符(整数)作为参数,并调用fdget_pos将其转换为struct fd。
-
fdget_pos
calls__fdget_pos
calls__fdget
calls__fget_light
.__fget_light
usescurrent->files
, the file descriptor table for the current process, to look up thestruct file
which corresponds to the passed file descriptor number. - fdget_pos调用__fdget_pos调用__fdget调用__fget_light。 __fget_light使用current-> files(当前进程的文件描述符表)来查找与传递的文件描述符号对应的struct文件。
- Back in the syscall handler, the file struct is passed to
vfs_read
, atfs/read_write.c:478
. - 回到syscall处理程序,文件结构传递给vfs_read,位于fs / read_write.c:478。
-
vfs_read
calls__vfs_read
, which callsfile->f_op->read
. From here on, you are in filesystem-specific code. - vfs_read调用__vfs_read,调用file-> f_op-> read。从此处开始,您将使用特定于文件系统的代码。
So the VFS doesn't really bother "identifying" the filesystem which a file lives on; it simply uses the table of "file operation" function pointers which is stored in its struct file
. When that struct file
is initialized, it is given the correct f_op
function pointer table which implements all the filesystem-specific operations for its filesystem.
所以VFS并不真正打扰“识别”文件所在的文件系统;它只是使用存储在其struct文件中的“文件操作”函数指针表。初始化该结构文件时,会为其提供正确的f_op函数指针表,该表实现其文件系统的所有特定于文件系统的操作。
#2
0
Each filesystem registers itself to VFS. When a filesystem is mounted, its superblock is read and VFS superblock is populated with this information. Function pointer table for this filesystem is also populated at this time. when file->f_op->read call happens, registered function from the filesystem is actually called. You can refer to text in http://www.science.unitn.it/~fiorella/guidelinux/tlk/node102.html
每个文件系统都将自己注册到VFS。安装文件系统时,将读取其超级块,并使用此信息填充VFS超级块。此时还会填充此文件系统的函数指针表。当file-> f_op->读取调用发生时,实际调用文件系统中的注册函数。您可以参考http://www.science.unitn.it/~fiorella/guidelinux/tlk/node102.html中的文字。