EXT4文件系统学习(三)文件系统的组成部分

文件系统的组成部分

block
    Linux中通过文件系统控制使用"块"为读写单元
    现在的文件系统上,块的大小一般为1024bytes(1K)或2048bytes(2K)或4096bytes(4K)

inode
    【文件存储位置的索引】
    通过扫描索引找到对应的数据,而且索引可以存储部分数据。
    在文件系统上索引技术具体化为索引节点(index node),在索引节点上存储的部分数据即为文件的属性元数据及其他少量信息。
    在inode中存储了inode号、文件类型、权限、文件所有者、大小、时间戳等元数据信息,最重要的是还存储了指向属于该文件block的指针,
    这样读取inode就可以找到属于该文件的block,进而读取这些block并获得该文件的数据
    一般inode大小为128字节或256字节

Inode: 12   Type: regular    Mode:  0644   Flags: 0x0
Generation: 1454951771    Version: 0x00000000:00000001
User:     0   Group:     0   Size: 5
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x5b628db2:15e0aff4 -- Thu Aug  2 12:50:58 2018
 atime: 0x5b628db2:15e0aff4 -- Thu Aug  2 12:50:58 2018
 mtime: 0x5b628db2:15e0aff4 -- Thu Aug  2 12:50:58 2018
crtime: 0x5b628db2:15e0aff4 -- Thu Aug  2 12:50:58 2018
Size of extra inode fields: 28
BLOCKS:
(0):1024
TOTAL: 1	
struct inode {
	umode_t			i_mode;
	unsigned short		i_opflags;
	kuid_t			i_uid;
	kgid_t			i_gid;
	unsigned int		i_flags;

#ifdef CONFIG_FS_POSIX_ACL
	struct posix_acl	*i_acl;
	struct posix_acl	*i_default_acl;
#endif

	const struct inode_operations	*i_op;
	struct super_block	*i_sb;
	struct address_space	*i_mapping;

#ifdef CONFIG_SECURITY
	void			*i_security;
#endif

	/* Stat data, not accessed from path walking */
	unsigned long		i_ino;
	/*
	 * Filesystems may only read i_nlink directly.  They shall use the
	 * following functions for modification:
	 *
	 *    (set|clear|inc|drop)_nlink
	 *    inode_(inc|dec)_link_count
	 */
	union {
		const unsigned int i_nlink;
		unsigned int __i_nlink;
	};
	dev_t			i_rdev;
	loff_t			i_size;
	struct timespec		i_atime;
	struct timespec		i_mtime;
	struct timespec		i_ctime;
	spinlock_t		i_lock;	/* i_blocks, i_bytes, maybe i_size */
	unsigned short          i_bytes;
	unsigned int		i_blkbits;
	blkcnt_t		i_blocks;

#ifdef __NEED_I_SIZE_ORDERED
	seqcount_t		i_size_seqcount;
#endif

	/* Misc */
	unsigned long		i_state;
	struct mutex		i_mutex;

	unsigned long		dirtied_when;	/* jiffies of first dirtying */
	unsigned long		dirtied_time_when;

	struct hlist_node	i_hash;
	struct list_head	i_wb_list;	/* backing dev IO list */
	struct list_head	i_lru;		/* inode LRU list */
	struct list_head	i_sb_list;
	union {
		struct hlist_head	i_dentry;
		struct rcu_head		i_rcu;
	};
	u64			i_version;
	atomic_t		i_count;
	atomic_t		i_dio_count;
	atomic_t		i_writecount;
#ifdef CONFIG_IMA
	atomic_t		i_readcount; /* struct files open RO */
#endif
	const struct file_operations	*i_fop;	/* former ->i_op->default_file_ops */
	struct file_lock_context	*i_flctx;
	struct address_space	i_data;
	struct list_head	i_devices;
	union {
		struct pipe_inode_info	*i_pipe;
		struct block_device	*i_bdev;
		struct cdev		*i_cdev;
	};

	__u32			i_generation;

#ifdef CONFIG_FSNOTIFY
	__u32			i_fsnotify_mask; /* all events this inode cares about */
	struct hlist_head	i_fsnotify_marks;
#endif

