Linu fs 中元数据使用技术机制

上传人:工**** 文档编号:562861451 上传时间:2024-01-04 格式:DOCX 页数:12 大小:23.66KB
返回 下载 相关 举报
Linu fs 中元数据使用技术机制_第1页
第1页 / 共12页
Linu fs 中元数据使用技术机制_第2页
第2页 / 共12页
Linu fs 中元数据使用技术机制_第3页
第3页 / 共12页
Linu fs 中元数据使用技术机制_第4页
第4页 / 共12页
Linu fs 中元数据使用技术机制_第5页
第5页 / 共12页
点击查看更多>>
资源描述

《Linu fs 中元数据使用技术机制》由会员分享,可在线阅读,更多相关《Linu fs 中元数据使用技术机制(12页珍藏版)》请在金锄头文库上搜索。

1、在Linux文件系统中,元数据的引用计数主要用于管理元数据(如inode, dentry结构)在内存 中的创建、使用和释放。了解这部分的机制,有利于深入认识文件系统的运行机制,以及Linux如何在内 存中管理元数据。这部分内容也是构建分布式文件系统所必须的知识,由此才能保证元数据在分布式文件 系统中的正确使用。概述元数据是一个文件系统的重要部分。很多书籍和文章都介绍过dentry和inode在Linux中的作 用和机制,但却很少有文献涉及到它们的使用计数(usage counter )。使用计数的机制看似很简单:使 用了一个元数据就递增,用完了就递减。但在这句简单的描述后面,具体的过程到底是如

2、何进行的呢?这 实际上贯穿了整个元数据的操作以及元数据在内存中的管理。了解这部分的机制,是一个很有意思的过程, 可以让你看到Linux严谨缜密的思路,可以深入认识Linux文件系统的运行机制。这部分内容也是构建 分布式文件系统所必须的知识。本文仍然从两方面来介绍使用计数:增加和减少。最后再看一下在分布式环境中有哪些变化。这里所引用的代码依据的是Linux内核2.6.20的版本。使用计数的增加创建操作元数据的创建主要可以分为对文件的创建和对目录的创建。不管是文件还是目录,它们都对应同样 的元数据结构,在内存中都有inode和dentry。下面我们分别看一下主要的两个创建操作:创建文件和创建目录。

3、(1)创建文件创建文件是通过系统调用sys_open(),并设置0_CREATE标志位来实现的。其调用过程如下:sys_open()do_sys_open()do_filp_open()open_namei()在open_namei()中,会创建出dentry和inode结构。先看关于dentry的路径:open_namei()lookup_hash()_lookup_hash()这里会分成3种情况:在 dcache 中查找:_lookup_hash()cached_lookup()d_lookup()_d_lookup()分配新的 dentry: _lookup_hash()d_alloc(

4、)atomic_set(&dentry - d_count, 1);在具体文件系统中查找: lookup_hash()i_op - lookup()和查找有关的内容我们在后面介绍,这里只看创建,也就d_alloc(), 它会分配一个新的dentry结构,在分配的过程中,就会把dentry的使用计数初始化为1。在d_alloc() 中,还会通过函数dget()递增父目录的使用计数,这是为了防止父目录在该dentry删除前被删除。(“/”除外,它没有父目录):d_alloc()dget(parent)atomic_inc(&dentry-d_count);我们再看关于inode的路径:open_n

5、amei()open_namei_crea te()vfs_crea te()i_op-crea te()最终会调用具体文件系统的create函数。这里以Ext2为例,其调用过程如下:ext 2_crea te()ex t2_new_inode()new_inode()alloc_inode()a to mic_se t(& inode-i_count,1);具体文件系统在分配inode结构的时候,会通过初始化把inode的i_count域置为1。同时还把 inode的i_nlink域置为1,这个域表示inode的hard link的数目,其值会被写入到具体文件系统的 磁盘中。总结一下,通过创

6、建操作,会在内存中建立起dentry和inode结构,并且会把它们的使用计数都 初始化为1。(2)创建目录创建目录和创建文件是类似的,这里我们简单看一下调用的路径就清楚了。创建目录是通过系统调用sys_mkdir()来实现的。关于dentry的路径如下:sys_mkdir()sys_mkdira t()l ookup_crea te()lookup_hash() _lookup_hash()可以看出,这与前面“创建文件”中介绍的是一样的。关于inode的路径如下:sys_mkdir()sys_mkdira t() vfs_MkdiR()i_opMkdir()最终会调用具体文件系统的mkdir函

7、数。这里以Ext2为例,其调用过程如下:sys_mkdir()sys_mkdira t() vfs_mkdir()i_opmkdir()可以看出,这与前面“创建文件”中介绍的也是一样的。由此也可以看出,从内存中的元数据结构来看,Linux对文件和目录的管理是一样的。查找操作创建了一个对象(文件或目录)后,要使用这个对象,就必须先进行查找。查找操作是元数据使用 的关键操作,基本上所有元数据操作都会以查找操作为起始,因为只有找到了元数据才能进一步对其进行 操作。即使对于创建操作,一开始也要进行查找,只不过因为要创建的对象还不存在,所以会查找失败, 然后才进行创建。查找操作的入口函数是_link_p

