set_buffer_new
2016-12-31
本文主要解释BH_New的含义, 以及何时设置该标志.
1. set_buffer_new
linux-3.10.86/fs/ext2/inode.c
static int ext2_get_blocks(struct inode *inode,
sector_t iblock, unsigned long maxblocks,
struct buffer_head *bh_result,
int create)
{
/*
在查找@iblock的过程中, 遇到了指向块0的情况.
比如ext2_get_blocks()查找iblock为6的映射,
结果ext2_inode的i_data[5]==0
假定文件的0-21块都是hole:
ext2_get_blocks()中查找@iblock为20,
i_data[12]==0, 那么, 会set_buffer_new;
下回查找@iblock为21, i_data[12]!=0,
不过, i_data的下一级, offset为8的地方, 还是0 ,
所以, 依旧set_buffer_new.
也就是说, 查找@iblock为20, 只触发1次set_buffer_new, 而不是2次,
因为是在分配好chain所需的块后, 才调用一次set_buffer_new.
然后查找@iblock为21, 会触发1次set_buffer_new;
问题:buffer_new()意味着什么?
答:意味着, 将原先还不属于文件系统的块, 划分给了文件系统.
*/
set_buffer_new(bh_result);
got_it:
...
}
2. unmap_underlying_metadata
__block_write_begin
{
...
err = get_block(inode, block, bh, 1); //比如ext2_get_blocks
if (err)
break;
if (buffer_new(bh)) {
unmap_underlying_metadata(bh->b_bdev,
bh->b_blocknr);
...
}
}
/*
__block_write_full_page
{
create_page_buffers //这里没有从裸块设备的地址空间中查找
unmap_underlying_metadata
}
*/
void unmap_underlying_metadata(struct block_device *bdev, sector_t block)
{
struct buffer_head *old_bh;
might_sleep();
old_bh = __find_get_block_slow(bdev, block);//从裸块设备的地址空间中查找
if (old_bh) {
clear_buffer_dirty(old_bh);
/*
问题:这里没有获取锁, 只是等待他人把锁释放掉, 意义何在?
答:让两者不要相互干扰.
*/
wait_on_buffer(old_bh);
clear_buffer_req(old_bh);
...
}
}
本文地址: https://awakening-fong.github.io/posts/io/set_buffer_new
转载请注明出处: https://awakening-fong.github.io
若无法评论, 请打开JavaScript, 并通过proxy.
blog comments powered by Disqus