前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >浅谈ext4文件系统初始化

浅谈ext4文件系统初始化

作者头像
用户4700054
发布2022-08-17 12:59:29
1.5K0
发布2022-08-17 12:59:29
举报
文章被收录于专栏:存储内核技术交流

调试环境

代码语言:javascript
复制
$ modprobe  -v ext4

$ dd if=/dev/zero of=/tmp/disk1 count=30 bs=1M

$ losetup --show -f /tmp/disk1 
/dev/loop0

$ mkfs.ext4 /dev/loop0

$ mount /tmp/disk1  /mnt/disk1

关于超级快基本知识

  • 当使用者适应mkfs.ext4 /dev/sdb时候,系统按照ext4内部的布局规则写入写入先关数据。mount时候按照内置的布局规则读取这些信息。ext4中涉及的的数据分为两大类,一类是数据;另外一类是元数据
  • 默认扇区大小是512个字节,而磁盘文件系统一般是按照block为单位管理磁盘,默认是4k大小。ext4文件系统为了减少碎片,使文件内容尽量落在相邻的block(这么做为了提高seek性能,尤其是在机械盘呢上)来提高访问的效率,ext4引入了block group,每个block group包含多个block,其中一个block用来这个block group中block使用情况。ext4把相邻的block group组成标记为一个flex_bg(flexible block group)。一个blex_bg中所有的block group的data block bitmapinode bitmapinode table存放在flex_bg的第一个block group,这样在flex_bg中除过第一个block group,其他的都可以存储实际的数据(其中有些block group还是要存储冗余的ext super block和group descriptors).ext4 super block和grouup descriptors会在每个block group中进行复制。下面简单介绍下block group的格式:
  • group 0 padding:第一个block group特有的,存储机器的启动信息;除过第一个block group有padding外,其他的block是没有的。
  • ext4 super block:包含整个磁盘的系统信息
  • group descriptors:所有block group的信息,每一个group descriptor和一个block group一一对应。这个包含block bimap/inode bitmap/ block从属的block group信息等;占用block是由磁盘大小决定
  • reserved gdt blocks:方便未来扩展而预留的空间
  • data block bitmap:存放block group的使用情况的位图。
  • inode bitmap:当前block group中inode使用情况位图
  • inode table:描述block group内所有inode的信息,占用大小是由block group中inode数乘以inode大小
  • data block:存储实际文件数据的block

ext4超级块内容分析

  • 在内核中vfs层定义了通用的struct super_block超级块,这个超级块中的s_fs_info指向ext4磁盘文件系统的struct ext4_sb_info的超级块。
代码语言:javascript
复制
// 内核定义的通用超级块
struct super_block {
 // 省略字段
}

// 具体磁盘文件系统ext4的超级块
struct ext4_sb_info {
	// 每个  group descriptor 大小
	unsigned long s_desc_size;	
	// 每个block的inode数量
	unsigned long s_inodes_per_block;
	// 每个block group中的block数量
	unsigned long s_blocks_per_group;
	unsigned long s_clusters_per_group; 
	// 每个block group中inode数量
	unsigned long s_inodes_per_group;/* Number of inodes in a group */
	// 每个block group中inode table数量
	unsigned long s_itb_per_group;	/* Number of inode table blocks per group */
	// 省略其他字段
}
  • ext4文件系统中每个块组会有一个数据机构来描述它,内核使用struct ext4_group_desc结构来描述每个块组信息。dumpe2fs工具转储磁盘时候,Group 0Group N信息都是来自读取struct ext4_group_desc
