inode生命周期

1.添加inode到inode cache链表

当inode的引用计数器i_count为0后,会调用iput_final去释放

c 复制代码
static void iput_final(struct inode *inode)
{
	struct super_block *sb = inode->i_sb;
	const struct super_operations *op = inode->i_sb->s_op;
	unsigned long state;
	int drop;

	WARN_ON(inode->i_state & I_NEW);

	if (op->drop_inode)
		drop = op->drop_inode(inode);
	else
		drop = generic_drop_inode(inode);
	
	//引用计数为0之后,将inode放到lru中,等待回收
	if (!drop &&
	    !(inode->i_state & I_DONTCACHE) &&
	    (sb->s_flags & SB_ACTIVE)) {
		inode_add_lru(inode);
		spin_unlock(&inode->i_lock);
		return;
	}
	
	//对于已经被文件系统除名的文件,即i_nlink = 0, 不必再保留inode,直接释放掉
	WRITE_ONCE(inode->i_state, state | I_FREEING);
	if (!list_empty(&inode->i_lru))
		inode_lru_list_del(inode);
	spin_unlock(&inode->i_lock);

	evict(inode);
}

2.从inode cache中删除inode

在系统需要回收内存时,就会对这个链表下手,回收最近最少使用的inode。

c 复制代码
long prune_icache_sb(struct super_block *sb, struct shrink_control *sc)
{
	LIST_HEAD(freeable);
	long freed;
	//遍历超级块的s_inode_lru链表,按照回收控制结构sc指定的回收数量,
	//将可回收的inode隔离到freeable链表中集中回收
	freed = list_lru_shrink_walk(&sb->s_inode_lru, sc,
				     inode_lru_isolate, &freeable);
	//将隔离出来的inode进行回收,这样隔离后可以避免锁竞争
	dispose_list(&freeable);
	return freed;
}
c 复制代码
static void dispose_list(struct list_head *head)
{
	while (!list_empty(head)) {
		struct inode *inode;
		
		inode = list_first_entry(head, struct inode, i_lru);
		//将inode从超级块的s_inode_lru链表摘除
		list_del_init(&inode->i_lru);
		//回收inode
		evict(inode);
		cond_resched();
	}
}

static void evict(struct inode *inode)
{
	const struct super_operations *op = inode->i_sb->s_op;

	BUG_ON(!(inode->i_state & I_FREEING));
	BUG_ON(!list_empty(&inode->i_lru));
	//从bdi_writeback的b_io链表摘除
	if (!list_empty(&inode->i_io_list))
		inode_io_list_del(inode);
	//将inode从超级块的s_inodes链表摘除
	inode_sb_list_del(inode);

	//等待该inode回写完毕
	inode_wait_for_writeback(inode);
	//调用对应文件系统的evict_inode方法,回写pagecache
	if (op->evict_inode) {
		op->evict_inode(inode);
	} else {
		truncate_inode_pages_final(&inode->i_data);
		clear_inode(inode);
	}
	//如果是块设备inode
	if (S_ISBLK(inode->i_mode) && inode->i_bdev)
		bd_forget(inode);
	//如果是字符型设备
	if (S_ISCHR(inode->i_mode) && inode->i_cdev)
		cd_forget(inode);
	//从全局inode哈希表中摘除
	remove_inode_hash(inode);
	...
	//回收inode
	destroy_inode(inode);
}

处理完这些引用后,就可以调用destroy_inode回收到slab缓存,对于ext4,调用的是ext4_destroy_inode

c 复制代码
static void destroy_inode(struct inode *inode)
{
	BUG_ON(!list_empty(&inode->i_lru));
	__destroy_inode(inode);
	//调用对应文件系统的destroy_inode方法,将inode回收到slab缓存
	//对于ext4,调用的是ext4_destroy_inode
	if (inode->i_sb->s_op->destroy_inode)
		inode->i_sb->s_op->destroy_inode(inode);
	else
		call_rcu(&inode->i_rcu, i_callback);
}

static void ext4_destroy_inode(struct inode *inode)
{	
	if (!list_empty(&(EXT4_I(inode)->i_orphan))) {
		...
	}
	//调用ext4_i_callback将inode释放会slab缓存
	call_rcu(&inode->i_rcu, ext4_i_callback);
}

static void ext4_i_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	//释放回slab缓存
	kmem_cache_free(ext4_inode_cachep, EXT4_I(inode));
}

3.记忆

  • 等待回收:iput_final会把i_count为0的inode放入superblock的LRU链表s_inode_lru【这个链表也称为inode cache】中(inode_lru_list_add函数)
  • 正式回收:回收链表s_inode_lru中的节点,大致调用栈:evict->destroy_inode -> ext4_destroy_inode -> ext4_i_callback(释放slab缓存)
相关推荐
硅基手札7 分钟前
【Linux 内核专栏 19】20 · 嵌入式子系统 — GPIO·pinctrl·clock·regulator
linux·运维·单片机·linux内核·嵌入式开发·调试定位
默|笙25 分钟前
【Linux网络】传输层协议TCP(3)滑动窗口、流量控制
linux·网络·tcp/ip
Linux界最忧郁之人2 小时前
华为云ECS&IMS&AS实战|弹性云服务器、私有镜像、弹性伸缩完整实验
linux·运维·服务器·centos·华为云·openstack
whyutianict_vv2 小时前
零基础转 AI 运维:投入清单、技术路线与核对表
linux·运维·人工智能·ai
无言听风雨丶2 小时前
systemd 与信号 / 僵尸进程:Linux 进程管理的底层逻辑与排错
linux·服务器·网络
DevOpenClub3 小时前
高考一分一段 API:分数查位次、科类枚举与历史对照
linux·数据库·高考
小贾要学习3 小时前
【C++后端开发项目】Reactor 模型 / C++ 仿写 muduo HTTP 服务器:让底层网络库真正跑起网页
linux·服务器·c++·http·网络编程·muduo·reactor模型
Blockbuater_drug3 小时前
OpenMM分子动力学模拟02 安装:Linux:conda 一条命令装通 GPU 加速的分子模拟环境
linux·conda·cuda·gpu驱动·pythonpath·openmm安装
程序员JerrySUN3 小时前
PCIe Gen5 SSD 为什么读得快、写得慢?从存储原理到 Linux 性能实测
linux·服务器·网络
Android系统攻城狮3 小时前
Linux FFmpeg深度解析之avcodec_parameters_copy调用流程与实战(二十五)
linux·运维·服务器·ffmpeg·音视频·车载音频