2013年(22)
分类: LINUX
2013-08-04 18:32:42
1.page读
do_mpage_readpage()
bio_add_page() //将page加入到bio时,page必须先被锁住,bio读操作执行的过程中page都是被锁住的
mpage_bio_submit()
bio->bi_end_io = mpage_end_io_read;
mpage_end_io_read()
if (uptodate) {
SetPageUptodate(page); //读成功,置UPTODATE标志
} else {
ClearPageUptodate(page);
SetPageError(page); //读失败,置pageError标志
}
unlock_page(page); //无论是否成功,都需要解锁
2.page写
__mpage_writepage()
bio_add_page()
set_page_writeback(page); //置WRITEBACK标志
unlock_page(page); //解锁,bio写操作执行的过程中page没有被加锁
mpage_bio_submit()
bio->bi_end_io = mpage_end_io_write;
mpage_end_io_write()
if (!uptodate){
SetPageError(page); //写失败,置pageError标志
}
end_page_writeback(page);
test_clear_page_writeback(page) //无论是否成功,都需要清WRITEBACK标志
3.buffer异步读
block_read_full_page()
BUG_ON(!PageLocked(page)); //异步读buffer时,page必须先被锁住,buffer在异步读的过程中,buffer和page都是加锁的
lock_buffer(bh); //锁buffer
mark_buffer_async_read(bh);
bh->b_end_io = end_buffer_async_read;
set_buffer_async_read(bh);
submit_bh()
end_buffer_async_read()
if (uptodate) {
set_buffer_uptodate(bh); //读成功,置UPTODATE标志
} else {
clear_buffer_uptodate(bh); //读失败,清buffer的UPTODATE标志
SetPageError(page); //读失败,置pageError标志
}
clear_buffer_async_read(bh);
unlock_buffer(bh); //无论成功失败,都解锁buffer
if(page中的buffer都完成了异步读)
unlock_page(page); //如果page中的buffer都完成了异步读,解锁page
4.buffer异步写
__block_write_full_page()
BUG_ON(!PageLocked(page)); //异步写buffer提交时,必须先加锁page
lock_buffer() //锁buffer
clear_buffer_dirty(bh) //清除DIRTY标志
mark_buffer_async_write(bh);
bh->b_end_io = end_buffer_async_write;
set_buffer_async_write(bh);
set_page_writeback(page); //置page的WRITEBACK标志
submit_bh(WRITE, bh); //提交请求
unlock_page(page); //解锁page,bio写操作执行的过程中page没有被加锁
end_buffer_async_write()
if (uptodate) {
set_buffer_uptodate(bh); //成功,置buffer的UPTODATE标志
} else {
set_buffer_write_io_error(bh); //写失败,置buffer的BH_Write_EIO标志
clear_buffer_uptodate(bh); //写失败,清buffer的UPTODATE标志
SetPageError(page); //写失败,置pageError标志
}
clear_buffer_async_write(bh);
unlock_buffer(bh); //解锁buffer
if(page中的buffer都完成了异步写)
end_page_writeback(page); //如果page中的buffer都完成了异步写,清除page的WRITEBACK标志
test_clear_page_writeback(page)
5.buffer同步读
ll_rw_block()
lock_buffer(bh); //读开始,锁buffer
bh->b_end_io = end_buffer_read_sync;
submit_bh(rw, bh);
end_buffer_read_sync()
if (uptodate) {
set_buffer_uptodate(bh); //读成功,置buffer的UPTODATE标志
} else {
clear_buffer_uptodate(bh); //读失败,清buffer的UPTODATE标志
}
unlock_buffer(bh); //读完毕,解锁buffer
6.buffer同步写
ll_rw_block()
lock_buffer(bh); //写开始,锁buffer
bh->b_end_io = end_buffer_write_sync;
submit_bh(rw, bh);
end_buffer_write_sync()
if (uptodate) {
set_buffer_uptodate(bh); //写成功,置buffer的UPTODATE标志
} else {
set_buffer_write_io_error(bh); //写失败,置buffer的BH_Write_EIO标志
clear_buffer_uptodate(bh); //写失败,清buffer的UPTODATE标志
}
unlock_buffer(bh); //写完毕,解锁buffer
总结:
1.page在回写的过程中(page_writeback置位)不会加锁,因此可以在page回写的过程中修改page的内容.
2.buffer无论是异步读写还是同步读写,操作开始时加锁,完成后解锁.
3.buffer异步读时,需要锁page.buffer异步写时,需要对page的WRITEBACK标志置位.而buffer同步读写时不影响page的加解锁和标志位.