John's spec of the second extended filesystem
This information has been compiled from resources published on the internet, the Linux kernel source and information gained from experimentation. Introduction minix -> extend fs -> 2nd extended Structure The file system is created from a sequential collection of blocks. These blocks can be either 1k, 2k or 4k in size. These blocks are divided up into groups for various reasons. The starting point for the filesystem is the superblock. This is a structure 1024 bytes in length and is always located at an offset of 1024 bytes from the start of the filesystem. The following is a list of the structure used by Linux. Note that other OS's (like hurd) may use a slightly different structure. For details see ???.h
s_r_blocks_count : s_first_data_block : s_log_block_size : s_log_frag_size : s_blocks_per_group s_inodes_per_group s_mtime, s_wtime s_mnt_count, s_max_mnt_count s_magic s_state s_errors s_creator_os s_rev_level The information in the superblock is used to access the rest of the data on the disk. The number of block groups = the number of blocks / the number of blocks per group; // rounded up All block and inode addresses start at 1. The first block on the disk is block 1. 0 is used to indicate no block. Each block group can be found at the block address ((group number - 1)* blocks per group) and is of course blocks per group long. Group numbers are 1 based aswell Each group is just a series of blocks, however the first blocks in the group have a special purpose. The remainder are used for storing data. | Superblock | Group Descriptors | Block Bitmap | INode Bitmap | INode Table | Data blocks | |--------------------------------|---------------------------------------------------------| |This is the same for all groups | this is specific to each group | The superblock is stored in the first data block (except for group 1) The Group Descriptors contains information on the block groups. This data is covers all the groups and is stored in all the groups for rudundency. This is an array of the following structure
The size of the descriptors can be calculated as (sizeof(ext2_group) * number of groups) / block size; // rounded up if necessary The information in this structure us used to locate the block and inode bitmaps and inode table. Remember that the first entry corresponds to block group 1. The block bitmap is a bitmap indicating which blocks in the group have been allocated. If the bit is set then the block is allocated. The size of the bitmap is (blocks per group / 8) / block size;// with both divisions rounded up. It is necessary to find out which group a particular block is in to be able to look up the bitmap. The group = ((Block number - 1) / Blocks per group) + 1; // rounded up The block in that group is then Block Number - (Group * Blocks per group) The inode bitmap is essentaly the same as the block bitmap, but indicates which inodes are allocated. The size of the inode bitmpap is (inodes per group / 8) / block size;// with both divisions rounded up. The same calculations can be used for finding the group of a particular inode. The group = ((INode number - 1) / INodes per group) + 1; // rounded up The inode in that group is then INode Number - (Group * INodes per group) The inode table is an array of the inodes for that particular group. Again, the first entry is for the first inode in that group.
The file mode is a set of flags that specify the type of file and the access permissions
The i_block entry is an array of block addresses. The first EXT2_NDIR_BLOCKS (12) are direct block addresses. The data in these blocks is the content of the file. The next block EXT2_IND_BLOCK in the indirect block. This is the address of a block which contains a list of addresses of blocks which contain the data. There are block size / sizeof(ULONG) addresses in this block. The EXT2_DIND_BLOCK is simalar, but it is a double indirect block. It countains the address of a block which has a list of indirect block addresses. Each indirect block then has another list is blocks. The EXT2_TIND_BLOCK is simalar again, but it is the tripple indirect block. It contains a list of double indirect blocks etc.
Now that you know how to find and read inodes, you can start to read the files. There are a set of special inodes which are reserved for certain puposes. These include
The most important inode here is the root inode. This is the inode at the root of the file system. This inode is a directory, which like all directories has the following structure:
A directory is a list of these structures. The structures can not pass over a block boundry, so the last record is extended to fill the block. And entry with an inode of 0 should be ignored. |