	void			*i_private; /* fs or device private pointer */
};	

bmap    
    【使用bit位标记block那些空闲和占用】    
    位图只使用0和1标识对应block是空闲还是被占用,0和1在位图中的位置和block的位置一一对应,第一位标识第一个块,第二个位标识第二个块,依次下去直到标记完所有的block。
    bmap的优化针对的是写优化,因为只有写才需要找到空闲block并分配空闲block
    虽然bmap已经极大的优化了扫描,但是仍有其瓶颈,如果容量超过100G,bmap会占用12800个1KB大小的block,扫描不连续的bmap也会占用很多时间

struct bmap {
	struct dbmap db_bmap;		/* on-disk aggregate map descriptor */
	struct inode *db_ipbmap;	/* ptr to aggregate map incore inode */
	struct mutex db_bmaplock;	/* aggregate map lock */
	atomic_t db_active[MAXAG];	/* count of active, open files in AG */
	u32 *db_DBmap;
};	

imap
    在格式化创建文件系统后所有的inode号都是被事先设定好存放在inode table中的,因此产生了问题:要为文件分配哪一个inode号呢?又如何知道某一个inode号是否已经被分配了呢?
    标识inode号是否被分配的位图称为inodemap简称为imap。这时要为一个文件分配inode号只需扫描imap即可知道哪一个inode号是空闲的。

块组的出现
    将文件系统占用的block划分成块组(block group),解决bmap、inode table和imap太大的问题。
    在物理层面上的划分是将磁盘按柱面划分为多个分区,即多个文件系统;在逻辑层面上的划分是将文件系统划分成块组。
    每个文件系统包含多个块组,每个块组包含多个元数据区和数据区:元数据区就是存储bmap、inode table、imap等的数据;数据区就是存储文件数据的区域

块组的划分    
    它只需确定一个数据——每个block的大小,再根据bmap至多只能占用一个完整的block的标准就能计算出块组如何划分
    
    block为默认的1KB,一个bmap完整占用一个block能标识1024*8= 8192个block,每个块组是8192K即8M
    创建100M的文件系统需要创建的快组=100/8=12.5=13,与格式化mkfs.ext4 /dev/loop0打印的13 block groups相符
    每个组设定多少个inode号呢?inode table占用多少block呢?这需要由系统决定了

超级块(superblock)    
    存储信息:一个文件系统会分多个块组,每个块组又有多少block多少inode号等等信息,
    文件系统本身的属性信息如各种时间戳、block总数量和空闲数量、inode总数量和空闲数量、当前文件系统是否正常、什么时候需要自检等等,
    
    superblock的起止位置是第二个1024(1024-2047)字节(前面1024字节是硬盘的引导区,占据1K字节用来存储分区信息,文件系统不能使用)。查看loop.img十六进制文件可以看出:

