When analyzing Linux VFS, we often need to involve specific file systems. The minix file can be said to be quite small, and it has considerable advantages for us to analyze VFS.
Physical Structure of the minix file system:
- The minix file system is a simple and simple file system. The ext2 file system can be seen as an improvement to minix, and each ext2 block group can be considered as a micro-minix file system.
- The length of the minix file system is only 1 K (the system disk block is 1 K), 1st is the start block, and 2nd is the super block, starting from 3rd, inode bitmap block group, data block bitmap block group, inode block group, and finally data block group.
- The directory items of the minix file system are composed of 16 inode numbers and fixed-length file name regions. inode starts from 1 and is numbered 0 to mark the deleted directory items. Id 1 is the root directory item. the directory items are divided into 16-byte version and 32-byte version. The maximum file names are 14 and 30, respectively.
- Inode of minix file system is divided into 32-byte (minix_inode) and 64-byte (minix2_inode ). the minix_inode has only one timestamp. the user group number (I _gid) is 8 bits and contains a double file index table consisting of nine 16-bit characters. minix2_inode uses three file timestamps, 16-bit GID and 10 32-bit characters to compose a triple file block index table.
- Depending on the directory and inode size, the minix file system disk is divided into four formatting versions: 0x137f, 0x138f, 0x2468, 0x2478.
/*
* This is the original minix inode layout on disk.
* Note the 8-bit GID and atime and ctime.
*/
Struct minix_inode {
_ 16i_mode;
_ 2010i_uid;
_ U32 I _size;
_ U32 I _time;
_ U8 I _gid;
_ U8 I _nlinks;
_ I _zone [9];/* indicates the logical block number array on the disk occupied by the file. The values 7 and 8 indicate the indirect blocks once and twice, respectively */
};
/*
* The New minix inode has all the time entries, as well
* Long block numbers and a third indirect block (7 + 1 + 1 + 1
* Instead of 7 + 1 + 1). Also, some previusly 8-bit values are
* Now 16-bit. The inode is now 64 bytes instead of 32.
*/
Struct minix2_inode {
_ 16i_mode;
_ 2010i_nlinks;
_ 2010i_uid;
_ 16i_gid;
_ U32 I _size;
_ U32 I _atime;
_ U32 I _mtime;
_ U32 I _ctime;
_ U32 I _zone [10];
};
/*
* Minix super-block data on disk
*/
Struct minix_super_block {
_ 2010s_ninodes;
_ 2010s_nzones;
_ 2010s_imap_blocks;
_ 2010s_zmap_blocks;
_ 2010s_firstdatazone;
_ 2010s_log_zone_size;
_ U32 s_max_size;
_ 2010s_magic;
_ 2010s_state;
_ U32 s_zones;
};
/*
* V3 minix super-block data on disk
*/
Struct minix3_super_block {
_ U32 s_ninodes;
_ 2010s_pad0;
_ 2010s_imap_blocks;
_ 2010s_zmap_blocks;
_ 2010s_firstdatazone;
_ 2010s_log_zone_size;
_ 2010s_pad1;
_ U32 s_max_size;
_ U32 s_zones;
_ 2010s_magic;
_ 2010s_pad2;
_ 2010s_blocksize;
_ U8 s_disk_version;
};
Struct minix_dir_entry {
_ 2010inode;
Char name [0];
};
Struct minix3_dir_entry {
_ U32 inode;
Char name [0];
};
/* Block read/write */
# Include <Linux/buffer_head.h>
Struct buffer_head * sb_read (struct super_block * Sb, sector_t block );
// Return _ bread (Sb-> s_bdev, block, Sb-> s_blocksize );
// _ Bread_slow (BH)
// _ Getblk (bdev, block, size)->
// _ Find_get_block
/*
Find_get_page
Map_bh: indicates the buffing between this buffer_head and blocknr and size on the disk.
*/
Sb_bread (SB, block)->
_ Bread (Sb-> s_bdev, block, Sb-> s_blocksize)->
BH =__ getblk (bdev, block, size)->
_ Find_get_block (bdev, block, size)->
Lookup_bh_lru (bdev, block, size) // find @ bdev, @ block, and @ size matching BH from the LRU linked list of the current CPU
_ Find_get_block_slow (bdev, block) // query all buffer_headers of the @ bdev device to find out if the @ block-matched BH exists.
_ Getblk_slow (bdev, block, size)->
_ Find_get_block (bdev, block, size) // search again
Grow_buffers (bdev, block, size)->
Grow_dev_page (bdev, block, index, size) // Add the page and corresponding BH for the device,
_ Bread_slow (BH)->
Submit_bh (BH)
Wait_on_buffer (BH)