inode 索引结点算法,EXT4 源码解析

Linux内核学习:EXT4 INode在磁盘上的读写 目录 1 关于Ext4系统的一些概念 1.1 Inode与Data Block 1.2 关于上述概念的规律 2 查找Inode在磁盘的位置 2.1 关于Inode操作的数据结构 2.2 Ext4在磁盘上Inode分配的策略分析 2.3.1目录的Inode分配策略 2.3.2文件的inode分配策略 2.3 Inode分配情况 2.3.1 磁盘块上的Inode分配 3 ex... 阅读详情


inode 中存储了文件的元信息,其中涉及了逻辑地址向物理地址的转换。linux 上用15个指针数组存储,其中12个是直接索引,后面三个分别是一级索引、二级索引和三级索引。如下图示。

(图片源自 https://upload.wikimedia.org/wikipedia/commons/a/a2/Ext2-inode.gif)

以linux-4.17.1 源码为例,为了便于理解,我将相关定义从各文件中拷过来,其中转换部分 ext4_block_to_path 函数的代码如下:

// ---------------------------------------------------------------------
// linux-4.17.1/fs/ext4/ext4.h

/*
 * Macro-instructions used to manage several block sizes
 */
#define EXT4_MIN_BLOCK_SIZE		1024
#define	EXT4_MAX_BLOCK_SIZE		65536
#define EXT4_MIN_BLOCK_LOG_SIZE		10
#define EXT4_MAX_BLOCK_LOG_SIZE		16
#define EXT4_MAX_CLUSTER_LOG_SIZE	30
#ifdef __KERNEL__
# define EXT4_BLOCK_SIZE(s)		((s)->s_blocksize)
#else
# define EXT4_BLOCK_SIZE(s)		(EXT4_MIN_BLOCK_SIZE << (s)->s_log_block_size)
#endif
#define	EXT4_ADDR_PER_BLOCK(s)		(EXT4_BLOCK_SIZE(s) / sizeof(__u32))

// sbi->s_addr_per_block_bits = ilog2(EXT4_ADDR_PER_BLOCK(sb)); // linux-4.17.1/fs/ext4/super.c
#define	EXT4_ADDR_PER_BLOCK_BITS(s)	(EXT4_SB(s)->s_addr_per_block_bits)

/*
 * Constants relative to the data blocks
 */
#define	EXT4_NDIR_BLOCKS		12
#define	EXT4_IND_BLOCK			EXT4_NDIR_BLOCKS
#define	EXT4_DIND_BLOCK			(EXT4_IND_BLOCK + 1)
#define	EXT4_TIND_BLOCK			(EXT4_DIND_BLOCK + 1)
#define	EXT4_N_BLOCKS			(EXT4_TIND_BLOCK + 1)

// ---------------------------------------------------------------------
// linux-4.17.1/fs/ext4/indirect.c


/**
 *	ext4_block_to_path - parse the block number into array of offsets
 *	@inode: inode in question (we are only interested in its superblock)
 *	@i_block: block number to be parsed
 *	@offsets: array to store the offsets in
 *	@boundary: set this non-zero if the referred-to block is likely to be
 *	       followed (on disk) by an indirect block.
 *
 *	To store the locations of file's data ext4 uses a data structure common
 *	for UNIX filesystems - tree of pointers anchored in the inode, with
 *	data blocks at leaves and indirect blocks in intermediate nodes.
 *	This function translates the block number into path in that tree -
 *	return value is the path length and @offsets[n] is the offset of
 *	pointer to (n+1)th node in the nth one. If @block is out of range
 *	(negative or too large) warning is printed and zero returned.
 *
 *	Note: function doesn't find node addresses, so no IO is needed. All
 *	we need to know is the capacity of indirect blocks (taken from the
 *	inode->i_sb).
 */
/*
 * Portability note: the last comparison (check that we fit into triple
 * indirect block) is spelled differently, because otherwise on an
 * architecture with 32-bit longs and 8Kb pages we might get into trouble
 * if our filesystem had 8Kb blocks. We might use long long, but that would
 * kill us on x86. Oh, well, at least the sign propagation does not matter -
 * i_block would have to be negative in the very beginning, so we would not
 * get there at all.
 */
static int ext4_block_to_path(struct inode *inode,
			      ext4_lblk_t i_block,
			      ext4_lblk_t offsets[4], int *boundary)
{
	int ptrs = EXT4_ADDR_PER_BLOCK(inode->i_sb); // 1024/4=256
	int ptrs_bits = EXT4_ADDR_PER_BLOCK_BITS(inode->i_sb); // ilog2(256)=8
	const long direct_blocks = EXT4_NDIR_BLOCKS, // 12
		indirect_blocks = ptrs, // 256
		double_blocks = (1 << (ptrs_bits * 2)); // 2^16=65536
	int n = 0;
	int final = 0;

	if (i_block < direct_blocks) { // i_block< 12
		offsets[n++] = i_block; // offset[0]=i_block
		final = direct_blocks; // final = 12
	} else if ((i_block -= direct_blocks) < indirect_blocks) { // i_block -= 10; i_block < 256
		offsets[n++] = EXT4_IND_BLOCK; // offset[0] = 12
		offsets[n++] = i_block; // offset[1] = i_block
		final = ptrs; // final = 256
	} else if ((i_block -= indirect_blocks) < double_blocks) { // i_block-= 256; i_block <65536
		offsets[n++] = EXT4_DIND_BLOCK; // offset[0]=12
		offsets[n++] = i_block >> ptrs_bits; // offset[1] = i_block/256 的商
		offsets[n++] = i_block & (ptrs - 1); // offset[2] = i_block/256 的余数
		final = ptrs; // final =256
	} else if (((i_block -= double_blocks) >> (ptrs_bits * 2)) < ptrs) { // i_block -= 65536; i_block/256/256 < 256
		offsets[n++] = EXT4_TIND_BLOCK; // offsets[0] = 12
		offsets[n++] = i_block >> (ptrs_bits * 2); // offset[1] = i_block/256/256 的商
		offsets[n++] = (i_block >> ptrs_bits) & (ptrs - 1); // offset[2] = i_block/256)256 的余数
		offsets[n++] = i_block & (ptrs - 1); // offset[3]=i_block/256的余数
		final = ptrs; // final = 256
	} else {
		ext4_warning(inode->i_sb, "block %lu > max in inode %lu",
			     i_block + direct_blocks +
			     indirect_blocks + double_blocks, inode->i_ino);
	}
	if (boundary)
		*boundary = final - 1 - (i_block & (ptrs - 1)); // final - 1 - i_block/256 的余数
	return n;
}

参考资料:
[1] inode. https://en.wikipedia.org/wiki/Inode
[2] inode pointer structure. https://en.wikipedia.org/wiki/Inode_pointer_structure
[3] Ext3 for large filesystems. [Posted June 12, 2006 by corbet] . https://lwn.net/Articles/187321/
[4] 《Unix 操作系统设计》.Maurice J. Bach 著, 陈葆珏, 王旭, 柳纯录, 冯切山译
[5] 《Operating System Concepts》. Avi Silberschatz, Peter Baer Galvin, Greg Gagne

ext4日志系统分析(二) 一、背景上篇博客介绍了jbd2模块的安装与卸载。同时也讲了安装时初始化函数会在/proc/fs下创建一个jbd2目录。这篇博客打算介绍一下在jbd2模块被安装后内核是如何对日志系统进行初始化的,以及jbd2目录下的文件是从哪里来的。这里所涉及的东西较多,所以我只挑重点功能函数来讲。二、jbd2目录不知道大家还记得吗,上一篇博客我提到在安装jbd2模块时,内核会在/proc/fs下创建一个jbd2目录 阅读详情

相关推荐

Linux文件系统inode:从EXT2到EXT4的演进

本文旨在系统性地介绍Linux文件系统中inode的概念及其在EXT2、EXT3和EXT4文件系统中的演进过程。我们将探讨inode如何作为文件系统的核心数据结构,以及EXT系列文件系统如何通过不断优化inode来提升整体性能。文章首先介绍inode的基本概念,然后详细分析EXT2、EXT3和EXT4中inode的实现差异,最后探讨实际应用和未来发展趋势。inode:索引节点(index node),用于存储文件元数据的数据结构EXT。

操作系统内核探秘的博客 999

【linux内核分析-存储】EXT4源码分析之“块分配算法分析”(1)主体流程

EXT4源码分析之“块分配算法分析”(1)主体流程,系列的第一篇文章,主要介绍块分配算法的主要流程以及一些细节点,如快速提交重放、简单分配器、配额文件、延迟分配、分配上下文。

ATFWUS的博客 1万+

ext4文件系统源码

包含完整的ext4文件系统的源代码,提供给大家学习和参考。

linux ext4 inode,Ext4文件系统中inode数量的限制

使用df -i命令可以查看系统中各个文件系统最大的Inodes数量以及当前已经使用的数量某个分区df以及df -i的输出Filesystem 1K-blocks Used Available Use% Mounted on/dev/diskA2 975372712 15957716 910617240 2% /usr/localFilesyst...

weixin_29240711的博客 2567

ext4-util源代码——制作make_ext4fs和simg2img工具

使用该工具可以直接将image文件载入ext4分区,安卓刷机必备,android

CSV文件输入到simulink中

将示波器波形和数据CSV文件保存下来进行数据分析。将波形绘制到simulink中

yay0923的博客 5327

ext4 extent详解2之内核源码详解

ext4 extent内核源码详解

dongzhiyan_hjp 3264

PaddleOCR实战:从零开始打造专属OCR模型的完整指南

本文提供了一份从零开始使用PaddleOCR打造专属OCR模型的完整实战指南。内容涵盖环境搭建、数据标注与准备、模型训练与调优,以及最终的模型转换与部署。重点介绍了如何利用PaddleOCR进行模型训练,并整合PPOCRLabel等工具高效准备数据集,帮助开发者快速构建适用于特定场景的高精度OCR识别能力。

rl6adventurer的博客 733

【Linux实验室】测试ext4文件系统的最大inode数量

安装操作系统或格式化磁盘分区的时候,操作系统会自动把磁盘分区分为两个区域 : Block存储区 和 inodes 存储区。Block存储区主要存储文件的内容,inodes存储区是由许多的inode组成的列表,每个 inode 中存储 文件元信息(文件大小,创建者,创建时间等)inode 是一种数据结构,用来存储文件以下的信息:1、文件大小2、文件类型(常规文件、目录、软连接等)3、权限(读写执行权限)4、属主(所属用户)5、属组(所属用户组)

翡翠泪滴的博客 1190

MTK Tunning ISP 模块面试总结

ISP面试问答

m0_72053187的博客 4540

基于图像分割的LIDC-IDRI 数据集预处理之数据下载篇

近期接触到了一个关于图像分割实验项目,关于数据预处理部分在此予以记录,和大家分享。

qq_67696694的博客 1904

ext4_dirty_inode与ext4_do_update_inode函数详解

一、ext4_dirty_inode 定义在fs/ext4/inode.c中,其内容如下: void ext4_dirty_inode(struct inode *inode, int flags) {     handle_t *handle;     if (flags == I_DIRTY_TIME)         return;     handle = ext4_journ...

SweeNeil 2503

Yolov5自学笔记之一--从入门到入狱,功能强大不要乱用(实现yolov5的基本功能使用流程及训练自己的数据集)

零基础自学yolov5,学会简单使用和训练自己的数据集,在自己工作中使用

qq_41597915的博客 1万+

ext4文件系统 文件/目录创建ext4_create/ext4_mkdir 函数源码解析

文件/目录创建函数ext4_create /ext4_mkdir,还有ext4_add_entry、__ext4_new_inode、find_group_orlov、find_group_other、ext4_getblk、ext4_mark_inode_dirty函数源码

dongzhiyan_hjp 2251

别再让步进电机‘发烧’了!用FOC闭环驱动实现精准力矩控制(基于P0斩波恒流版)

本文详细介绍了如何利用FOC闭环驱动技术(基于P0斩波恒流版)解决步进电机过热和力矩控制不精准的问题。通过对比传统开环控制的缺陷,展示了FOC在降低温度、提升精度和能效方面的显著优势,并提供了硬件配置、软件实现及性能优化的完整方案。

weixin_30872157的博客 567

YOLO26改进策略【小目标改进】| 添加专用于小目标的检测层 附YOLOv1~YOLOv11的检测头变化详解

在目标检测领域,小目标检测一直是一个具有挑战性的问题。算法以其高效快速的特点受到广泛关注,然而在面对小目标时,仍存在一些局限性。本文将介绍如何在中添加小目标检测层,以提高对小目标的检测能力。原始模型结构如下: 二、有效特征层对应的检测头类别 2.1 P3/8 - small检测头 原始模型中的对应的检测头主要用于检测相对较小的目标。其特征图大小相对较大,空间分辨率较高。 适合检测尺寸大概在到像素左右的目标。 2.2 P4/16 - medium检测头 这个检测头对应的经过了更多的下采样操作,相比P3/

Limiiiing的博客 353

【linux内核分析-存储】EXT4源码分析之“创建文件”原理

EXT4源码分析之“文件创建”原理,详细的介绍文件创建的核心流程,并对EXT4中关于文件创建的关键函数进行了分析。

ATFWUS的博客 1万+

DDD系列 - 第12讲 如何在DDD中实现Query服务(轻量化CQRS)

轻量化CQRS、整合Repository和DAO的优势。

罗小爬的技术宝书 267

ext4文件系统之文件查找ext4_lookup函数源码解析

网上讲解ext4的文章挺多的,但是讲解ext4源码的文章很少。本文首先介绍ext4磁盘布局,然后讲解文件查找函数ext4_lookup源码

dongzhiyan_hjp 3462

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【linux内核分析-存储】EXT4源码分析之“文件删除”原理【七万字超长合并版】(源码+关键细节分析)

EXT4源码分析之“文件删除”原理【七万字超长合并版】(源码+关键细节分析),详细的跟踪了ext4文件删除的核心调用链,分析关键函数的细节,解答了开篇中提出的三个核心疑问。

ATFWUS的博客 1万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

ContainerizationEXT4 源码全解析:在 macOS 上用 Swift 读取与格式化 ext4 块设备

`ContainerizationEXT4` 是 Containerization(在 macOS 上运行 Linux 容器的 Swift 包)中的磁盘格式模块,它实现了两件核心事情:**读取现有 ext4 块设备的超级块(superblock)**,以及**将一块空白块设备格式化为可用的 ext4 文件系统**。本文以该模块的官方 README 与文档注释为主体,结合仓库源码与测试,从磁盘布局、

gitblog_00689的博客 704

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Ext4文件系统架构分析(四) ——ioctl源码分析之设置/获取Inode标志位

1. EXT4_IOC_GETFLAGS获取inode标志位 Ext4的EXT4_IOC_GETFLAGS命令用于获取inode已设置的标志信息,将获取的inode标志位的信息的结果传给ioctl的第三个参数unsigned int arg: ioctl(fd, EXT4_IOC_GETFLAGS, arg ) 2. EXT4_IOC_SETFLAGS设置inode标志位 Ext4...

有趣的人生 一半是山川湖海 一半是初心情怀 736

系统性学习Ext4文件系统(图例解析)

一个的Ext4文件系统被分成一系列块组。为减少磁盘碎片产生的性能瓶颈,块分配器尽量保持每个文件的数据块都在同一个块组中,从而减少寻道时间。以4KB的数据块为例,一个块组可以包含32768个数据块,也就是128MB。

m0_74282605的博客 2348

浅谈EXT2文件系统----inode table

在 EXT2 文件系统中,inode 表(Inode Table)是一个非常重要的结构,用于存储文件和目录的元数据。每个文件和目录都由一个 inode(索引节点)来表示,inode 中包含了关于该文件或目录的关键信息,如文件的大小、权限、所属用户、时间戳以及指向数据块的指针等。EXT2 文件系统将所有 inode 结构集中存储在 inode 表中。ext2_inode结构体详细描述了在ext2文件系统中如何存储文件的元数据信息,包括文件的权限、大小、时间戳、数据块指针以及针对不同操作系统的定制字段。

zyqash的博客 1395

ext4 extent详解3之内核源码流程讲解

ext4 extent 源码+举例 详解

dongzhiyan_hjp 2638

ext4 delay allocation之ext4_writepages页回写源码剖析

ext4 write写入pagecache之后,再合适的时机会回写到磁盘,ext4文件系统中是通过ext4_writepages写入磁盘,本来将在源码角度分析该过程。建议先参照ext4 - delay allocation数据结构_nginux的博客-优快云博客看下涉及的重要数据结构。

GetnextWindow的专栏 1152
上一篇: R 创建地区热力图
下一篇: Java 多线程通过 Mybatis 获取 Oracle 序列值重复问题处理
rootcn
博客等级 码龄23年 27粉丝 91原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值