美文网首页
2020-08-25 linux中dentry的理解

2020-08-25 linux中dentry的理解

作者: 昨天今天下雨天1 | 来源:发表于2020-08-25 10:33 被阅读0次

inode仅仅只是保存了文件对象的属性信息,包括:权限、属组、数据块的位置、时间戳等信息。但是并没有包含文件名,文件在文件系统的目录树中所处的位置信息。那么内核又是怎么管理文件系统的目录树呢?答案是目录项。

目录项在内核中起到了连接不同的文件对象inode的作用,进而起到了维护文件系统目录树的作用。dentry是一个纯粹的内存结构,由文件系统在提供文件访问的过程中在内存中直接建立(并没有实际对应的磁盘上的描述)。

struct dentry

{

/* RCUlookup touched fields */

unsignedint d_flags;/*protected by d_lock */

seqcount_t d_seq;/*per dentry seqlock */

struct hlist_bl_noded_hash;/* lookup hash list */

struct dentry *d_parent;/*parent directory */

struct qstrd_name;                                //目录项名称

struct inode *d_inode;                             /* Where the name belongsto - NULL is negative */

unsignedchar d_iname[DNAME_INLINE_LEN];/*small names */

 

/* Reflookup also touches following */

struct lockrefd_lockref;/* per-dentry lock and refcount */

conststruct dentry_operations *d_op;

struct super_block *d_sb;/*The root of the dentry tree */

unsignedlong d_time;/*used by d_revalidate */

void*d_fsdata;/*fs-specific data */

 

struct list_headd_lru;/* LRU list */

struct list_headd_child;/* child of parent list */

struct list_headd_subdirs;/* our children */

/*

*d_alias and d_rcu can share memory

*/

union

{

struct hlist_noded_alias;/* inode alias list */

struct rcu_headd_rcu;

} d_u;

};

在内存中,每个文件都有一个dentry(目录项),dentry记录文件名、父目录、子目录等信息,形成文件树结构。而且每个dentry都有一个唯一对应的inode,而每个inode则可能有多个dentry(这种情况是由ln硬链接产生的)。

[root@localhostnewtest]# tree

.

├──subtest

│   └──subtest.py

└──test.py

 

1 directory, 2 files

[root@localhostnewtest]# ls -i

131074subtest  131075 test.py

[root@localhostnewtest]#

[root@localhostnewtest]# ls -i subtest/subtest.py

131076subtest/subtest.py

Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。

文件读取过程
文件由文件名、文件属性和数据组成。文件的inode中不包含文件的名字,文件的名字位于存放文件所在的目录中,在目录中通过查看目录项,因为每个目录项包含两项信息,即这个目录中的文件名字及对应的inode编号,通过这种对应关系找到文件。

具体来说VFS在查找的时候,根据一层一层的目录项找到对应的每个目录项的inode,那么沿着目录项进行操作就可以找到最终的文件。又inode储存有一些指针,这些指针指向存储设备中的一些数据块,文件的内容就储存在这些数据块中。当Linux想要打开一个文件时,只需要找到文件对应的inode,然后沿着指针,将所有的数据块收集起来,就可以在内存中组成一个文件的数据了。

image.png

例如:cat一个文件/newtest/subtest/subtest.py时(/、newtest、subtest、subtest.py都是一个目录项),它的查找过程如下

系统通过挂载信息(在超级块中,位置固定)找到根目录(/)的inode编号,根目录对应的inode是固定的。在dentry中找到对应的inode信息,从inode信息中找到存储根目录信息的数据块。

从目录块中存储的信息中,找到文件名(目录名)为newtest所对应的inode编号,如

[[root@localhostnewtest]# ls -i /

     17 bin     1025 dev        13 lib         11 lost+found   131073

newtest   786433 root  2883585 srv   262145 tmp

      2 boot 4325377 etc        15 lib64  1048577 media       5242881 opt         8199 run         1 sys  6029313 usr

7995393d1    4980737 home  1310721 logs  3145729 mnt               1 proc          16 sbin   655361 test  917505 var

[root@localhostnewtest]#

找到newtest的inode编号后,从该inode信息中,找到newtest目录存放的数据块,再从该数据块存储的信息中,找到subtest目录对应的inode编号

[root@localhostnewtest]# ls -i

131074 subtest 131075 test.py

重复上述步骤,直至找到test.py文件对应的inode结点,根据inode结点中记录的message文件内容对应的数据块,从数据块中读取内容。

写入文件的过程
当我们写入一个文件时,是分配一个空白inode给该文件,将其inode编号记入该文件所属的目录,然后选取空白的数据块,让inode的指针指像这些数据块,并放入内存中的数据。

删除文件
实质上就是减少link count,当link count为0时,就表示这个Inode可以使用,并把Block标记为可以写,但并没有清除Block里面数据,除非是有新的数据需要用到这个block。

相关文章

网友评论

      本文标题:2020-08-25 linux中dentry的理解

      本文链接:https://www.haomeiwen.com/subject/vtmajktx.html