static int ext4_ext_insert_index(handle_t *handle, struct inode *inode,
struct ext4_ext_path *curp,
int logical, ext4_fsblk_t ptr)
{
新的数据块插入当前的路径深度里。
}
static int ext4_ext_split(handle_t *handle, struct inode *inode,
unsigned int flags,
struct ext4_ext_path *path,
struct ext4_extent *newext, int at)//at是当前的深度,depth – at得出到叶子节点还差的深度,需要用新的块,建立新的索引节点和叶子节点。
{
1. 先建立新的块为当前路径下的新叶子块,将当前路径下的旧的叶子节点信息复制到新块中;
2. 建立中间的索引路径节点
3. 路径建立好后,新块插入新的路径中
}
static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
unsigned int flags,
struct ext4_extent *newext)
{
分配一个新块,将原来在INODE中的i_data数据复制到新块中,同时更新INDOE中i_data的数据,用后移的数据填充它。
}
static int ext4_ext_create_new_leaf(handle_t *handle, struct inode *inode,
unsigned int flags,
struct ext4_ext_path *path,
struct ext4_extent *newext)
{
curp = path + depth;
while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) { //查找是否有空闲索引
i--;
curp--;
}
1. 如果有空闲索引,分裂。
err = ext4_ext_split(handle, inode, flags, path, newext, i);
path = ext4_ext_find_extent(inode, //重新建立路径,返回后有用
(ext4_lblk_t)le32_to_cpu(newext->ee_block),
path);
2. 如果没有空闲索引,整棵树增加一个深度
err = ext4_ext_grow_indepth(handle, inode, flags, newext);
path = ext4_ext_find_extent(inode,//重新建立路径,返回后有用
(ext4_lblk_t)le32_to_cpu(newext->ee_block),
path);
}
int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
struct ext4_ext_path *path,
struct ext4_extent *newext, int flag)
{
depth = ext_depth(inode);
ex = path[depth].p_ext; //找到叶子节点
depth = ext_depth(inode);
eh = path[depth].p_hdr;
if (le16_to_cpu(eh->eh_entries) < le16_to_cpu(eh->eh_max)) //叶子节点还有空间
goto has_space; //跳转到有空间的处理
如果没有空间就创建新的节点
err = ext4_ext_create_new_leaf(handle, inode, flags, path, newext);
has_space:
新节点插入,然后看能否合并
}
int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, struct ext4_map_blocks *map, int flags)
{
1. 逻辑块在节点的cache中,查找到已经分配的块,返回;
2. 2.1 path = ext4_ext_find_extent(inode, map->m_lblk, NULL); //查找完整的路径链
depth = ext_depth(inode);
ex = path[depth].p_ext; //叶子节点
如果叶子节点存在,目标逻辑块在叶子节点范围内,则查找到块,返回;
2.2 如果叶子节点不存在或者上文的节点不符合要求,则分配新块;
newex.ee_block = cpu_to_le32(map->m_lblk);
newex.ee_len = cpu_to_le16(map->m_len);
err = ext4_ext_check_overlap(sbi, inode, &newex, path); //检查是否有重叠
if (err)
allocated = ext4_ext_get_actual_len(&newex);
else
allocated = map->m_len;
2.3 ar.inode = inode;
ar.goal = ext4_ext_find_goal(inode, path, map->m_lblk);
ar.logical = map->m_lblk;
2.3 newblock = ext4_mb_new_blocks(handle, &ar, &err); //分配新块
2.4 ext4_ext_store_pblock(&newex, newblock + offset);
newex.ee_len = cpu_to_le16(ar.len);
err = ext4_ext_insert_extent(handle, inode, path, &newex, flags);//新块插入路径
newblock = ext4_ext_pblock(&newex);
allocated = ext4_ext_get_actual_len(&newex);
if (allocated > map->m_len)
allocated = map->m_len;
}
int ext4_map_blocks(handle_t *handle, struct inode *inode, struct ext4_map_blocks *map, int flags)
{
if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
retval = ext4_ext_map_blocks(handle, inode, map, flags &
EXT4_GET_BLOCKS_KEEP_SIZE); //使用extents
} else {
retval = ext4_ind_map_blocks(handle, inode, map, flags &
EXT4_GET_BLOCKS_KEEP_SIZE);//使用间接块
}
}
static int _ext4_get_block(struct inode *inode, sector_t iblock,
struct buffer_head *bh, int flags)
{
map.m_lblk = iblock; //申请块的逻辑块号
map.m_len = bh->b_size >> inode->i_blkbits; //申请块的块数
if (flags && !handle) {//直接IO传输,暂时不讨论
/* Direct IO write... */
if (map.m_len > DIO_MAX_BLOCKS)
map.m_len = DIO_MAX_BLOCKS;
dio_credits = ext4_chunk_trans_blocks(inode, map.m_len);
handle = ext4_journal_start(inode, dio_credits);
if (IS_ERR(handle)) {
ret = PTR_ERR(handle);
return ret;
}
started = 1;
}
ret = ext4_map_blocks(handle, inode, &map, flags);
if (ret > 0) {
map_bh(bh, inode->i_sb, map.m_pblk);//申请后返回的物理块号
bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
bh->b_size = inode->i_sb->s_blocksize * map.m_len;//申请后返回的字节数
ret = 0;
}
}
int ext4_get_block(struct inode *inode, sector_t iblock,struct buffer_head *bh, int create)
{
return _ext4_get_block(inode, iblock, bh,
create ? EXT4_GET_BLOCKS_CREATE : 0);
}
EXT4文件系统之extents的ext4_get_block()
最新推荐文章于 2022-12-31 22:52:02 发布