读写函数中的lock_page
2016-12-30
do_generic_file_read和generic_perform_write中对锁的处理.
从磁盘读到RAM中的过程中, page需要处于lock状态.
把用户的数据拷贝到page cahe, 该过程也要处理好lock page问题.
从磁盘读到RAM中的过程中, page需要处于lock状态.
把用户的数据拷贝到page cahe, 该过程也要处理好lock page问题.
1. do_generic_file_read中的lock page
linux-3.10.86/mm/filemap.c
do_generic_file_read
{
if (!PageUptodate(page)) {
if ( ... || !mapping->a_ops->is_partially_uptodate)
goto page_not_up_to_date;
unlock_page(page);
}
page_not_up_to_date:
error = lock_page_killable(page);
page_not_up_to_date_locked:
...
/* Start the actual read. The read will unlock the page. */
error = mapping->a_ops->readpage(filp, page);
if (!PageUptodate(page)) {
/*
a_ops->readpage会立刻返回吗?
答:是的, 通常是submit_bh或submit_bio后就返回了,
所以, lock_page_killable()就是在
等a_ops->readpage中的设置的I/O completion handler的unlock.
比如end_buffer_async_read中的unlock_page();
*/
error = lock_page_killable(page);
...
}
}
- 读的发起者 lock_page
- 读的发起者 a_ops->readpage()
- 读的发起者不必unlock_page, 而是由io complete handler来完成.
2. generic_perform_write 填充page cache
generic_perform_write
{
a_ops->write_begin(...); //这里面lock_page
...
copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
...
a_ops->write_end(...); //这里面unlock_page
}
block_write_begin
{
page = grab_cache_page_write_begin(mapping, index, flags); //内有lock page
}
ext2_write_end -> generic_write_end()
{
...
/* 填好page cache, 剩下是write back的事了*/
unlock_page(page);
}
3. write_cache_pages 回写
linux-3.10.86/mm/page-writeback.c
write_cache_pages
{
while (...) {
nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1);
if (nr_pages == 0)
break;
...
lock_page(page);
...
/*常见的有__mpage_writepage 或者 __writepage*/
ret = (*writepage)(page, wbc, data);
}
__block_write_full_page
{
/*
问题:这个是和哪里对应的?
答:
write_cache_pages
|--lock_page
|--writepage -> __writepage -> ext2_writepage -> block_write_full_page -> block_write_full_page_endio -> __block_write_full_page
*/
unlock_page(page);
}
4. more ...
Documentation/filesystems/Locking
本文地址: https://awakening-fong.github.io/posts/io/read_write_lock_page
转载请注明出处: https://awakening-fong.github.io
若无法评论, 请打开JavaScript, 并通过proxy.
blog comments powered by Disqus