ext2_get_block()
Rev.4を表示中。最新版はこちら。
1. 概要
ext2fsのget_blockハンドラである。ext2_get_block()の実装まとめ。
編集中
2. 処理概要
2.1 ext2_get_block()
ext2_get_block()の処理概要
/*
* iblock番目のブロックのXXXXXXXXXをoffsetに格納して返す。
* 例えば、iblockが14の時は
* offset[0] = 12
* offset[1] = 2
* となる。(図xx参照)
*/
int depth = ext2_block_to_path(inode, iblock, offsets, &boundary);
/*
* offsetで指定されたパスを辿って
*/
partial = ext2_get_branch(inode, depth, offsets, chain, &err);
if (!partial) {
got_it:
/* 判明したディスクブロックをbh_resultに設定する */
map_bh(bh_result, inode->i_sb, le32_to_cpu(chain[depth-1].key));
if (boundary)
set_buffer_boundary(bh_result);
/* Clean up and exit */
partial = chain+depth-1; /* the whole chain */
goto cleanup;
}
if (!create || err == -EIO) {
/* create = 0なら新規割り当てはせず終了 */
cleanup:
while (partial > chain) {
brelse(partial->bh);
partial--;
}
out:
return err;
}
if (err == -EAGAIN)
goto changed;
/* 割り当て場所を決める? */
goal = 0;
if (ext2_find_goal(inode, iblock, chain, partial, &goal) < 0)
goto changed;
/* ブロックを割り当てる partialで指定した位置からIndirectが格納される*/
left = (chain + depth) - partial;
err = ext2_alloc_branch(inode, left, goal,
offsets+(partial-chain), partial);
if (err)
goto cleanup;
if (ext2_use_xip(inode->i_sb)) {
/*
* we need to clear the block
*/
err = ext2_clear_xip_target (inode,
le32_to_cpu(chain[depth-1].key));
if (err)
goto cleanup;
}
/* ei->i_next_alloc_block = block
このファイルに直近で割り当てたブロック番号(ファイル内のブロック番号)
linearly ascending allocation requestsを検出するのに使われる。
ei->i_next_alloc_goal = le32_to_cpu(where[num-1].key);
このファイルに対して直近で割り当てた物理ブロック番号
連続Request(linearly ascending)を検出した時の次の割り当て位置
*/
if (ext2_splice_branch(inode, iblock, chain, partial, left) < 0)
goto changed;
set_buffer_new(bh_result);
goto got_it;
changed:
while (partial > chain) {
brelse(partial->bh);
partial--;
}
goto reread;
2.2 ext2_block_to_path()
int ext2_block_to_path(*inode, i_block, offsets[4], *boundary)ext2fsではi-node内にファイル内のブロックがディスク上のどこに存在しているのかブロック番号を格納したテーブルがある。ただしこのテーブルはファイル内の#0〜11番目のブロックのみしか格納しておらず、それ以降のブロックについてはテーブルが別のディスクブロックに格納されているので、ディスクブロックをたどって(間接参照)いく必要がある(「Ext2 FS」参照)。
ext2_block_to_path()はinodeで指定されたファイル内のi_block番目のブロックへアクセスするためのパスをoffsetに返す。

図2.1 offsetとchain

図2.2 ブロックの間接アクセス
