忘记密码   免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 4633 | 回复: 9

[内存管理] 请教buffer_head的具体作用 [复制链接]

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
发表于 2014-05-07 11:27 |显示全部楼层
个人理解buffer通常是用在需要按块进行读写或者读写的页对应的磁盘块不连续时,才使用buffer page按块进行读写。通常的读写应该都是直接通过页缓存。
但是,不解的是在write的流程中,prepare_write的时候,看似对每个page都会分配对应的buffer_head,不知为何要这样做?还大侠们指点下buffer具体的应用场景?

论坛徽章:
1
双鱼座
日期:2013-08-28 13:47:26
发表于 2014-05-07 16:36 |显示全部楼层
You do not need to write back the whole page if you can just write back the dirty part(block buffer whose buffer head with BH_Dirty flag), right?

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
发表于 2014-05-07 20:25 |显示全部楼层
回复 2# firkraag
但是正常情况下,应该都是整页回写的哦(即使写的数量小于一页),除非通过submit_bh指定块进行写


   

论坛徽章:
1
双鱼座
日期:2013-08-28 13:47:26
发表于 2014-05-08 10:28 |显示全部楼层
If the page is mapped, it will write back the whole page. But if you use the 'write' systemcall and  just write a few bytes less than a page and the page is not mapped, then it will not need
to write back the whole page.

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
发表于 2014-05-08 12:41 |显示全部楼层
ooo~
static int __block_prepare_write(struct inode *inode, struct page *page,
                unsigned from, unsigned to, get_block_t *get_block)
{
        unsigned block_start, block_end;
        sector_t block;
        int err = 0;
        unsigned blocksize, bbits;
        struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;

        BUG_ON(!PageLocked(page));
        BUG_ON(from > PAGE_CACHE_SIZE);
        BUG_ON(to > PAGE_CACHE_SIZE);
        BUG_ON(from > to);

        blocksize = 1 << inode->i_blkbits;
        /**
         * 检查某页是否是一个缓冲区页(如果是则PG_Private标志置位)。
         * 如果没有设置该标志,则调用create_empty_buffers为页中所有的缓冲区分配缓冲区首部
         */
        if (!page_has_buffers(page))
                create_empty_buffers(page, blocksize, 0);
        head = page_buffers(page);

请问为什么这里,当page不是buffer page的时候,还要为其分配buffer_head呢?照理解,正常的write不需要使用buffer,也就不需要使用buffer_head吧?如果是这样的话,那write时所有的页都需要为其分配buffer_head了?为啥?

论坛徽章:
1
双鱼座
日期:2013-08-28 13:47:26
发表于 2014-05-09 13:58 |显示全部楼层
I mean if you write to a part of a file which the corresponding page has not been loaded into the page cache and you may just write 2000 bytes. This time kernel can not find the page in the page cache,  it just allocates a page and don't load the content of the whole file page into the page(without PG_Uptodate), then add it to the page cache, it just loads the parts(BH_Mapped) which are affected by the writing action and the commitment will mark the corresponding parts of the page as dirty(BH_Dirty) and uptodated(BH_Uptodate). Of course, mark the page as dirty.

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
发表于 2014-05-10 12:05 |显示全部楼层
firkraag 发表于 2014-05-09 13:58
I mean if you write to a part of a file which the corresponding page has not been loaded into the pa ...

感谢回复~

照兄台的意思,只有当写入的内容小于一页,同时该页还没有page cache时,才会使用buffer?
那为何在prepare_write的时候,看似对所有的cache页都分配了buffer_head呢?这也是我最大的疑问

论坛徽章:
1
双鱼座
日期:2013-08-28 13:47:26
发表于 2014-05-11 09:40 |显示全部楼层
Even kernel can find the page in the page cache, if you write a part of the file, the block buffer is useful for just writing the dirty part back to the disk.  And the page you can find in the page cache may not have corresponding blocks allocated on the disk, if this happened, block buffer is needed. Although there is a flag 'PG_mappedtodisk' to indicated all corresponds blocks are allocated on the disk, they seems not to making use of it.

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
发表于 2014-05-12 18:33 |显示全部楼层
firkraag 发表于 2014-05-11 09:40
Even kernel can find the page in the page cache, if you write a part of the file, the block buffer i ...

感谢解答,后面再研究下代码~~

论坛徽章:
0
发表于 2018-07-31 10:46 |显示全部楼层
本帖最后由 zhangku0 于 2018-07-31 11:07 编辑

最近在看这一块 也觉得这部分有些奇怪
我的理解是 写出到pagecache的时候 在写出数据的首尾的位置 未必是以块对齐  这样在此块信息无效的时候 就需要读入这些并非重写整个块的块内容(在读入块的时候就需要bufferhead了) 以便于一起flush到硬盘(可以想象 如果不读入这些额外内容  写入硬盘的单位又是块  就会导致块内部分内容缺失)  

但是这么理解奇怪的是 这样只需要首尾块所在的页产生bufferhead就可以  为啥所有页都变成这样呢

另外 写入页都生成了bufferhead 是不是说明 写入过的页 都是缓冲区页?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:wangnan@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP