mapping 关系

linux中i_rdev i_bdev i_mapping 关系

i_bdev只有块设备文件系统的inode会设置该属性,对应的是块设备的数据结构

i_rdev 通过mknod创建的inode都会指定设备号

一个块设备可以通过mknod创建多个具有相同i_rdev的inode,那么在访问这些inode的时候,具体对应的块设备是i_bdev指定的,这和普通的文件系统是不一样的,普通文件系统只使用sb中记录的s_bdev。所有使用相同设备号创建的inode的i_mapping属性都是相同的,他们等于inode->i_mapping = bdev->bd_inode->i_mapping。inode的i_bdev开始可能是空的,在blkdev_open函数中会调用bd_acquire函数,这里面会根据i_rdev值调用bdget函数,该函数会调用iget5_locked在块文件系统的超级块blockdev_superblock中查找对应的inode,获取bdev_inode的bdev属性,并设置inode的bdev

blkdev_get_block 和普通文件系统,例如ext2_get_block

blkdev_get_block 把bh->b_bdev 设置为inode对应的i_bdev, 而其他文件系统则使用map_bh, 把bh的b_bdev设置为sb的s_bdev,在最后调用submit_bid的时候会根据b_bdev获取设备的request_queue

在执行echo u > /proc/sysrq-trigger时执行remount_ro将系统中已经挂载的文件系统设置为只读,但在选取要设置的文件系统时有一个判断条件s_bdev是否为空,如果为空那么不设置该文件系统为只读,而网路文件系统nfs的s_bdev是为NULL的,所以这个操作对它们是无效的。

super_block的s_bdev是在mount时指定的,mount会分为两个分支mount_noblk和mount_blk,mount_noblk每次都指定的dev指针为空,所以每次都是创建新的super_block对象,而mount_blk会根据指定的dev,这个dev也是根据path查找的,查找的过程中会根据holder属性判断,是否有其他文件系统类型已经占用该dev了,这个是在全局链表上进行的,先进行查找看是否已经创建了和该dev关联的super_block对象,如果还没有则创建super_block对象,并把它加入到file_system_type对象的成员链表中,如果查找和该dev关联的super_block对象,则引用加一,并使用该super_block对象,因此同一个设备多次mount使用的是同一个super_block

如何分配唯一的ID,并且可以服用,可以参看idr和ida模块

fuse有两种类型的文件系统fuseblk和fuse,fuseblk文件系统需要指定device,而fuse类型不需要,但是使用fuse类型时bmap接口应该是不能使用的。

块文件系统和普通文件系统共用块缓存,buffer_head, buffer_head都有指针只想pagecache中的page


分享到:


相關文章: