19日目

19日目はtypeコマンドやアプリケーションの実行がテーマ。そのためにはファイル内容を取得する関数を作らねば。


以下がその関数。iノードポインタを受け取ってファイル内容を先頭からsizeバイトbufに書きこみ書き込んだバイト数を返す。

static int ext2_loadfile(struct ext2_inode* ptr_inode, int size, char *buf)
{
	size_t blocksize;
	size_t readsize;
	int depth;
	__le32* i_block;
	int i, block_no, bytes;
	int offsets[4];

	int boundary;	// ダミー
	struct ext2_super_block* ptr_sb;

	readsize = (ptr_inode->i_size < size)? ptr_inode->i_size : size; 

	ptr_sb = EXT2_SB;
	blocksize = EXT2_BLOCK_SIZE(ptr_sb);

	block_no = 0;
	bytes = 0;

	for(;;){
		// block_noに対するオフセットを取得
		depth = ext2_block_to_path(ptr_sb, block_no++, offsets, &boundary);
		
		// ブロックを取得
		i_block = ptr_inode->i_block;
		for(i = 0; i < depth; i++){
			i_block = ((void*)ptr_sb + blocksize * (i_block[offsets[i]] -1));
		}

		// ブロック内容を取得
		memcpy(	&buf[bytes], i_block, (blocksize < readsize)? blocksize : readsize);
		if( blocksize < readsize){
			bytes += blocksize;
			readsize -= blocksize;
		} else {
			bytes += readsize;
			break;
		}
	}

	return bytes;
}

ext2の多段ブロック構造*1に対応するためext2_block_to_path(Linuxソースより拝借)で各ブロック配列に対するオフセットを取得し、そのオフセットをたよりに間接ブロックのリンクをたどり目的のブロック(i_block)を得るというつくり。

ファイルブロックがブロックグループ1以降にある場合には対応できてない、というあいかわらずいいかげんなコードだけどファイルシステムのサイズ小さいし当面問題ないであろう。

*1:ここ参照