最近一段时间一直在做一个块设备模块的性能分析、优化工作,因此,对Linux文件系统层的代码进行了初略的阅读,颇有心得。Linux的文件系统的确非常庞大,层次也非常清晰。以前一直将注意力集中在了设备管理的层面,所以,通过这次的阅读分析,可以从用户程序的system call开始,将读写请求整个贯穿到底层硬件的DMA。下面对块设备与文件系统之间的接口关系进行阐述,主要解决“文件系统是如何访问块设备的?”这个问题。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
块设备可以在两种情况下发起probe过程,一是当总线驱动发现了块设备,回调该块设备驱动的probe函数,例如磁盘设备的驱动;二是驱动程序主动probe块设备,例如软RAID驱动程序,在insmod该程序后,会主动调用probe函数。Probe函数是设备驱动程序的核心函数,对于一类设备驱动而言,该函数的实现方式是雷同的,具有固定的格式。
在块设备的probe过程中,首先需要例化一个对象——gendisk,该对象在内核中对块设备进行了抽象。Gendisk对象初始化成功之后调用add_disk()函数将gendisk添加到系统中,在add_disk过程中需要生成bdev_inode结构,该结构维护了一个文件系统所需的inode节点,以及块设备的更高层次抽象bdev。该结构描述如下:
struct bdev_inode {
struct block_device bdev; //块设备
struct inode vfs_inode; //文件系统inode节点
};
如下图所示,在inode节点中一系列ops指针,指向具体的操作函数集。如果inode描述的是一个块设备,那么ops函数集指向标准的块设备操作函数集。当用户open一个块设备时,会找到对应的inode,生成一个file对象,并且将inode中的file_operations(i_op)赋值给file对象中的f_op,从而建立了文件系统接口与块设备之间的接口。如果inode描述的是一个文件系统,那么inode中的操作函数集将指向文件系统具体的操作函数集。从这个思路来看,inode是vfs层的接口,block device是一个特殊的文件系统,具体文件系统在注册时,需要将回调的方法注册到inode中。/fs/Block_dev.c文件就是block device这一特殊文件系统的具体实现,其中实现了与文件系统之间接口的各种函数,包括file_operations函数集。大家感兴趣不妨研究一下。
ash_riple_768180695 2009-3-11 17:36