原文来自 http://blog.chinaunix.net/uid-28989651-id-4552536.html
Ext4文件系统在线扩展大小的本质是将文件系统的数据块个数扩展到用户期望的数据块的个数。从功能上来看是扩展文件系统最后一个块组(EXT4_IOC_GROUP_EXTEND)与增加块组扩展文件系统(EXT4_IOC_GROUP_ADD)两种方式的结合,但是处理上稍微有点不同。Ext4文件系统的Ioctl命令EXT4_IOC_RESIZE_FS用于在线扩展Ext4文件系统的大小。使用以下命令就可实现调用EXT4_IOC_RESIZE_FS命令扩展Ext4文件系统:
ioctl(fd, EXT4_IOC_RESIZE_FS,arg )
参数arg为用户希望扩展后最终的文件系统所具有的(文件系统)数据块的个数unsigned int arg。
1. EXT4_IOC_RESIZE_FS扩展文件系统的限制
利用Ext4 的EXT4_IOC_RESIZE_FS命令扩展文件系统,它对文件系统的扩展结果受到以下限制:
(1)不支持缩小文件系统;
(2)如果Ext4文件系统开启了bigalloc(大数据块)特性,则不支持在线扩展;
(3)如果Ext4文件系统开启了元块组(meta_bg)特性,则不支持在线扩展;
(4)如果Ext4当前使用32位系统且系统不兼容64位,同时调整后的数据块的个数超过2^32,那么不支持在线扩展;
(5)如果新扩展的部分要使用新的块组描述符数据块,且Ext4中没有预留GDT数据块,则不进行在线扩展;
(6)如果用户期望扩展的文件系统大小超过实际分区,则不进行扩展。
2. 在线扩展Ext4文件系统的操作流程
(1) 依次判断当期Ext4是否开启bigalloc特性与元块组特性,如果开启,则不进行扩展文件系统的操作;
(2)如果当前Ext4文件系统使用32位数据块个数寻址且不支持64位兼容性,那么如果用户期望扩展文件系统使其超过2^32个,则不进行在线扩展;
(3) 设置ext4_sb_info->s_resize_flags标志位,表示将进行在线调整大小;
(4) 获取对文件系统的写权限;
(5) 调用ext4_resize_fs(sb, n_blocks_count)函数扩展文件系统,其中sb为要扩展的文件系统的超级块,n_blocks_count为期望扩展到的最终数据块个数。该函数实际执行如下操作:
a) 判断参数以及文件系统自身的配置是否满足扩展操作执行的条件。
i. 获取当前文件系统的数据块个数;
ii. 判断参数是否指向缩小文件系统,如果是,则推出。不支持缩小文件系统的在线扩展调整;
iii. 如果新增的部分的块组的描述符要在一个新的块组描述符数据块中分配,判断文件系统中是否有预留GDT数据块,如果没有,那么不能进行扩展。
b) 获取预留GDT数据块的Inode并进行有效性检查;
c) 查看硬件物理空间是否足够扩展文件系统;
d) 先将当前文件系统的最后一个块组扩充完整;
e) 以每次新增一个flex块组的方式扩展文件系统,具体步骤如下:
i. 调用alloc_flex_gd(flexbg_size)分配一个struct ext4_new_flex_group_data,用于增加一个flex块组,其中参数flexbg_size为每个flex块组中普通块组的个数;
ii. 反复调用ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count,flexbg_size)函数每次增加一个新的flex块组,直到所有新增数据块都增加到文件系统中。每次增加一个新的flex块组后,先调用ext4_alloc_group_tables(sb, flex_gd, flexbg_size)在创建的flex块组中分配块位图、Inode位图以及Inode表,然后调用ext4_flex_group_add(sb, resize_inode, flex_gd)函数将块组加到文件系统中。
f) 释放分配的struct ext4_new_flex_group_data空间,将预留GDT数据块的Inode的引用次数减1,返回。
(6) 建立日志事务锁(barrier机制),更新文件系统元数据;
(7) 释放对文件系统的写权限;
(8) 清除ext4_sb_info->s_resize_flags标志位,返回;扩展文件系统操作结束。