EXT4文件系统之间接块的ext4_get_block()

static int ext4_alloc_branch(handle_t *handle, struct inode *inode,
			     ext4_lblk_t iblock, int indirect_blks,
			     int *blks, ext4_fsblk_t goal,
			     ext4_lblk_t *offsets, Indirect *branch)
{
1.	分配数据块
2.	建立多次间接块的映射关系
}

int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
			struct ext4_map_blocks *map,
			int flags)
{
	depth = ext4_block_to_path(inode, map->m_lblk, offsets,
				   &blocks_to_boundary);
    //该函数建立从直接块到三次间接块之间的完整的路径,depth返回深度,各个中间间接块的地址保存在offsets中;
	if (depth == 0)
		goto out;
	partial = ext4_get_branch(inode, depth, offsets, chain, &err);
    //查找各个路径下的地址,看能否找到目标块
	/* Simplest case - block found, no allocation needed */
	if (!partial) {//该种情况下,找到了数据块。
		first_block = le32_to_cpu(chain[depth - 1].key);
		count++;
		/*map more blocks*/
		while (count < map->m_len && count <= blocks_to_boundary) {
			ext4_fsblk_t blk;

			blk = le32_to_cpu(*(chain[depth-1].p + count));

			if (blk == first_block + count)
				count++;
			else
				break;
		}
		goto got_it;//找到了数据块,返回
	}

	/* Next simple case - plain lookup or failed read of indirect block */
	if ((flags & EXT4_GET_BLOCKS_CREATE) == 0 || err == -EIO)
		goto cleanup;

	if (EXT4_HAS_RO_COMPAT_FEATURE(inode->i_sb,
				       EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
		EXT4_ERROR_INODE(inode, "Can't allocate blocks for "
				 "non-extent mapped inodes with bigalloc");
		return -ENOSPC;
	}

	goal = ext4_find_goal(inode, map->m_lblk, partial); //查找当前逻辑地址最合适的地址

	/* the number of blocks need to allocate for [d,t]indirect blocks */
	indirect_blks = (chain + depth) - partial - 1;

	/*
	 * Next look up the indirect map to count the totoal number of
	 * direct blocks to allocate for this branch.
     需要分配的块数
	 */
	count = ext4_blks_to_allocate(partial, indirect_blks,
				      map->m_len, blocks_to_boundary);
	/*
	 * Block out ext4_truncate while we alter the tree
	 */
	err = ext4_alloc_branch(handle, inode, map->m_lblk, indirect_blks,
				&count, goal,
				offsets + (partial - chain), partial);

	/*
	 * The ext4_splice_branch call will free and forget any buffers
	 * on the new chain if there is a failure, but that risks using
	 * up transaction credits, especially for bitmaps where the
	 * credits cannot be returned.  Can we handle this somehow?  We
	 * may need to return -EAGAIN upwards in the worst case.  --sct
	 */
	if (!err)
		err = ext4_splice_branch(handle, inode, map->m_lblk,
					 partial, indirect_blks, count);
	if (err)
		goto cleanup;

	map->m_flags |= EXT4_MAP_NEW;

	ext4_update_inode_fsync_trans(handle, inode, 1);
got_it:
	map->m_flags |= EXT4_MAP_MAPPED;
	map->m_pblk = le32_to_cpu(chain[depth-1].key);
	map->m_len = count;
	if (count > blocks_to_boundary)
		map->m_flags |= EXT4_MAP_BOUNDARY;
	err = count;
	/* Clean up and exit */
	partial = chain + depth - 1;	/* the whole chain */
cleanup:
	while (partial > chain) {
		BUFFER_TRACE(partial->bh, "call brelse");
		brelse(partial->bh);
		partial--;
	}
out:
	trace_ext4_ind_map_blocks_exit(inode, map->m_lblk,
				map->m_pblk, map->m_len, err);
	return err;
}

int ext4_map_blocks(handle_t *handle, struct inode *inode, struct ext4_map_blocks *map, int flags)
{
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;

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

### Linux EXT4 文件系统特性 EXT4是第四代扩展文件系统,在Linux系统下作为日志文件系统存在,继承并改进了ext3文件系统的功能[^1]。主要特性如下: - **更大的存储容量**:支持超过16TB的单个文件大小和1EB(Exabyte)级别的文件系统总量。 - **更快的速度**:通过多分配(multiblock allocation)、延迟分配(delayed allocation),减少磁盘碎片化程度,从而提升读写效率[^3]。 - **更可靠的数据保护机制**:提供元数据校验和等功能来增强数据完整性。 ### 工作原理 EXT4采用了一系列技术手段优化其性能表现与可靠性: - 日志记录(Logging): 所有更改都会先记入日志再应用到实际位置上,这有助于防止意外断电等情况造成损坏。 - 多分配(Multi-block Allocation): 当创建新文件时一次性分配多个连续簇给该文件而不是逐个分配,减少了索引节点更新次数。 - 延迟分配(Delayed Allocation): 不立即为待写入的数据分配物理地址直到真正需要刷盘为止,这样可以更好地组织这些即将落地的信息流以降低碎片率。 ### 性能测试方法 为了评估EXT4文件系统的性能状况,可以通过多种方式来进行测量分析: #### 使用`fio`工具执行I/O负载模拟 `fio`是一款灵活强大的IO测试工具, 可用于生成各种类型的IO模式并对结果进行统计汇总. ```bash sudo apt-get install fio fio --name=test --rw=randwrite --bs=4k --size=2G --numjobs=8 --runtime=60 --group_reporting ``` 此命令设置了一个随机写的场景,其中每个线程负责向指定目录下的临时文件发起请求;参数含义分别为名称(name), 读写类型(rw=random write), 数据尺寸(bs=block size), 测试规模(size), 并发数(numjobs), 运行时间(runtime). #### 利用内置命令清理未使用的空间 定期运行`fstrim`指令可帮助释放已删除文件占用的空间,并改善SSD设备上的长期使用体验[^2]. ```bash sudo fstrim / ``` 上述操作会针对根路径(/)所指向的具体挂载点实施处理动作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值