from 3.9.4
1.
static ssize_t generic_perform_write(struct file *file,
struct iov_iter *i, loff_t pos)
{
...
copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
if (unlikely(copied == 0)) {<----------为何有不能复制的情况?
/*
* If we were unable to copy any data at all, we must
* fall back to a single segment length write.
*
* If we didn't fallback here, we could livelock
* because not all segments in the iov can be copied at
* once without a pagefault.
*/
bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
iov_iter_single_seg_count(i));
goto again;
}
....
}
2.
为何读时有2种方式:基于page和基于缓冲,但是写时仅有基于缓冲的?
3.
调用unmap_underlying_metadata是要处理此块的alias问题,可是为何只对new的bh才做此处理?
觉得只要dirty的都该做此处理啊?可是代码中可见都是判断new,然后做unmap处理!
if (buffer_new(bh)) {
/* blockdev mappings never come here */
clear_buffer_new(bh);
unmap_underlying_metadata(bh->b_bdev,
bh->b_blocknr);
}
另外,普通文件的读写和块设备之间是否有类似上述alias问题的关联?
因为我觉得:读写普通文件时,应该不会操作块设备的address space啊。。。
4.
int __block_write_begin(struct page *page, loff_t pos, unsigned len,
get_block_t *get_block)
{
...
if (block_end <= from || block_start >= to) {
if (PageUptodate(page)) {
if (!buffer_uptodate(bh))
set_buffer_uptodate(bh);<-----------------从page同步到bh的:除了page是新建的case外还有其它case能这么同步么?
}
...
}