8、ath_walk(),其调用过程如下:_link_pa th_walk()do_lookup()到了这里,要做的事情主要是在内存中查找相应文件所对应的dentry结构。这会分为两种情况:(1)该dentry结构在内存中此时,通过哈希就可以获取该dentry结构,并将其使用计数递增。do_lookup() _d_lookup()a to mic_inc(&dent ryd_cou nt)(2)该dentry结构不在内存中此时,该dentry结构可能从来就没在内存中建立起来,或者在内存中存在过,但已经从LRU队列 dentry_unused中被换出内存。无论如何,都需要从磁盘读取元数据,在内存中建

9、立起dentry和inode结 构。这时所进行的步骤是:首先在内存中分配一个dentry结构:do_lookup() _d_lookup()a to mic_inc(&dent ryd_cou nt)这里的d_alloc()和前面创建操作”介绍的一样,会把dentry的使用计数初始化为1,并将其 父目录的使用计数通过dget()递增。分配了 dentry结构后,就要从磁盘找出对应的元数据。这个过程因文件系统而异,所以通过父节 点的inode i_op里的函数来进行。do_lookup() _d_lookup()a to mic_inc(&dent ryd_cou nt)这里以Ext2为例,调用

10、的是ext2_create(),过程如下:(1) ext 2_lookup()ige t( dir-i_sb,ino);(2)ext 2_lookup()d_splice_alias() _d_find_alias() _dge t_ locked() atomic_inc(&dentry-d_count);前者调用iget(),首先通过ino在inode cache中查找inode,如果找到就返回并增加其引用 计数;如果没有找到,就分配一个新的(调用alloc_inode(),会把使用计数初始化为1,参照前面“创 建操作”),并从磁盘读入相应索引节点,在内存中建立起inode结构。后者则把d

11、entry与inode结构绑定,并递增了 dentry的使用计数。总结一下,查找操作的主要过程就是在内存中查找dentry结构,如果找到就递增其使用计数;如 果找不到就到磁盘中去取,并在内存建立dentry和inode结构,同时将它们的使用计数初始化为1。因 此查找操作都会增加dentry的使用计数,或者递增,或者初始化为1。元数据操作对使用计数的运用这里我们举例说明元数据操作对dentry使用计数的运用,让大家对其有个比较具体的认识和感觉。元数据操作的实质就是对元数据进行使用。那么,要使用某个元数据时,必须在内存中为其建立相 应的结构,即inode和dentry 。但并不是所有的元数据每时每

12、刻都会有对应的结构在内存中,只有需要 时才会建立这些结构,并且在特定的时候又会被换出内存。那么如何管理内存元数据结构的使用,从而决 定其何时在内存中,何时被换出,这就是通过dentry的使用计数来实现的。下面我们以两个常见的元数据操作为例,来看Linux如何管理内存元数据结构的使用。(1) getattr 操作Linux内核中有很多操作都会调用到getattr,我们举其中的一个来说明: sys_stat()vfs_stat_fd()。函数vfs_stat_fd()比较短,我们将其内容都列出来:int vfs_stat_fd(int dfd, char _user *name, struct k

13、stat*stat)struet nameidata nd;int error;error = _user_walk_fd(dfd, name, L00KUP_F0LL0W,&nd);if (!error) error = vfs_getattr(nd.mnt,nd.dentry, stat);path_release(&nd);return error;这里先调用了 _user_walk_fd(),这个函数继续走下去的路径是:_user_walk_fd()do_path_lookup()link_path_walk()_link_pa th_walk( )可以看出,link_path_wal

14、k()就是前面介绍过的查找操作。如果成功返回,就会增加dentry的 使用计数,否则就不增加。而如果查找成功,就进行具体的getattr的工作,调用的是vfs_stat_fd()的 主体函数vfs_getattr()。这之后,会调用path_release(),这个函数的路径是:_user_walk_fd()do_path_lookup()link_path_walk()_link_pa th_walk( )函数dput()会将dentry的使用计数减少,这个函数我们将在后面详细介绍。总结一下,getattr操作首先要查找元数据,找到后,就增加dentry的使用计数,只要dentry的 使用计

15、数不为0,它就会存在于deaehe中,而不会被换出内存。当getattr的主要操作步骤完成后,就 会减少dentry的使用计数,表明getattr操作已经完成,不再需要使用这个dentry 了。(2) link 操作下面再看一个操作。Link操作用于创建一个对象链接。其调用路径为: sys_link()sys_linka t()接下来可以分为七个部分:(1) error = _user_walk_fd(olddfd, oldname, flags &AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0,&old_nd);(2) error =do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);(3) new_dentry = lookup_crea te(&nd, 0);(4) error = vfs_link(old_nd.de nt ry,nd.de nt ry-d_inode, new_den try);(5) dput( new_de nt ry);(6)path_release(&nd);(7) path_release(&old_nd);第1步中,user_walk_fd()会查找要被链接的文件,这和前面getattr中的函数一样,会把这个文件对应的dentry的使用计数进行递增。它

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 学术论文 > 其它学术论文

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号