分类: LINUX
2020-11-16 16:04:32
1.成功按页读取page,page的UPTODATE标志置位
mpage_end_io_read()
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
if (uptodate) {
SetPageUptodate(page);
}
2.异步读取buffer_head成功后,buffer_head的标志置位,如果buffer_head对应的page中所有的buffer_head都为UPTODATE,则会将page的UPTODATE标志置位
end_buffer_async_read()
if (uptodate) {
set_buffer_uptodate(bh);
}
do {
if (!buffer_uptodate(tmp))
page_uptodate = 0;
tmp = tmp->b_this_page;
} while (tmp != bh);
if (page_uptodate)
SetPageUptodate(page);
3.调用sb_bread()同步读取buffer_head成功后,buffer_head的标志置位,但不会影响对应page的UPTODATE标志,block_read_full_page()如果发现page的buffer都是UPTODATE的,直接置位page的UPTODATE标志
4.准备缓冲写时,如果PageUptodate(page)=1,则同步buffer_head跟page的UPTODATE标志
__block_prepare_write()
if (block_end <= from || block_start >= to) {//[from,to]与当前块没有交集
if (PageUptodate(page)) {
if (!buffer_uptodate(bh))
set_buffer_uptodate(bh);//同步UPTODATE标志
}
}
...
if (buffer_new(bh)) {
//page的数据是有效的,此时可以任意写入
if (PageUptodate(page)) {
clear_buffer_new(bh);
set_buffer_uptodate(bh);//同步UPTODATE标志
mark_buffer_dirty(bh);//mapped + uptodate = dirty
continue;
}
}
5.对buffer_head部分写入时,需要将未写入的部分从磁盘读出,写完毕时,置位对应buffer的UPTODATE标志,如果buffer所在page所有的buffer都是UPTODATE的,则会将page的UPTODATE标志置位
__block_commit_write()
set_buffer_uptodate(bh);
...
if (all_buffer_uptodate)
SetPageUptodate(page);
6.对page部分写入时,不能置位page的UPTODATE标志,如果page中的空洞块或EOF块的UPTODATE的标志都已置位(内容都已清零),
由上面几点可知,page和buffer的UPTODATE标志位的含义:page或buffer的内容与磁盘内容是相同的或page或buffer的内容是可以回写到磁盘的,至于有没有必要回写,由dirty标志来决定.