Final Year Project:
Using Linux Filesystems Under Windows
Chris Bryden
BEng. Electronics and Software Engineering
School of Computer Science
University of Birmingham
42
contained within this group. To calculate the exact block required, the inode
offset is divided by the number of inodes per block, this gives a block offset
within the inode table. This result is added to the bg_inode_table value to
produce the final block address of the block containing the required inode.
The block containing the inode can now be read into a memory buffer
using the ReadBlock function. To aid performance the GetInode function caches
the last block that was read by the previous call to the function. If the next inode
is from the same block, no disk read is necessary as the block is already cached
in memory and can be reused.
The final task for this function to perform is copying the specified inode
from the block buffer to the Inode variable. The byte offset off the required inode
within the buffered block has to be calculated, however. This is achieved as
shown below:
The first result that is required is the number of inodes that are in the buffered
block before the required inode. This is calculated by first determining the
number of blocks in the inode table that lie before the buffered block. This is
achieved by subtracting the block address of the beginning of the inode table,
bg_inode_table, from the block address of the buffered block, ulBlock. This result
is then multiplied by the number of inodes per block, ulInodesPerBlk, to give the
number of inodes that lie in the blocks before the buffered block. This result is
then subtracted from the inode offset, ulINodeOffset, minus 1. This gives the
number of inodes that are in the buffered block before the required inode, the
result that is required. This is then simply multiplied by the size of an inode to
give the byte offset.
This byte offset is then used to copy the desired inode from the block
buffer into the Inode structure.
5.15 Layer 1: The GetBlockList Function
This function is used to read the complete list of block addresses for the
blocks that are allocated by a particular inode. These are the direct blocks,
contained within the inode itself, and also the indirect, double indirect and triple
indirect blocks. The function reads the list of block addresses into a memory
buffer and returns a pointer to this buffer, lpBlocksBuff. The memory required for
the block buffer is dynamically expanded according to how many block
addresses are read into it and an offset, ulBuffOffset, (measured in unsigned
//calculate offset of desired inode within buffered block
ulBlkOffset = sizeof(INODE) * (ulInodeOffset - 1 -
((ulBlock - GroupDesc.bg_inode_table) * ulInodesPerBlk));