读书人

文件系统的深度剖解

发布时间: 2012-09-19 13:43:54 作者: rapoo

文件系统的深度剖析

内核中用结构体struct file表示打开的文件,有标示文件位置的变量,还有文件引用数,文件锁等。而各个进程用结构体files_struct表示进程打开的文件,其中的成员fd是struct file **,而fd指向的是一个数组,数组里每个成员存放的是file的指针,也就是说,打开的文件的结构体在内核中就一份,但是各个成员可以都拥有它的指针,这个指针是放在各自进程的fd指向的属于该进程的数组某个元素里的。

当某个文件被某个进程第一次打开时:1)内核会创建一个结构体file的实例来描述该文件2)用户空间根据设备节点(/dev/xxx)找到对应的主次设备号,并把主次设备号传入内核,在内核中会把根据主次设备号找到对应的inode。如果inode的i_cdev或i_bdev非空,则把inode->i_cdev->ops或inode->i_bdev->ops赋值给file的f_op,否则把inode的i_fop(缺省文件操作)初始化file的f_op(可参看chrdev_open)(块设备是在设备挂载后根据设备读写情况动态创建或注销inode的,字符设备是在注册设备驱动时创建inode而注销驱动时注销inode的,inode保存有设备文件的属性,而且i_cdev或i_bdev会指向相应的驱动程序。)3)修改file对象的应用计数,同时把它的指针存放到该进程的files_struct实例的成员fd指向的数组的最低可用元素中。如果该文件不是首次打开,则会根据读写锁来运行第三步。

当成功打开文件后,对文件进行读写时,通过系统api的调用,传入内核的是文件描述符,内核中调用对应的系统函数,根据文件描述符,到属于该进程的struct_file的fd指向的数组中找到对应的file指针,从而调用file的f_op的某个成员函数。从而通过驱动实现硬件与内核的IO操作。

文件读写位置由file里的f_pos描述,且读写公用。

C库里的API是对系统API的封装,FILE是对文件描述符在用户空间的一个封装,主要是在用户空间多了一个缓冲区,而分别用读写指针来表示缓冲区当前时刻那一部分属于读的缓存哪一部分属于写的缓存。通过C的API、FILE *对文件读写定位仍然操作的是file里的f_pos,读写仍然是公用f_pos标示位置。用户空间的那个缓冲区读写位置是自动的,这个缓冲区的作用主要是减少系统调用次数,平时说的scanf匹配也是在这个缓冲区里读匹配,printf也是首先写到这个缓冲区,遇到换行符才写进内核进而写到设备。

另外,每个进程还有一个fs_struct表示进程当前的目录项,根目录项等信息。

读书人网 >其他相关

热点推荐