2012年(11)
分类: LINUX
2012-09-16 15:41:32
虚拟文件系统(VFS)在文件系统的上一层,它封装了文件系统的实现,对于VFS更上一层来说,就不用知道操作的是何种具体的文件系统了。
我们知道真正存放信息的是储存媒介(如磁盘)
文件系统相当于媒介储存信息的协议(ext3、ntfs等)
所谓mount指的是使用某种文件系统去操作储存媒介
我们关心某个文件中的内容,但是对文件本身的信息(如创建日期、权限、大小)等也感兴趣,这些信息成为file metadata,在VFS中用inode(index node)结构体表示,每个文件只有唯一的一个inode。
文件系统也有相应的描述信息,VFS中用superblock超级块结构体来表示。
目录在VFS中是一种特殊的文件,用dentry(directory entry)结构体来表示。
总的来说,VFS关心以下几种结构体:
The superblock object represents a specific mounted filesystem.
The inode object represents a specific file.
The dentry object, which represents a directory entry, is a single component of a path.
The file object represents an open file as associated with a process.
注意这里的file指的不是文件系统中的某一个文件,而是在一个进程中打开的文件,可以想象成是文件描述符。一个文件可以被多个进程打开,从而有多个file结构体,但是inode只有一个。每当一个文件被一个进程打开就需要一个file的一个可能的原因是,假设多个进程都在读一个文件中的内容,若每个都有file结构,那每个进程读取的位置都可以不一样。
对上述这几种结构体的操作为:
The super_operations object contains the methods that the kernel can invoke on a specific filesystem, such as write_inode() and sync_fs()
The inode_operations object contains the methods that the kernel can invoke on a specific file, such as create() and link()
The dentry_operations object contains the methods that the kernel can invoke on a specific directory entry, such as d_compare() and d_delete()
The file_operations object contains the methods that a process can invoke on an open file, such as read() and write()
具体的结构体成员和操作函数就不列举了。
一个进程保存着已打开的文件和文件系统信息——files_struct, fs_struct。
• 块设备
VFS是高层,这里再从底层讲起。VFS的下层是真实的文件系统,真实的文件系统下面是block IO层,接着下面是块设备驱动层,最下面是真实某种块设备。块设备是指可以随机读写访问,并且每次最小只能访问固定数量的数据。硬件的最小单位是扇区sector(通常512字节或更大)。
与字符设备的file_operations结构体一样,块设备对上层也有统一的接口,用block_device_operations结构体表示。对于内核来说,块设备只是一块块sector的数据,不同的文件系统对这些数据有着不同的操作方法。
块设备驱动要实现一个request的方法:
void request(request_queue_t *queue);
每当需要对块设备进行读写等操作的时候就会调用这个方法,所以它是块设备操作的源头。每个块设备有一个request队列,为了提高块设备的有效性,每个读写操作的request都加入这个队列,并在队列中按一定算法进行reordering(比如将几个连续地址的间隔读操作request放在一起)。
这种reordering的算法称为block IO rescheduler(也有叫elevator的)。算法的一种思路是“deadline scheduler”,它为每个request设置deadline,在deadline之前必须完成;另一种思路是“anticipatory scheduler”,它假设对连续sector的操作紧接着当前的操作。
request是用一种叫bio的数据结构来描述的。也就是说,VFS或者某个文件系统要对块设备进行操作时,将该操作用bio来描述,bio包括了操作所需的相关信息。块IO层会对bio新建一个request或者合并到某一个现有的request中去。
• 页缓存
为避免频繁的磁盘访问,从而提出了页缓存。
页缓存的回写策略有:
若写,则直接写磁盘,并标志页无效
若写,则不光写磁盘,而且写(更新)写,这个叫write-through
若写,则写页,不立即写磁盘,标记页为dirty(其实指的是磁盘上的数据为dirty),并将dirty的页放入dirty页list,周期性的回写至磁盘(相关的flusher内核线程来做),这个叫write-back
一个页(page)可以缓存多个磁盘上的block,因为一个page通常为4KB,磁盘上的一个block可能只有512B。一个文件在页缓存上的描述用struct address_space来表示。
详细查看mmap应用。