免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: qtdszws

映射的冲突 [复制链接]

论坛徽章:
0
发表于 2007-06-20 19:26 |显示全部楼层
原帖由 思一克 于 2007-6-20 18:58 发表于 20楼  
我是问
"则读写是以page为单位的而不是以block为单位的,所以不需要buffer_head
"


哦,这个是因为对于以regular file方式打开的文件的,读写的时候kernel以page为单位管理page cache,这个时候一个页不会被分成多个block,所以就没有对应的buffer_head结构。
我不太清楚2.4内核的时候是否也如此,但2.6内核的时候是这样的。

论坛徽章:
0
发表于 2007-06-20 19:44 |显示全部楼层
没有bh的原因是block的大小等于page大小.

你前边说linux ext2 block大小一般是1024. 不是的, 一般是4096.

原帖由 zx_wing 于 2007-6-20 19:26 发表于 21楼  


哦,这个是因为对于以regular file方式打开的文件的,读写的时候kernel以page为单位管理page cache,这个时候一个页不会被分成多个block,所以就没有对应的buffer_head结构。
我不太清楚2.4内核的时候是否 ...

论坛徽章:
0
发表于 2007-06-20 20:32 |显示全部楼层
原帖由 思一克 于 2007-6-20 19:44 发表于 22楼  
没有bh的原因是block的大小等于page大小.

你前边说linux ext2 block大小一般是1024. 不是的, 一般是4096.


>>没有bh的原因是block的大小等于page大小.

我想不是这样的,这个可以通过源码来证明。以读为例子,我们从regluar file的read操作中和page cache打交道的函数do_generic_mapping_read()开始(这里只列出了和page cache相关的函数):
do_generic_mapping_read() --->find_get_page() ---->radix_tree_lookup() ---->__lookup_slot()
上述就是read操作在page cache中查找对应page的过程,整个过程中我们可以看出,kernel是以radix_tree_node 这个结构来管理以页为单位的page cache的,它是直接查找radix树,不涉及到buffer page(也就是包含bh结构的page)。
对于bh存在的理由,我们用一段ULK上的话来解释:

  1. In old versions of the Linux kernel, there were two different main disk caches: the page cache, which stored whole pages of disk data resulting from accesses to the contents of the disk files, and the buffer cache , which was used to keep in memory the contents of the blocks accessed by the VFS to manage the disk-based filesystems.

  2. Starting from stable version 2.4.10, the buffer cache does not really exist anymore. In fact, for reasons of efficiency, block buffers are no longer allocated individually; instead, they are stored in dedicated pages called "buffer pages ," which are kept in the page cache.

  3. [color=Red]Formally, a buffer page is a page of data associated with additional descriptors called "buffer heads ," whose main purpose is to quickly locate the disk address of each individual block in the page. In fact, the chunks of data stored in a page belonging to the page cache are not necessarily adjacent on disk[/color]
复制代码

可以看出,bh的主要目的在于一个page中包含的block在disk不相邻的情况。这种不相邻的情况就是我说的文件的hole(对于regular file)。

此外,我的印象中记得linux默认的block是1024字节,但刚才查了查资料又看看了源码,没有找到证明。版主说是4k,什么地方能查到呢?我认为4k的block对于设备来说太大了,因为DMA操作多以segment为单位,一个segment包含多个sector。硬件规定了segment中的sector必须物理上连续,所以如果一个block太大的话,包含不连续sector的概率就会增大,这样很可能一个次I/O要拆分成多次dma,毕竟block是VFS管理文件的单位。

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
发表于 2007-06-20 20:56 |显示全部楼层
原帖由 qtdszws 于 2007-6-20 17:47 发表于 15楼  
塑料袋 2.4.32中
2)...但是只有块设备文件的page所关联的buffer_head,才能进入buffer_head的hash表...

没找到具体的代码,能否指定一下



见grow_buffers函数


所有增加buffercache的操作,归根到底是要调用grow_buffers。这个应该没疑问。

