/
就是一个文件,这个文件也对应一个inode,文件的数据就是根目录下的文件名和对应的inode号/home/niugen/testfile
$ pwd
/home/niugen
$ echo 'This is a test file for learning ext4' > testfile
$ cat testfile
This is a test file for learning ext4
cat testfile
时,cat命令接收到testfile
参数,进而根据当前工作目录计算出这个文件的绝对路径为/home/niugen/testfile
/
即根目录,根目录这个文件对应的inode号固定为2,所以可以直接找到根目录的inodedev、usr、home
等等,于是找到了home
对应的inode号/home
这个文件的inode,发现这也是一个目录文件,继续读出数据,找到niugen
对应的inode号/home/niugen
这个文件的inode,发现这还是一个目录文件,继续读出数据,找到testfile
对应的inode号/home/niugen/testfile
这个文件的inode,发现这是一个普通文件,可以使用cat命令,于是读出数据并打印在屏幕上i_block[EXT2_N_BLOCKS]
,存放磁盘块号struct ext2_inode{
__le16 i_mode; //文件类型和访问权限
__le16 i_uid; //拥有者id
__le32 i_size; //文件大小,单位byte
__le32 i_atime,i_ctime,i_mtime,i_dtime; //时间相关信息
__le16 i_gid; //用户组id
__le16 i_links_count; //硬链接计数器
__le32 i_blocks; //文件数据块数
__le32 i_flags; //标志
union osd1; //操作系统相关信息
__le32 i_block[EXT2_N_BLOCKS]; //指向数据块的指针,即磁盘块号
__le32 i_generation; //文件版本,用于网络文件系统
__le32 i_file_acl; //文件访问控制列表
__le32 i_dir_acl; //目录访问控制列表
__le32 i_faddr; //片地址(不懂)
union osd2; //操作系统相关信息
}
i_block
字段是一个有EXT2_N_BLOCKS
个元素的数组,若EXT2_N_BLOCKS
的默认值为15
ext4_inode
定义于/fs/ext4/ext4.h
,ext4_inode
的大小为256字节,一个4KB的块可以保存16个inode
i_block[EXT4_N_BLOCKS]
/*
* Constants relative to the data blocks
*/
#define EXT4_NDIR_BLOCKS 12
#define EXT4_IND_BLOCK EXT4_NDIR_BLOCKS
#define EXT4_DIND_BLOCK (EXT4_IND_BLOCK + 1)
#define EXT4_TIND_BLOCK (EXT4_DIND_BLOCK + 1)
#define EXT4_N_BLOCKS (EXT4_TIND_BLOCK + 1)
/*
* Structure of an inode on the disk
*/
struct ext4_inode {
__le16 i_mode; /* File mode */
__le16 i_uid; /* Low 16 bits of Owner Uid */
__le32 i_size_lo; /* Size in bytes */
__le32 i_atime; /* Access time */
__le32 i_ctime; /* Inode Change time */
__le32 i_mtime; /* Modification time */
__le32 i_dtime; /* Deletion Time */
__le16 i_gid; /* Low 16 bits of Group Id */
__le16 i_links_count; /* Links count */
__le32 i_blocks_lo; /* Blocks count */
__le32 i_flags; /* File flags */
union {
struct {
__le32 l_i_version;
} linux1;
struct {
__u32 h_i_translator;
} hurd1;
struct {
__u32 m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
__le32 i_block[EXT4_N_BLOCKS];/* Pointers to blocks */
__le32 i_generation; /* File version (for NFS) */
__le32 i_file_acl_lo; /* File ACL */
__le32 i_size_high;
__le32 i_obso_faddr; /* Obsoleted fragment address */
union {
struct {
__le16 l_i_blocks_high; /* were l_i_reserved1 */
__le16 l_i_file_acl_high;
__le16 l_i_uid_high; /* these 2 fields */
__le16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2;
} linux2;
struct {
__le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
} hurd2;
struct {
__le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */
__le16 m_i_file_acl_high;
__u32 m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
__le16 i_extra_isize;
__le16 i_pad1;
__le32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */
__le32 i_mtime_extra; /* extra Modification time(nsec << 2 | epoch) */
__le32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
__le32 i_crtime; /* File Creation time */
__le32 i_crtime_extra; /* extra FileCreationtime (nsec << 2 | epoch) */
__le32 i_version_hi; /* high 32 bits for 64-bit version */
};
i_block
的大小为60个字节,即__le32 i_block[EXT4_N_BLOCKS]
且EXT4_N_BLOCKS=15
/fs/ext4/ext4_extents.h
/*
* Each block (leaves and indexes), even inode-stored has header.
*/
struct ext4_extent_header {
__le16 eh_magic; /* probably will support different formats */
__le16 eh_entries; /* number of valid entries */
__le16 eh_max; /* capacity of store in entries */
__le16 eh_depth; /* has tree real underlying blocks? */
__le32 eh_generation; /* generation of the tree */
};
/*
* This is the extent on-disk structure.
* It's used at the bottom of the tree.
*/
struct ext4_extent {
__le32 ee_block; /* first logical block extent covers */
__le16 ee_len; /* number of blocks covered by extent */
__le16 ee_start_hi; /* high 16 bits of physical block */
__le32 ee_start_lo; /* low 32 bits of physical block */
};
/*
* This is index on-disk structure.
* It's used at all the levels except the bottom.
*/
struct ext4_extent_idx {
__le32 ei_block; /* index covers logical blocks from 'block' */
__le32 ei_leaf_lo; /* pointer to the physical block of the next *
* level. leaf or next index could be there */
__le16 ei_leaf_hi; /* high 16 bits of physical block */
__u16 ei_unused;
};
引导块 | 块组0 | … | 块组n |
---|---|---|---|
第1个块 | m个块 | … | m个块 |
每个块组有如下内容
其中超级块和组描述符,对于所有块组均相同,且总是缓存在内存中
其余则用于描述本块组管理的inode块和数据块
superblock
实在太大,不值得搬上来,源码见此ext4_sb.hext4_group_desc
如下
/*
* Structure of a blocks group descriptor
*/
struct ext4_group_desc
{
__le32 bg_block_bitmap_lo; /* Blocks bitmap block */
__le32 bg_inode_bitmap_lo; /* Inodes bitmap block */
__le32 bg_inode_table_lo; /* Inodes table block */
__le16 bg_free_blocks_count; /* Free blocks count */
__le16 bg_free_inodes_count; /* Free inodes count */
__le16 bg_used_dirs_count; /* Directories count */
__le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
__u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */
__le16 bg_itable_unused; /* Unused inodes count */
__le16 bg_checksum; /* crc16(sb_uuid+group+desc) */
__le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
__le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */
__le32 bg_inode_table_hi; /* Inodes table block MSB */
__le16 bg_free_blocks_count_hi;/* Free blocks count MSB */
__le16 bg_free_inodes_count_hi;/* Free inodes count MSB */
__le16 bg_used_dirs_count_hi; /* Directories count MSB */
__le16 bg_itable_unused_hi; /* Unused inodes count MSB */
__u32 bg_reserved2[3];
};
testfile
$ pwd
/home/niugen
$ echo 'This is a test file for learning ext4' > testfile
$ cat testfile
This is a test file for learning ext4
cat
命令可以打印一个普通文件的内容,那么对于目录文件就是常见的ls
命令,使用ls -i
可以打印出相应的inode号$ ls -i testfile
2629310 testfile
df
命令列出挂载的设备,可知/home
对应设备/dev/sda3
$ df
文件系统 1K-块 已用 可用 已用% 挂载点
udev 4010336 0 4010336 0% /dev
tmpfs 805968 17880 788088 3% /run
/dev/sda2 192115292 54064596 128268680 30% /
tmpfs 4029832 23168 4006664 1% /dev/shm
tmpfs 5120 4 5116 1% /run/lock
tmpfs 4029832 0 4029832 0% /sys/fs/cgroup
/dev/sda3 44049544 6435924 35352936 16% /home
tmpfs 805968 12 805956 1% /run/user/126
tmpfs 805968 64 805904 1% /run/user/1000
$ pwd
/home/niugen
$ ls -li testfile
2629310 -rw-rw-r-- 1 niugen niugen 38 6月 26 21:13 testfile
istat
命令可以打印出某个设备上的某个inode信息
$ sudo istat /dev/sda3 2629310
inode: 2629310
Allocated
Group: 320
Generation Id: 2014416585
uid / gid: 1000 / 1000
mode: rrw-rw-r--
Flags: Extents,
size: 38
num of links: 1
Inode Times:
Accessed: 2017-06-26 21:13:12.184134514 (CST)
File Modified: 2017-06-26 21:13:10.628122013 (CST)
Inode Modified: 2017-06-26 21:13:10.628122013 (CST)
File Created: 2017-06-26 10:18:07.690160310 (CST)
Direct Blocks:
10622354
根据前一步可知这个inode位于块组320中,inode号为2629310
fsstat
列出文件系统的信息,找到320块组的信息
$ sudo fsstat /dev/sda3 > dev.sda3.fsstat
$ cat dev.sda3.fsstat | grep "Group: 320" -n
4560:Group: 320:
$ cat dev.sda3.fsstat | head -n 4572 | tail -n 13
Group: 320:
Block Group Flags: [INODE_ZEROED]
Inode Range: 2621441 - 2629632
Block Range: 10485760 - 10518527
Layout:
Data bitmap: 10485760 - 10485760
Inode bitmap: 10485776 - 10485776
Inode Table: 10485792 - 10486303
Data Blocks: 10493984 - 10518527
Free Inodes: 8 (0%)
Free Blocks: 23488 (71%)
Total Directories: 534
Stored Checksum: 0x03D2
blkcat
命令读出一个磁盘块的内容$ sudo blkcat /dev/sda3 10486283 > dev.sda3.blk.10486283
hexedit
查看内容数据,其中该inode是这个块的第14个inodeistat
告诉我们的Direct Blocks
一样~~~istat
的Direct Blocks
已经告诉我们了)$ sudo blkcat /dev/sda3 10622354
This is a test file for learning ext4