美文网首页
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