generic_perform_write流程
2016-12-31
generic_perform_write
{
/*
==0==计算没有和PAGE_CACHE_SIZE对齐的那部分的大小, 代码中的bytes.
杂问题:
假定PAGE_CACHE_SIZE为4, pos为5, iov_iter_count()大于2个PAGE_CACHE_SIZE,
则offset为1, bytes为3
所以, 代码中的bytes就是示意图中|///|那部分:
pos==0 pos==5
^ ^
| |
|----| |-.---| |----|
|///|
读取
*/
offset = (pos & (PAGE_CACHE_SIZE - 1));
bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
iov_iter_count(i));
again:
/*
如何防止dead lock可参考
https://lkml.org/lkml/2015/6/30/631
*/
iov_iter_fault_in_readable(...);
/*
==1==准备page
答:
如果在address_space中没有该pos对应的page, 则分配page并添加到address_space.
如果没有写完整的一个sector, 则需要先从磁盘读出原sector.
*/
status = a_ops->write_begin(file, mapping, pos, bytes, flags,
&page, &fsdata);
/*
==2==填充page cache
*/
/*
flush_dcache_page 见https://awakening-fong.github.io/posts/flush_dcache_page
*/
if (mapping_writably_mapped(mapping))
flush_dcache_page(page);
pagefault_disable();
copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
pagefault_enable();
flush_dcache_page(page);
/*
==3==标记为dirty, 处理short write
short wrtie是让 copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);复制bytes, 结果实际只复制copied. 若发生short write, 则重来.
*/
a_ops->write_end(...);
}
本文地址: https://awakening-fong.github.io/posts/io/generic_perform_write
转载请注明出处: https://awakening-fong.github.io
若无法评论, 请打开JavaScript, 并通过proxy.
blog comments powered by Disqus