grow_buffers在2.4.32的实现是以( block_device->bd_inode->i_mapping,index)为唯一索引,搜索pagecache,在pagecache中找到或者创建一个,属于块设备文件的缓存页,然后将这个page上关联的buffer_head哈希之。

由此可见,所有hash表中的buffer_head所占用的内存空间,是块设备文件页缓存的子集;极端条件下,两者相等。

论坛徽章:
0
发表于 2007-06-20 21:08 |显示全部楼层
原帖由 塑料袋 于 2007-6-20 20:56 发表于 24楼  



见grow_buffers函数


所有增加buffercache的操作,归根到底是要调用grow_buffers。这个应该没疑问。

grow_buffers在2.4.32的实现是以( block_device->bd_inode->i_mapping,index)为唯一索引 ...

在2.4中,用文件方式读写而不用打开设备文件的方式读写,也会调用到 grow_buffers分配buffer page吗?

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
发表于 2007-06-20 21:17 |显示全部楼层
原帖由 zx_wing 于 2007-6-20 21:08 发表于 25楼  

在2.4中,用文件方式读写而不用打开设备文件的方式读写,也会调用到 grow_buffers分配buffer page吗?


没看明白,你是指的:
文件方式读写==读写regular文件
打开设备文件方式读写==读写块设备文件??

论坛徽章:
0
发表于 2007-06-20 21:24 |显示全部楼层
原帖由 塑料袋 于 2007-6-20 21:17 发表于 26楼  


没看明白,你是指的:
文件方式读写==读写regular文件
打开设备文件方式读写==读写块设备文件??

是的,是的是的是的是的是的是的(不好意思,10字限制)

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
发表于 2007-06-20 21:42 |显示全部楼层
无论怎么写文件,都不会调用grow_buffers。只有那些诸如ext2_get_block,ext2_unlink,ext2_alloc_branches......这些以文件系统的管理为目的的函数才会直接调用getblk---->grow_buffers。

不论写什么文件,2.4.32都是直接写在pagecache里的某一page上,然后将这个page关联上buffer_head结构,仅只是buffer_head结构,而不包括那1024的空间。将buffer_head记bh_dirty或submit_bh后就返回了。

假设你写的块设备文件,那么到现在为止,page关联的buffer_head并不属于buffercache,并没有对buffer_head进行hash,他们只在lru链和b_this_page链。

只有当getblk要查找某一buffer_head时:
1:先在buffercache中查找;
2:查找失败,则将目标buffer_head的(k_dev,nr)换算成(block_device->i_mapping,index),到pagecache中查找/创建对应页。这时就找到了你刚才所写的page。
3:将你刚才所写的page所关联的buffer_head进行hash,进入buffercache

论坛徽章:
0
发表于 2007-06-20 21:54 |显示全部楼层
原帖由 塑料袋 于 2007-6-20 21:42 发表于 28楼  
无论怎么写文件,都不会调用grow_buffers。只有那些诸如ext2_get_block,ext2_unlink,ext2_alloc_branches......这些以文件系统的管理为目的的函数才会直接调用getblk---->grow_buffers。

不论写什么文件 ...

谢谢,明白了
这样看来,2.4中的page cache都会被分成block,然后和bh关联

[ 本帖最后由 zx_wing 于 2007-6-20 22:00 编辑 ]

论坛徽章:
0
发表于 2007-06-21 12:19 |显示全部楼层
原帖由 塑料袋 于 2007-6-20 21:42 发表于 28楼  
无论怎么写文件,都不会调用grow_buffers。只有那些诸如ext2_get_block,ext2_unlink,ext2_alloc_branches......这些以文件系统的管理为目的的函数才会直接调用getblk---->grow_buffers。

不论写什么文件 ...


是否可以说,
在v2.4.0中,对普通文件的读写的buffer_head不进入hash,对设备文件的读写和文件系统的metadata进行读写的buffer_head进入hash
在v2.4.32中,对普通文件的读写和对设备文件的读写的buffer_head都不进入hash,只有对文件系统的metadata进行读写的buffer_head才进入hash
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP