static int __block_prepare_write(struct inode *inode, struct page *page,
unsigned from, unsigned to, get_block_t *get_block)
中有如下代码:
if (!page->buffers)
create_empty_buffers(page, inode->i_dev, blocksize)
head = page->buffers
bbits = inode->i_sb->s_blocksize_bits
block = page->index <<(PAGE_CACHE_SHIFT - bbits)
for(bh = head, block_start = 0bh != head || !block_start
block++, block_start=block_end, bh = bh->b_this_page) {
if (!bh)
BUG()
block_end = block_start+blocksize
if (block_end <= from)
continue
if (block_start >= to)
break
if (!buffer_mapped(bh)) {
err = get_block(inode, block, bh, 1)
if (err)
goto out
if (buffer_new(bh)) {
unmap_underlying_metadata(bh)
if (Page_Uptodate(page)) {
set_bit(BH_Uptodate, &bh->b_state)
continue
}
if (block_end >to)
memset(kaddr+to, 0, block_end-to)
if (block_start <from)
memset(kaddr+block_start, 0, from-block_start)
if (block_end >to || block_start <from)
flush_dcache_page(page)
continue
}
}
对unmap_underlying_metadata 的意义不是特别明确, 注释说是释放潜在的bh. 实现是从hash中找到bh代表的设备上, bh-->blocknr 那个块的oldbh, 如果有的话把它释放.
奇怪的是,既然是新分配的,为什么在hash中能找到? 如果hash中本来就有, 需要新分配吗?
/*
* We are taking a block for data and we don't want any output from any
* buffer-cache aliases starting from return from that function and
* until the moment when something will explicitly mark the buffer
* dirty (hopefully that will not happen until we will free that block -)
* We don't even need to mark it not-uptodate - nobody can expect
* anything from a newly allocated buffer anyway. We used to used
* unmap_buffer() for such invalidation, but that was wrong. We definitely
* don't want to mark the alias unmapped, for example - it would confuse
* anyone who might pick it with bread() afterwards...
*/
static void unmap_underlying_metadata(struct buffer_head * bh)
{
struct buffer_head *old_bh
old_bh = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size)
if (old_bh) {
mark_buffer_clean(old_bh)
wait_on_buffer(old_bh)
clear_bit(BH_Req, &old_bh->b_state)
/* Here we could run brelse or bforget. We use
bforget because it will try to put the buffer
in the freelist. */
__bforget(old_bh)
}
}
我要没记错:block
是块,这个是系统文件系统的最小分配单位,注意是系统的,不是硬件的。
这个block
是看文件系统建立时的设置情况,类似于
Windows
下面所说的簇。
这个是在格式化系统时进行设置,具体多大看文件系统,我记得现在默认都是
4k
。至少
Ext3
默认是
4k
。而且
block
大小和磁盘最大限制有关系的,如果你用
4k
,ext3
极限最高
16T
,也就是
4k
*
2^32
,如果你用
1k
,那么就缩小到了
4T。
其他场合,block
同样也是最小分配单位的意思,但有些仅限于当作一个“计量单位”来使用。当作计量单位时,好像一般都是
1k。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)