EXT4文件系统之extents的ext4_get_block()

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);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值