代码语言:javascript
复制
struct ext4_group_desc
{
	// 数据块位图所在的block号
	__le32	bg_block_bitmap_lo;	
	// inode位图所在的的数据块
	__le32	bg_inode_bitmap_lo;
	// inode table所在数据块
	__le32	bg_inode_table_lo;	
	// 空闲数据块数量
	__le16	bg_free_blocks_count_lo;
	// 空闲inodes数量
	__le16	bg_free_inodes_count_lo;
	// 当前目录的数量
	__le16	bg_used_dirs_count_lo;
	// falg信息
	__le16	bg_flags;		
	__le32  bg_exclude_bitmap_lo;   /* Exclude bitmap for snapshots */
	//  crc32c(s_uuid+grp_num+bbitmap) 低位校验
	__le16  bg_block_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+bbitmap) LE */
	__le16  bg_inode_bitmap_csum_lo;/* crc32c(s_uuid+grp_num+ibitmap) LE */
	__le16  bg_itable_unused_lo;	/* 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 */
	__le32  bg_exclude_bitmap_hi;   /* Exclude bitmap block MSB */
	// crc32c(s_uuid+grp_num+bbitmap) 高位校验
	__le16  bg_block_bitmap_csum_hi;
	__le16  bg_inode_bitmap_csum_hi;
	__u32   bg_reserved;
};
  • mkfs.ext4初始化过程,磁盘大小是30M,一共是标号从0~3的4个block group,当使用mkfs.ext4内核关联一个进程static struct task_struct *ext4_lazyinit_task来做初始化。
代码语言:javascript
复制
static int ext4_run_lazyinit_thread(void)
{
	// 启动内核线程,调用ext4_lazyinit_thread 函数铏初始化
	ext4_lazyinit_task = kthread_run(ext4_lazyinit_thread,
					 ext4_li_info, "ext4lazyinit");
	if (IS_ERR(ext4_lazyinit_task)) {
		int err = PTR_ERR(ext4_lazyinit_task);
		ext4_clear_request_list();
		kfree(ext4_li_info);
		ext4_li_info = NULL;
		printk(KERN_CRIT "EXT4-fs: error %d creating inode table "
				 "initialization thread\n",
				 err);
		return err;
	}
	ext4_li_info->li_state |= EXT4_LAZYINIT_RUNNING;
	return 0;
}

/********调用的函数路径******/

ext4_lazyinit_thread [ext4]() {
  // 加载block group
  ext4_get_group_desc [ext4]();
  // 初始化inode table
  ext4_init_inode_table [ext4]() {
	// 获取block group desc结构
    ext4_get_group_desc [ext4]();
    // 启动日志
    ext4_journal_check_start [ext4]();
    // 获取未使用的inode table数量
    ext4_itable_unused_count [ext4]();
    // 设置 block group中的标记位 bg_inode_table_hi
    ext4_inode_table [ext4]();
    // 设置 block group的crc
    ext4_group_desc_csum_set [ext4]() {
      ext4_group_desc_csum [ext4]();
    }
  }
  ext4_get_group_desc [ext4]();
  ext4_init_inode_table [ext4]() {
    ext4_get_group_desc [ext4]();
    ext4_journal_check_start [ext4]();
    ext4_inode_table [ext4]();
    ext4_group_desc_csum_set [ext4]() {
      ext4_group_desc_csum [ext4]();
    }
  }
  ext4_get_group_desc [ext4]();
  ext4_init_inode_table [ext4]() {
    ext4_get_group_desc [ext4]();
    ext4_journal_check_start [ext4]();
    ext4_inode_table [ext4]();
    ext4_group_desc_csum_set [ext4]() {
      ext4_group_desc_csum [ext4]();
    }
  }
  ext4_get_group_desc [ext4]();
  ext4_init_inode_table [ext4]() {
    ext4_get_group_desc [ext4]();
    ext4_journal_check_start [ext4]();
    ext4_inode_table [ext4]();
    ext4_group_desc_csum_set [ext4]() {
      ext4_group_desc_csum [ext4]();
    }
  }
  ext4_remove_li_request.part.119 [ext4]();
}
  • 使用mkfs.ext4命令后,初始化了磁盘的超级块。dumpe2fs把整个超级快dump出来,这里 磁盘大小一共是30M,dump出来后如下:
