日期:2014-05-16  浏览次数:20590 次

linux文件系统—inode及相关概念(转载)




?当一个文件系统被格式化成ext2或者ext3的时候,就会产生Inode number。大家注意到,在文件系统中每一个inode-no对应一个文件:例如图中对应的1-F1(文件名)、2-D1等等而每一个Inode-no对应一个inode-table,即图中下面部分的一张表首先我们看看,我们是怎么样读取和修改一个文件的:

1、我们首先根据文件名,找到这个文件的Inode-no(节点数)。
2、当我们找到个文件的Inode-no时,就会根据这个number数在inodetable中找到对应的条目。
3、现在要我们看一看inodetable中的信息:从左到右依次是:节点数、文件类型、文件的权限、硬链接数、用户ID、组ID、文件的大小、时间戳记,最后为指向硬盘上存放数据的数据块的指针。

简单说一下其中的某些项(文件类型大有7种):

-????????? 普通的文件
d????????? 目录
l????????? 链接文件
b????????? 块设备文件
c????????? 字符设备文件
p????????? 命名管道
s????????? socket文件

?????? 从这里我们也可以看出,在linux文件系统中,目录也是当作文件来看的!对于时间戳记有三种:存取时间,修改时间,变更时间 存取时间,为最后一次打开,或者是访问这个文件的时间; 而修改时间,为最后一次修改文件的时间; 当inodetable中的某项改变时,会更新变更时间。4、系统首先检查权限等信息,确定该用户可以访问该文件的时候,就会通过最后的指针找到实际的数据块,对文件进行存取。

硬链接和软链接的区别

?????? 文件系统维护着一个分区的索引节点表,索引节点也就是所谓的inode , 它其实就是代表这一个文件真实的数据块同样也记录着文件的其他属性如修改时间文件类型等,同样每个文件一般表示就是使用目录项(dirent) , 每个目录项包含着该文件的名字 ,该文件指向的inode节点标号等 ,记住linux把目录和文件都用目录项来表示,真实的文件类型是在inode节点里面新建一个硬连接,其实也就是新建一个目录项指向目标目录项指向的inode节点,一个inode节点可以指向多个目录项, 如果一个inode节点所引用的目录项计数不为0,该文件的真实数据是不会被释放的,当计数为零且没有进程使用时内核自动释放该文件的数据,所以如果删除了一个硬连接,也只是删除了一个目录项 ,如果那个inode节点还执行其他的目录项,该文件的真实数据是不会被删除的,其实我们平时删除一个文件实际上调用的操作也就是unlink,新建一个符号连接其实也新建了一个目录项,所以一个符号连接的名字可以和源目标不同,但这个符号连接的目录项里指向的inode节点里面的文件数据指针其实是指向该符号连接所引用的文件的真实地址, 如:

ln -s /etc/profile ./ss

这里ss只是该符号连接文件在目录项里面的名字,而该目录项里面inode节点里面的文件数据指针指向的数据就是"/etc/profile"这个路径值, 且inode节点里面的文件类型是符号连接,所以系统在使用这类文件时就知道读取符号连接文件的真实数据也就是源地址。

系统是不允许普通用户创建目录的硬连接,因为硬连接可能造成循环,这样的硬连接很难删除很容易造成文件系统的混乱,如下面的错误操作:

mkdir test
ln test test/test

只有root用户才能创建目录的硬连接。


(UNIX中运用inode来代表一个文件,inode在文件系统创建之初就被分配到硬盘的特定位置(大约占1%的空间),inode结构描述了一个文件的各种属性,最重要的是定位到了硬盘的某个块,实现了从软件到硬件的对应。inode的结构对不同的文件系统可能不一样,为了提高扩展性,保证一致的接口,UNIX运用了vnode,vnode指向具体的文件系统的inode。(Linux下有vnode吗,似乎有类似的实现,是否叫vnode,得看看代码)。总之,UNIX系统中对某个文件的访问经历了:由文件路径获取vnode,由vnode确定inode,由inode确定块的过程。)

?

?

?

?

?

?

?

?

1.索引节点对象struct inode<linux/fs.h>
??? 索引节点对象包含了内核在操作文件或目录时需要的全部元信息(meta data),注意,文件名不包含在inode中。对于Unix/Linux系统来说,这些信息可以从磁盘索引节点直接读入,而对于没有磁盘索引节点的文件系统,如FAT, NTFS;那么在内存中也必须现场组建索引节点对象。


2.目录项对象struct dentry<linux/dcache.h>
??? 路径中的每个组成部分都由一个索引节点对象表示,例如:/home/user/.vimrc,上面这个路径包含了4个目录项对象:/, home, user, .vimrc;需要注意的是:文件也是目录项对象。为了方便查找操作,VFS引入了目录项概念。每个dentry代表路径中的一个特定部分。目录项也可以包括安装点,VFS在执行目录操作时——如果需要的话——会现场创建目录项对象。
??? 不同于超级块和inode,目录项对象没有对应的磁盘数据结构,VFS根据字符串形式的路径名现场创建它;所以也不需要回写目录项对象。对于目录项的理解,有一点曾经迷惑过我。如下:

view plaincopy to clipboardprint?
/* linux/fs.h */?
struct inode {??
??? ...??
??? struct list_head i_dentry;??
??? ...??
};??
/* linux/dcache.h */?
struct dentry {??
??? ...??
??? struct inode *d_inode;??
??? ...??
};?
/* linux/fs.h */
struct inode {
??? ...
??? struct list_head i_dentry;
??? ...
};
/* linux/dcache.h */
struct dentry {
??? ...
??? struct inode *d_inode;
??? ...
};

结论:

??? 在inode结构中有一个双向链表struct list_head i_dentry结构,这个链表链接“被使用的”目录项,当然,这些目录项的d_inode指针都指向同一个inode结构。这代表什么呢?表示一个索引节点可以对应多个目录项对象。

分析:

??? 显然,要让一个索引节点表示多个目录项对象,肯定会使用文件链接,文件链接有两种类型,硬链接和符号链接(软链接)。使用ls -i可以查看文件的inode。执行一些简单操作如下:

$mkdir test_dir

然后执行

$ln $PWD/test_dir $PWD/test_dir_hardlink

显然,上面的命令会失败,因为硬链接不能指向目录,否则在文件系统中会形成环,另外,硬链接还不能跨文件系统,为什么呢?看了下面的命令就知道。

$touch test_file??????????????????????????????????????????????????????????????????? 建立一个文件

$ln $PWD/test_file $PWD/t