ext3、ext4 orphan inode机制分析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ext3、ext4的orphan inode机制分析

一、概述

orphan在英文中是孤儿的意思,在这里取被遗弃、被删除之意。

orphan inode是什么样的inode呢?这种inode是怎样产生的呢?

先介绍一个概念,文件的引用计数,准确地说应该是inode的引用计数,因为一般来说一个文件会对应

一个inode。文件的引用计数,简单地说是表示有多少个文件指向该文件,准确地说是文件的硬链接的个数。

情况1:设想一个进程,open一个文件,然后unlink该文件,然后进行文件读写。这是允许的,并且在进程退出时,内核会自动将引用计数为0的文件删除。

但是如果该进程尚未退出之前,系统崩溃了,那么,内核就没有机会将已被unlink、并且引用计数为0

的inode从磁盘上删除了。

情况2:设想我们正在截断一个大文件(系统调用truncate),但是操作尚未完成,系统就崩溃了。同样,内核也没有办法将该文件的所有数据块全部删除了。

ext3、ext4的orphan inode机制就是处理上述两种情况的。基本思想是这样的:如果要删除或截断一个inode,要先把这个inode记录到磁盘上的一个特殊的orphan inode链表上。如果删除或截断操作能够

正常完成,那么,就从磁盘上的orphan inode链表上删除该inode;否则,如果删除或截断操作未完成之前,系统就发生崩溃了,那么,系统重启后,文件系统会遍历磁盘上的orphan inode链表,对链表上的每一个inode都重新进行一遍删除或截断操作,以此来保证这些inode真正在磁盘上被删除,维护文

件系统的一致性。

内核版本:2.6.35

二、相关数据结构及之间的关系

先总体说一下orphan inode的组织。

orphan inode需要在两个地方组织,分别是在内存中和在磁盘上。不论在哪里,从抽象角度来看,orphan inode都被组织成一个单向链表。

1、ext4_inode

struct ext4_inode {

__le32 i_dtime; /* Deletion Time */

.........

}

这个是磁盘上的inode的结构,i_dtime本来表示该inode被删除的时间,在orphan inode机制中,因

为此时该域的值并不重要,故借用一下,用于记录下一个被unlink/truncate的inode号。

2、ext4_super_block

struct ext4_super_block {

__le32 s_last_orphan; /* start of list of inodes to delete */

.........

}

这个是磁盘上的superblock 结构。其中,s_last_orphan 记录的是最近一个被unlink/truncate 的inode 号,从抽象角度来看,它就代表磁盘上orphan inode 单链表的头。

新的inode 插入orphan inode 链表时采用“头插法”,也就是说,最近被unlink/truncate 的inode 号会放在s_last_orphan 中。

这样,磁盘上的orphan inode 单链表如下图1所示。

图1 磁盘上的orphan inode 链表结构图

3、ext4_inode_info

struct ext4_inode_info {

__u32 i_dtime;

struct list_head i_orphan; /* unlinked but open inodes */

.......

}

这个是内存中的inode 结构,即 磁盘上的ext4_inode 在内存中的表现。

其中,i_dtime 与ext4_inode 中的i_dtime 相对应,i_orphan 是个链表节点,用于在内存中组成orphan inode 链表。

4、ext4_sb_info

struct ext4_sb_info {

struct list_head s_orphan;

struct mutex s_orphan_lock;

.........

}

这个是内存中的superblock 结构,即磁盘上ext4_super_block 在内存中的表现。其中,s_orphan 代表链表头,s_orphan_lock 是用于保护链表的互斥锁。在内存中的orphan inode 链表结构与图1很类似,在此从略。

三、辅助函数

1、NEX T_ORPHAN(inode)

fs/ext4/ext4.h

1209 #define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime

这个宏的作用是在磁盘orphan inode链表上取得下一个orphan inode号。

2、ext4_orphan_g et()

1074 struct inode *ext4_orphan_g et(struct super_block *sb, unsi g ned lon g ino)

{ .......

1104 inode = ext4_i g et(sb, ino);

.......

}

这个函数的主要作用是根据一个inode号ino,从磁盘上将该inode的信息读入内存,保存在

ext4_inode_info结构中。

3、ext4_orphan_add()

1984 int ext4_orphan_add(handle_t *handle, struct inode *inode)

{

.......

// 将“下一个”最近的inode号保存在本inode的ext4_inode_info->i_dtime中

// 这样,当本inode写回磁盘时,会将“下一个”orphan inode号写回磁盘。

2030 NEX T_ORPHAN(inode)= le32_to_cpu(EX T4_SB(sb)->s_es->s_last_orphan);

// 将最近的inode号保存在ext4_super_block->s_last_orphan中,

// 这样,当本超级块写回磁盘时,会将最近的orphan inode号写回磁盘。

2031 EX T4_SB(sb)->s_es->s_last_orphan = cpu_to_le32(inode->i_ino);

.......

// 将内存中的ext4_inode_info结构链到ext4_sb_info->s_orphan链表的第一个位置。2046 if (!err)

2047 list_add(&EX T4_I(inode)->i_orphan,&EX T4_SB(sb)->s_orphan);

.......

}

总之,ext4_orphan_add()的作用是在内存中和磁盘上的orphan inode链表中分别添加一个inode节点。

相关文档
最新文档