Ext4文件系统

Ext4文件系统

2023-05-12
linux
  • 一个ext4文件系统被分割为多个block groups,block groups的大小在sb.s_blocks_per_group块中指定。
  • 默认情况下一个块的大小是4KiB,此时每个block group会包含32768个块,即一个group的大小为128MiB。
  • ext4中块是最小的分配单位。
  • ext4文件系统采用小端模式,数值的低字节存储在低地址处,高字节存储在高地址处。比如数“12 34 56 78”,小端存放的形式如下“78 56 34 12”。大端存放的形式为“12 34 56 78”。
  • 一个标准的block group布局如下(并非所有的块都是此布局):
  • centos7下使用dumpe2fs获取到的ext4文件系统的信息
  • ext4会保留一些inode作为特殊用途,如下:

ext4文件系统 #

目录 #

  • 目录也是文件,目录有对应的inode和data blocks,目录的data block中存放多个ext4_dir_entry_2,结构如下:
  • 文件类型可以取的值如下:
  • 案例
    • 0D000000 1000 05 01 6673746162 000000
    • 第一块表示inode号
    • 第二块表示此结构体长度为0x0010,即16,因为ext4采用小端存放,所以高位在高地址,低位在低地址。
    • 第三块表示文件名为5字节
    • 第四块表示文件类型为普通文件
    • 第五块是文件名,对应fstab,f的ascii是0x66,s的是0x73,t是0x75。
    • 最后一块是填充位,结构体大小必须是最大对其数的整数倍。

虚拟文件系统 #

  • Linux通过虚拟文件系统(VFS)来访问不同的文件系统。VFS使得用户可以直接使用open()、read()、write()这样的系统调用而无需考虑具体的文件系统。
  • VFS相当于定义了接口,具体的文件系统来实现这个接口。

VFS对象 #

  • VFS中主要定义了四个对象类型:
    • 超级块对象,它代表一个具体的文件系统。
    • 索引节点对象,即inode,代表一个具体文件。
    • 目录项对象,代表一个目录项(不是目录文件)。
    • 文件对象,代表进程打开的文件。

超级块对象 #

  • 超级块用来存储文件系统的信息,通常对应于存放在磁盘特定扇区中的文件系统超级块。
  • 超级块由super_block结构体表示,定义在include/linux/fs.h中。
struct super_block {
	struct list_head	s_list;
	dev_t			s_dev;
	unsigned long		s_blocksize; //每个块的大小(单位是字节)
	unsigned char		s_blocksize_bits; //每个块的大小(单位是比特)
	unsigned char		s_dirt;
	unsigned long long	s_maxbytes;	//文件大小上限
	struct file_system_type	*s_type;  //文件系统类型
	const struct super_operations	*s_op;
	struct dquot_operations	*dq_op;
 	struct quotactl_ops	*s_qcop;
	const struct export_operations *s_export_op;
	unsigned long		s_flags;
	unsigned long		s_magic;
	struct dentry		*s_root;
	struct rw_semaphore	s_umount;
	struct mutex		s_lock;
	int			s_count;
	int			s_syncing;
	int			s_need_sync_fs;
	atomic_t		s_active;
#ifdef CONFIG_SECURITY
	void                    *s_security;
#endif
	struct xattr_handler	**s_xattr;
	struct list_head	s_inodes;	/* all inodes */
	struct list_head	s_dirty;	/* dirty inodes */
	struct list_head	s_io;		/* parked for writeback */
	struct list_head	s_more_io;	/* parked for more writeback */
	struct hlist_head	s_anon;		/* anonymous dentries for (nfs) exporting */
	struct list_head	s_files;
	struct block_device	*s_bdev;
	struct mtd_info		*s_mtd;
	struct list_head	s_instances;
	struct quota_info	s_dquot;	/* Diskquota specific options */
  //......省略部分代码
};

目录项对象 #

  • Linux下一切皆文件,这里的文件包括目录和普通的文件。
  • 在路径/bin/vi中,bin和vi都属于文件,bin是目录文件,vi是普通文件。
  • VFS经常要执行和目录相关的操作,所以定义了一个目录项的概念,注意此目录项和目录文件不是同一个东西。在路径/bin/vi中,/ bin vi都属于目录项对象。
  • 目录项对象由dentry结构体表示,定义在include/linux/dcache.h
struct dentry {
	atomic_t d_count;
	unsigned int d_flags;
	spinlock_t d_lock;
	struct inode *d_inode;		//和目录项相关联的索引节点
	struct dentry *d_parent;	//父目录项
	struct qstr d_name;
	struct list_head d_lru;
	union {
		struct list_head d_child;
	 	struct rcu_head d_rcu;
	} d_u;
	struct list_head d_subdirs;	//子目录链表
	struct list_head d_alias;
	unsigned long d_time;
	struct dentry_operations *d_op;
	struct super_block *d_sb;
	void *d_fsdata;
#ifdef CONFIG_PROFILING
	struct dcookie_struct *d_cookie;
#endif
	int d_mounted;
	unsigned char d_iname[DNAME_INLINE_LEN_MIN];
};