00000400h: 58 64 00 00 00 90 01 00 00 14 00 00 40 6D 01 00 ; Xd...?.....@m..
00000410h: 4D 64 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ; Md..............
00000420h: 00 20 00 00 00 20 00 00 B8 07 00 00 0E E7 FC 5B ; . ... ..?...琰[
00000430h: 0E E7 FC 5B 01 00 FF FF 53 EF 01 00 01 00 00 00 ; .琰[..S?.....
00000440h: DB E6 FC 5B 00 00 00 00 00 00 00 00 01 00 00 00 ; 坻黐............
00000450h: 00 00 00 00 0B 00 00 00 80 00 00 00 3C 00 00 00 ; ........€...<...
00000460h: C6 02 00 00 79 00 00 00 20 E9 3F EE 0A 18 48 46 ; ?..y... ??.HF
00000470h: AD 69 A9 C6 D6 C0 3C E6 00 00 00 00 00 00 00 00 ; 璱┢掷<?.......
00000480h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000490h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
000004a0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
000004b0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
000004c0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 ; ................
000004d0h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
000004e0h: 08 00 00 00 00 00 00 00 00 00 00 00 26 DF 2A A0 ; ............&??
000004f0h: CC 39 46 D8 98 B0 0A 48 A6 42 18 67 01 01 40 00 ; ?F貥?H.g..@.
00000500h: 0C 00 00 00 00 00 00 00 DB E6 FC 5B 0A F3 01 00 ; ........坻黐.?.
00000510h: 04 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 ; ................
00000520h: 01 C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; .?.............
00000530h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000540h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 40 00 ; ..............@.
00000550h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000560h: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................
00000570h: 00 00 00 00 04 00 00 00 5F 11 00 00 00 00 00 00 ; ........_.......	

    且可以看到有5个superblock的备份
    使用dumpe2fs命令是读设备的超级快(没有实时更新的),df命令是读内存中文件系统superblock信息(实时更新),所以速度很快
    在块组0、1和3、5、7幂次方的块组中保存超级块的信息
    0x80 0400 == 8193*1024

块组描述符表(GDT)    
    ext文件系统每一个块组信息使用32字节描述,这32个字节称为块组描述符,所有块组的块组描述符组成块组描述符表GDT(group descriptor table)。
    将它们组成一个GDT,并将该GDT存放于某些块组中,存放GDT的块组和存放superblock和备份superblock的块相同,也就是说它们是同时出现在某一个块组中的。
    读取时也总是读取Group0中的块组描述符表信息。

    格式化后:

	Group 0: (Blocks 1-8192) [ITABLE_ZEROED]
	  Checksum 0x0229, unused inodes 1965
	  主 superblock at 1, Group descriptors at 2-2
	  保留的GDT块位于 3-258
	  Block bitmap at 259 (+258), Inode bitmap at 275 (+274)
	  Inode表位于 291-537 (+290)
	  4683 free blocks, 1965 free inodes, 2 directories, 1965个未使用的inodes
	  可用块数: 3510-8192
	  可用inode数: 12-1976	

11 drwx------. 2 root root 12288 11月 27 14:40 lost+found【lost+found在格式化完成后就创建了占用inode号11】

block分布:
	0		1		2		3-258		259		(260-274)	275		(276-290)	291-537			(538-3509)		3510-8192
	null	super	GDT		GDT_BACK	bmap				imap				Inode table						data block

创建文件1.c 和目录abc:

	Group 0: (Blocks 1-8192) [ITABLE_ZEROED]
	  Checksum 0x0f88, unused inodes 1964
	  主 superblock at 1, Group descriptors at 2-2
	  保留的GDT块位于 3-258
	  Block bitmap at 259 (+258), Inode bitmap at 275 (+274)
	  Inode表位于 291-537 (+290)
	  4681 free blocks, 1964 free inodes, 2 directories, 1964个未使用的inodes
	  可用块数: 3512-8192
	  可用inode数: 13-1976
	1.c  a2  abc  lost+found
	Group 0: (Blocks 1-8192) [ITABLE_ZEROED]
	  Checksum 0xd264, unused inodes 1964
	  主 superblock at 1, Group descriptors at 2-2
	  保留的GDT块位于 3-258
	  Block bitmap at 259 (+258), Inode bitmap at 275 (+274)
	  Inode表位于 291-537 (+290)
	  4680 free blocks, 1964 free inodes, 2 directories, 1964个未使用的inodes
	  可用块数: 3513-8192
	  可用inode数: 13-1976
	  【创建文件和目录不消耗inode?】【不会实时更新到设备的superblock中,在umount或者mount时更新】
	[yubo.wang@localhost dir]$ ll -i
	总用量 18
	  12 -rwxr-xr-x. 1 root root     0 11月 27 19:30 1.c
	  13 -rw-r--r--. 1 root root     0 11月 27 20:11 2.c
	1978 drwxr-xr-x. 2 root root  1024 11月 27 19:54 a2
	1977 drwxr-xr-x. 2 root root  1024 11月 27 19:34 abc
	  11 drwx------. 2 root root 12288 11月 27 14:40 lost+found	
	【创建空文件会保存在Group 0中,inode加1,空文件不占用空间就不会占用block】
	【创建目录会保存在Group 1中,inode加1,占用1个block】

下一篇手动破坏超级块和inode再进行恢复;

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值