代码语言:javascript
复制
$ dumpe2fs /dev/loop0
// 文件系统元数据
dumpe2fs 1.45.6 (20-Mar-2020)
Filesystem volume name:   <none>
Last mounted on:          <not available>
Filesystem UUID:          d0b48bf3-4aab-4019-8617-6f4fe1a20268
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file dir_nlink extra_isize metadata_csum
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              7680
Block count:              30720
Reserved block count:     1536
Free blocks:              27990
Free inodes:              7669
First block:              1
Block size:               1024
Fragment size:            1024
Group descriptor size:    64
Reserved GDT blocks:      239
Blocks per group:         8192
Fragments per group:      8192
Inodes per group:         1920
Inode blocks per group:   240
Flex block group size:    16
Filesystem created:       Sun Mar 27 19:18:41 2022
Last mount time:          n/a
Last write time:          Sun Mar 27 19:18:41 2022
Mount count:              0
Maximum mount count:      -1
Last checked:             Sun Mar 27 19:18:41 2022
Check interval:           0 (<none>)
Lifetime writes:          261 kB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               128
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      46745eac-889b-4456-91bc-989742111935
Journal backup:           inode blocks
Checksum type:            crc32c
Checksum:                 0xda84b217
Journal features:         (none)
Journal size:             1024k
Journal length:           1024
Journal sequence:         0x00000001
Journal start:            0


// 一共3个 block group,每个block group的block bitmap和inode bitmap都在第一个block group中存储
// block group 0 存储了其他block group的数据块位图、inode位图、inode table.
Group 0: (Blocks 1-8192) csum 0x2efa
  Primary superblock at 1, Group descriptors at 2-2
  Reserved GDT blocks at 3-241
  // block bitmap和inode bitmap 都存储在第一个block group中
  Block bitmap at 242 (+241), csum 0x9d8af453
  Inode bitmap at 246 (+245), csum 0x494ef22a
  Inode table at 250-489 (+249)
  6969 free blocks, 1909 free inodes, 2 directories, 1909 unused inodes
  Free blocks: 1224-8192
  Free inodes: 12-1920
Group 1: (Blocks 8193-16384) csum 0xcb52 [INODE_UNINIT, BLOCK_UNINIT]
  Backup superblock at 8193, Group descriptors at 8194-8194
  Reserved GDT blocks at 8195-8433
  // 数据块的位图
  Block bitmap at 243 (bg #0 + 242), csum 0x00000000
  // inode的位图
  Inode bitmap at 247 (bg #0 + 246), csum 0x00000000
  // inode table
  Inode table at 490-729 (bg #0 + 489)
  // 空闲块
  7951 free blocks, 1920 free inodes, 0 directories, 1920 unused inodes
  Free blocks: 8434-16384
  Free inodes: 1921-3840
Group 2: (Blocks 16385-24576) csum 0xb0d5 [INODE_UNINIT]
  Block bitmap at 244 (bg #0 + 243), csum 0x1364dcda
  Inode bitmap at 248 (bg #0 + 247), csum 0x00000000
  Inode table at 730-969 (bg #0 + 729)
  7168 free blocks, 1920 free inodes, 0 directories, 1920 unused inodes
  Free blocks: 17409-24576
  Free inodes: 3841-5760
Group 3: (Blocks 24577-30719) csum 0x05de [INODE_UNINIT]
  Backup superblock at 24577, Group descriptors at 24578-24578
  Reserved GDT blocks at 24579-24817
  Block bitmap at 245 (bg #0 + 244), csum 0x628642b2
  Inode bitmap at 249 (bg #0 + 248), csum 0x00000000
  Inode table at 970-1209 (bg #0 + 969)
  5902 free blocks, 1920 free inodes, 0 directories, 1920 unused inodes
  Free blocks: 24818-30719
  Free inodes: 5761-7680
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 存储内核技术交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 调试环境
    • 关于超级快基本知识
      • ext4超级块内容分析
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档