Lab1.html 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <!DOCTYPE html>
  2. <html lang="en-US">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width,initial-scale=1">
  6. <title>文件系统 | 操作系统实验</title>
  7. <meta name="generator" content="VuePress 1.9.10">
  8. <meta name="description" content="Welcome!">
  9. <link rel="preload" href="/OS_lab_tutorial/assets/css/0.styles.dbcc0abd.css" as="style"><link rel="preload" href="/OS_lab_tutorial/assets/js/app.11bc9cdf.js" as="script"><link rel="preload" href="/OS_lab_tutorial/assets/js/2.3dc1b8de.js" as="script"><link rel="preload" href="/OS_lab_tutorial/assets/js/1.7f771cfb.js" as="script"><link rel="preload" href="/OS_lab_tutorial/assets/js/34.46f5bb23.js" as="script"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/10.23a1f579.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/11.c389195a.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/12.1d996921.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/13.4d4410c4.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/14.37ef2a72.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/15.5542c093.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/16.d48fd1ce.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/17.bd8d538c.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/18.6d3b94c1.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/19.eb35cfee.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/20.c11ec329.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/21.db1b5d88.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/22.bc10dbcb.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/23.da61e3a5.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/24.df968878.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/25.182a101f.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/26.abaed860.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/27.f53ecd1d.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/28.ce8973fe.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/29.13038134.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/3.5322f14a.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/30.8831ff4f.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/31.111c3df1.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/32.09d2c7bf.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/33.3ffbc094.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/35.194738b7.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/36.3597c59a.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/37.437db42a.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/38.2485c0ae.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/39.b4d5f235.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/4.84e1e480.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/40.1cf48109.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/41.88a9cd89.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/42.517be223.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/43.dc7c858f.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/44.ea49cfe0.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/45.020b5946.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/46.9e08647b.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/47.f9039b1a.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/48.2f547fd0.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/49.808c5013.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/5.f0541060.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/50.9a07e6b8.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/51.9590672f.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/52.72405151.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/53.1531273a.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/54.12a5d073.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/55.25860b43.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/56.f45c6ced.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/57.8bc5c8a2.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/58.4802c1c4.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/59.ee33963c.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/6.dfb06aa0.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/60.4aec6da7.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/61.f4291450.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/62.33242384.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/63.0baf087a.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/64.5ef98696.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/65.622dfe34.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/66.69329830.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/7.7551a9fb.js"><link rel="prefetch" href="/OS_lab_tutorial/assets/js/vendors~docsearch.5e19b665.js">
  10. <link rel="stylesheet" href="/OS_lab_tutorial/assets/css/0.styles.dbcc0abd.css">
  11. </head>
  12. <body>
  13. <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/OS_lab_tutorial/" class="home-link router-link-active"><!----> <span class="site-name">操作系统实验</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/OS_lab_tutorial/" class="nav-link">
  14. 首页
  15. </a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Linux" class="dropdown-title"><span class="title">Linux</span> <span class="arrow down"></span></button> <button type="button" aria-label="Linux" class="mobile-dropdown-title"><span class="title">Linux</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
  16. 实验教程
  17. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab1.html" class="nav-link">
  18. 实验1-熟悉类Linux系统
  19. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab2.html" class="nav-link">
  20. 实验2-进程创建与进程间通信
  21. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab3/" class="nav-link">
  22. 实验3-进程调度算法
  23. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab4/" class="nav-link">
  24. 实验4-存储管理算法
  25. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab5.html" class="nav-link">
  26. 实验5-文件管理系统
  27. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab6.html" class="nav-link">
  28. 实验6-网络编程(暂定)
  29. </a></li></ul></li><li class="dropdown-item"><h4>
  30. 课程练习
  31. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab1.html" class="nav-link">
  32. 实验1-熟悉类Linux系统
  33. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab2.html" class="nav-link">
  34. 实验2-进程创建与进程间通信
  35. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab3.html" class="nav-link">
  36. 实验3-进程调度算法
  37. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab4.html" class="nav-link">
  38. 实验4-存储管理算法
  39. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab5.html" class="nav-link">
  40. 实验5-文件管理系统
  41. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab6.html" class="nav-link">
  42. 实验6-网络编程(暂定)
  43. </a></li></ul></li><li class="dropdown-item"><h4>
  44. 附录
  45. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab1.html" class="nav-link">
  46. 实验1-熟悉类Linux系统
  47. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab2.html" class="nav-link">
  48. 实验2-进程创建与进程间通信
  49. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab3.html" class="nav-link">
  50. 实验3-进程调度算法
  51. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab4.html" class="nav-link">
  52. 实验4-存储管理算法
  53. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab5.html" class="nav-link">
  54. 实验5-文件管理系统
  55. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab6.html" class="nav-link">
  56. 实验6-网络编程(暂定)
  57. </a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="DragonOS" class="dropdown-title"><span class="title">DragonOS</span> <span class="arrow down"></span></button> <button type="button" aria-label="DragonOS" class="mobile-dropdown-title"><span class="title">DragonOS</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
  58. 实验教程
  59. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/DragonOS/Lab/Lab1.html" aria-current="page" class="nav-link router-link-exact-active router-link-active">
  60. 实验-文件系统
  61. </a></li></ul></li><li class="dropdown-item"><h4>
  62. 课程练习
  63. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/DragonOS/Assignment/Lab1.html" class="nav-link">
  64. 实验-文件系统
  65. </a></li></ul></li><li class="dropdown-item"><h4>
  66. 附录
  67. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/DragonOS/Appendix/Lab1.html" class="nav-link">
  68. 实验-文件系统
  69. </a></li></ul></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/OS_lab_tutorial/" class="nav-link">
  70. 首页
  71. </a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Linux" class="dropdown-title"><span class="title">Linux</span> <span class="arrow down"></span></button> <button type="button" aria-label="Linux" class="mobile-dropdown-title"><span class="title">Linux</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
  72. 实验教程
  73. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab1.html" class="nav-link">
  74. 实验1-熟悉类Linux系统
  75. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab2.html" class="nav-link">
  76. 实验2-进程创建与进程间通信
  77. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab3/" class="nav-link">
  78. 实验3-进程调度算法
  79. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab4/" class="nav-link">
  80. 实验4-存储管理算法
  81. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab5.html" class="nav-link">
  82. 实验5-文件管理系统
  83. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Lab/Lab6.html" class="nav-link">
  84. 实验6-网络编程(暂定)
  85. </a></li></ul></li><li class="dropdown-item"><h4>
  86. 课程练习
  87. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab1.html" class="nav-link">
  88. 实验1-熟悉类Linux系统
  89. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab2.html" class="nav-link">
  90. 实验2-进程创建与进程间通信
  91. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab3.html" class="nav-link">
  92. 实验3-进程调度算法
  93. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab4.html" class="nav-link">
  94. 实验4-存储管理算法
  95. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab5.html" class="nav-link">
  96. 实验5-文件管理系统
  97. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Assignment/Lab6.html" class="nav-link">
  98. 实验6-网络编程(暂定)
  99. </a></li></ul></li><li class="dropdown-item"><h4>
  100. 附录
  101. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab1.html" class="nav-link">
  102. 实验1-熟悉类Linux系统
  103. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab2.html" class="nav-link">
  104. 实验2-进程创建与进程间通信
  105. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab3.html" class="nav-link">
  106. 实验3-进程调度算法
  107. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab4.html" class="nav-link">
  108. 实验4-存储管理算法
  109. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab5.html" class="nav-link">
  110. 实验5-文件管理系统
  111. </a></li><li class="dropdown-subitem"><a href="/OS_lab_tutorial/Linux/Appendix/Lab6.html" class="nav-link">
  112. 实验6-网络编程(暂定)
  113. </a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="DragonOS" class="dropdown-title"><span class="title">DragonOS</span> <span class="arrow down"></span></button> <button type="button" aria-label="DragonOS" class="mobile-dropdown-title"><span class="title">DragonOS</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><h4>
  114. 实验教程
  115. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/DragonOS/Lab/Lab1.html" aria-current="page" class="nav-link router-link-exact-active router-link-active">
  116. 实验-文件系统
  117. </a></li></ul></li><li class="dropdown-item"><h4>
  118. 课程练习
  119. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/DragonOS/Assignment/Lab1.html" class="nav-link">
  120. 实验-文件系统
  121. </a></li></ul></li><li class="dropdown-item"><h4>
  122. 附录
  123. </h4> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/OS_lab_tutorial/DragonOS/Appendix/Lab1.html" class="nav-link">
  124. 实验-文件系统
  125. </a></li></ul></li></ul></div></div> <!----></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>文件系统</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/OS_lab_tutorial/DragonOS/Lab/Lab1.html#本章导读" class="sidebar-link">本章导读</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/OS_lab_tutorial/DragonOS/Lab/Lab1.html#dragonos文件系统的架构设计" class="sidebar-link">DragonOS文件系统的架构设计</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/OS_lab_tutorial/DragonOS/Lab/Lab1.html#虚拟文件系统" class="sidebar-link">虚拟文件系统</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/OS_lab_tutorial/DragonOS/Lab/Lab1.html#vfs的架构设计" class="sidebar-link">VFS的架构设计</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/OS_lab_tutorial/DragonOS/Lab/Lab1.html#file" class="sidebar-link">File</a></li><li class="sidebar-sub-header"><a href="/OS_lab_tutorial/DragonOS/Lab/Lab1.html#traits" class="sidebar-link">Traits</a></li><li class="sidebar-sub-header"><a href="/OS_lab_tutorial/DragonOS/Lab/Lab1.html#mountfs" class="sidebar-link">MountFS</a></li></ul></li><li><a href="/OS_lab_tutorial/DragonOS/Lab/Lab1.html#ramfs" class="sidebar-link">RamFS</a><ul class="sidebar-sub-headers"></ul></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="文件系统"><a href="#文件系统" class="header-anchor">#</a> 文件系统</h1> <h2 id="本章导读"><a href="#本章导读" class="header-anchor">#</a> 本章导读</h2> <p>本章意在介绍文件系统相关知识,包括虚拟文件系统、ramfs以及如何在用户程序对自己写的文件系统进行测试</p> <h2 id="dragonos文件系统的架构设计"><a href="#dragonos文件系统的架构设计" class="header-anchor">#</a> DragonOS文件系统的架构设计</h2> <p>首先,我们来总览一下DragonOS文件系统的架构设计。相关的机制主要包括以下几个部分:</p> <blockquote><ul><li><p>系统调用接口</p></li> <li><p>虚拟文件系统</p></li></ul> <blockquote><p>文件抽象(File)</p> <p>挂载文件系统(MountFS)</p></blockquote> <ul><li>具体的文件系统</li></ul></blockquote> <p>如图所示:</p> <p><img src="/OS_lab_tutorial/docs/.vuepress/public/DragonOS/DragonOS.png" alt="图片1" title="文件系统架构设计"></p> <p>其中我们可以看到,中间部分作为接口对多个并行的物理文件系统实例(每一个都叫做文件系统的实现)提供支持。这就是虚拟文件系统。</p> <h2 id="虚拟文件系统"><a href="#虚拟文件系统" class="header-anchor">#</a> 虚拟文件系统</h2> <p><code>虚拟文件系统</code>(Virtual File System,缩写为<code>VFS</code>)是计算机操作系统中的一个抽象层,它提供了文件系统的标准化接口,使得应用程序可以通过统一的方式访问各种不同类型的文件系统。</p> <p>其设计目的是将文件系统的实现细节与应用程序分离,使得应用程序可以独立于底层文件系统的具体实现方式。它定义了一组通用的文件操作接口,如打开文件、关闭文件、读取文件、写入文件等,应用程序可以通过这些接口来访问和操作文件,而无需关心文件系统的底层细节。例如,一个应用程序可以通过虚拟文件系统接口打开一个文件,而不需要关心这个文件是存储在本地磁盘上的普通文件,还是位于远程服务器上的网络文件。虚拟文件系统会将这些不同类型的文件系统映射到一个统一的文件层次结构中,使得应用程序可以以相同的方式访问这些文件。</p> <p>在<em>DragonOS</em>中,VFS作为适配器,遮住了具体文件系统之间的差异,对外提供统一的文件操作接口抽象。</p> <p>VFS是DragonOS文件系统的核心,它提供了一套统一的文件系统接口,使得DragonOS可以支持多种不同的文件系统。VFS的主要功能包括:</p> <blockquote><p>提供统一的文件系统接口</p> <p>提供文件系统的挂载和卸载机制(MountFS)</p> <p>提供文件抽象(File)</p> <p>提供文件系统的抽象(FileSystem)</p> <p>提供IndexNode抽象</p></blockquote> <h2 id="vfs的架构设计"><a href="#vfs的架构设计" class="header-anchor">#</a> VFS的架构设计</h2> <p><img src="/OS_lab_tutorial/docs/.vuepress/public/DragonOS/vfs_archi_design.png" alt="图片2" title="vfs架构设计"></p> <h3 id="file"><a href="#file" class="header-anchor">#</a> File</h3> <p><code>File</code>结构体是VFS中最基本的抽象,它代表了一个打开的文件。每当进程打开了一个文件,就会创建一个File结构体,用于维护该文件的状态信息。</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">/// @brief 抽象文件结构体</span>
  126. <span class="token keyword">pub</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">File</span> <span class="token punctuation">{</span>
  127. inode<span class="token punctuation">:</span> <span class="token class-name">Arc</span><span class="token operator">&lt;</span><span class="token keyword">dyn</span> <span class="token class-name">IndexNode</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
  128. <span class="token comment">/// 对于文件,表示字节偏移量;对于文件夹,表示当前操作的子目录项偏移量</span>
  129. offset<span class="token punctuation">:</span> <span class="token keyword">usize</span><span class="token punctuation">,</span>
  130. <span class="token comment">/// 文件的打开模式</span>
  131. mode<span class="token punctuation">:</span> <span class="token class-name">FileMode</span><span class="token punctuation">,</span>
  132. <span class="token comment">/// 文件类型</span>
  133. file_type<span class="token punctuation">:</span> <span class="token class-name">FileType</span><span class="token punctuation">,</span>
  134. <span class="token comment">/// readdir时候用的,暂存的本次循环中,所有子目录项的名字的数组</span>
  135. readdir_subdirs_name<span class="token punctuation">:</span> <span class="token class-name">Vec</span><span class="token operator">&lt;</span><span class="token class-name">String</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
  136. <span class="token keyword">pub</span> private_data<span class="token punctuation">:</span> <span class="token class-name">FilePrivateData</span><span class="token punctuation">,</span>
  137. <span class="token punctuation">}</span>
  138. </code></pre></div><h3 id="traits"><a href="#traits" class="header-anchor">#</a> Traits</h3> <p>对于每个具体文件系统,都需要实现以下的trait:</p> <p>FileSystem:表明某个struct是一个文件系统</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">trait</span> <span class="token type-definition class-name">FileSystem</span><span class="token punctuation">:</span> <span class="token class-name">Any</span> <span class="token operator">+</span> <span class="token class-name">Sync</span> <span class="token operator">+</span> <span class="token class-name">Send</span> <span class="token operator">+</span> <span class="token class-name">Debug</span> <span class="token punctuation">{</span>
  139. <span class="token comment">/// @brief 获取当前文件系统的root inode的指针</span>
  140. <span class="token keyword">fn</span> <span class="token function-definition function">root_inode</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">Arc</span><span class="token operator">&lt;</span><span class="token keyword">dyn</span> <span class="token class-name">IndexNode</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
  141. <span class="token comment">/// @brief 获取当前文件系统的信息</span>
  142. <span class="token keyword">fn</span> <span class="token function-definition function">info</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">FsInfo</span><span class="token punctuation">;</span>
  143. <span class="token comment">/// @brief 本函数用于实现动态转换。</span>
  144. <span class="token comment">/// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self</span>
  145. <span class="token keyword">fn</span> <span class="token function-definition function">as_any_ref</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token operator">&amp;</span><span class="token keyword">dyn</span> <span class="token class-name">Any</span><span class="token punctuation">;</span>
  146. <span class="token punctuation">}</span>
  147. </code></pre></div><p><code>IndexNode</code>: 表明某个struct是一个索引节点</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">trait</span> <span class="token type-definition class-name">IndexNode</span><span class="token punctuation">:</span> <span class="token class-name">Any</span> <span class="token operator">+</span> <span class="token class-name">Sync</span> <span class="token operator">+</span> <span class="token class-name">Send</span> <span class="token operator">+</span> <span class="token class-name">Debug</span> <span class="token punctuation">{</span>
  148. <span class="token comment">/// 以下陈列部分函数</span>
  149. <span class="token comment">/// @brief 打开文件</span>
  150. <span class="token comment">/// @return 成功:Ok()</span>
  151. <span class="token comment">/// 失败:Err(错误码)</span>
  152. <span class="token keyword">fn</span> <span class="token function-definition function">open</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">,</span> _data<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token class-name">FilePrivateData</span><span class="token punctuation">,</span> _mode<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token class-name">FileMode</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">Result</span><span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">SystemError</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
  153. <span class="token comment">// 若文件系统没有实现此方法,则返回“不支持”</span>
  154. <span class="token keyword">return</span> <span class="token class-name">Err</span><span class="token punctuation">(</span><span class="token class-name">SystemError</span><span class="token punctuation">::</span><span class="token constant">EOPNOTSUPP_OR_ENOTSUP</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  155. <span class="token punctuation">}</span>
  156. <span class="token comment">/// @brief 关闭文件</span>
  157. <span class="token comment">/// @return 成功:Ok()</span>
  158. <span class="token comment">/// 失败:Err(错误码)</span>
  159. <span class="token keyword">fn</span> <span class="token function-definition function">close</span><span class="token punctuation">(</span><span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">,</span> _data<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token class-name">FilePrivateData</span><span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">Result</span><span class="token operator">&lt;</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">SystemError</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
  160. <span class="token comment">// 若文件系统没有实现此方法,则返回“不支持”</span>
  161. <span class="token keyword">return</span> <span class="token class-name">Err</span><span class="token punctuation">(</span><span class="token class-name">SystemError</span><span class="token punctuation">::</span><span class="token constant">EOPNOTSUPP_OR_ENOTSUP</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  162. <span class="token punctuation">}</span>
  163. <span class="token comment">/// @brief 在inode的指定偏移量开始,读取指定大小的数据</span>
  164. <span class="token comment">/// @param offset 起始位置在Inode中的偏移量</span>
  165. <span class="token comment">/// @param len 要读取的字节数</span>
  166. <span class="token comment">/// @param buf 缓冲区. 请注意,必须满足@buf.len()&gt;=@len</span>
  167. <span class="token comment">/// @param _data 各文件系统系统所需私有信息</span>
  168. <span class="token comment">/// @return 成功:Ok(读取的字节数)</span>
  169. <span class="token comment">/// 失败:Err(Posix错误码)</span>
  170. <span class="token keyword">fn</span> <span class="token function-definition function">read_at</span><span class="token punctuation">(</span>
  171. <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">,</span>
  172. offset<span class="token punctuation">:</span> <span class="token keyword">usize</span><span class="token punctuation">,</span>
  173. len<span class="token punctuation">:</span> <span class="token keyword">usize</span><span class="token punctuation">,</span>
  174. buf<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token punctuation">[</span><span class="token keyword">u8</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  175. _data<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token class-name">FilePrivateData</span><span class="token punctuation">,</span>
  176. <span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">Result</span><span class="token operator">&lt;</span><span class="token keyword">usize</span><span class="token punctuation">,</span> <span class="token class-name">SystemError</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
  177. <span class="token comment">/// @brief 在inode的指定偏移量开始,写入指定大小的数据(从buf的第0byte开始写入)</span>
  178. <span class="token comment">/// @param offset 起始位置在Inode中的偏移量</span>
  179. <span class="token comment">/// @param len 要写入的字节数</span>
  180. <span class="token comment">/// @param buf 缓冲区. 请注意,必须满足@buf.len()&gt;=@len</span>
  181. <span class="token comment">/// @param _data 各文件系统系统所需私有信息</span>
  182. <span class="token comment">/// @return 成功:Ok(写入的字节数)</span>
  183. <span class="token comment">/// 失败:Err(Posix错误码)</span>
  184. <span class="token keyword">fn</span> <span class="token function-definition function">write_at</span><span class="token punctuation">(</span>
  185. <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">,</span>
  186. offset<span class="token punctuation">:</span> <span class="token keyword">usize</span><span class="token punctuation">,</span>
  187. len<span class="token punctuation">:</span> <span class="token keyword">usize</span><span class="token punctuation">,</span>
  188. buf<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token punctuation">[</span><span class="token keyword">u8</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  189. _data<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">mut</span> <span class="token class-name">FilePrivateData</span><span class="token punctuation">,</span>
  190. <span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">Result</span><span class="token operator">&lt;</span><span class="token keyword">usize</span><span class="token punctuation">,</span> <span class="token class-name">SystemError</span><span class="token operator">&gt;</span><span class="token punctuation">;</span>
  191. <span class="token comment">/// @brief 在当前目录下创建一个新的inode,并传入一个简单的data字段,方便进行初始化。</span>
  192. <span class="token comment">/// @param name 目录项的名字</span>
  193. <span class="token comment">/// @param file_type 文件类型</span>
  194. <span class="token comment">/// @param mode 权限</span>
  195. <span class="token comment">/// @param data 用于初始化该inode的数据。(为0则表示忽略此字段)对于不同的文件系统来说,代表的含义可能不同。</span>
  196. <span class="token comment">/// @return 创建成功:返回Ok(新的inode的Arc指针)</span>
  197. <span class="token comment">/// @return 创建失败:返回Err(错误码)</span>
  198. <span class="token keyword">fn</span> <span class="token function-definition function">create_with_data</span><span class="token punctuation">(</span>
  199. <span class="token operator">&amp;</span><span class="token keyword">self</span><span class="token punctuation">,</span>
  200. _name<span class="token punctuation">:</span> <span class="token operator">&amp;</span><span class="token keyword">str</span><span class="token punctuation">,</span>
  201. _file_type<span class="token punctuation">:</span> <span class="token class-name">FileType</span><span class="token punctuation">,</span>
  202. _mode<span class="token punctuation">:</span> <span class="token keyword">u32</span><span class="token punctuation">,</span>
  203. _data<span class="token punctuation">:</span> <span class="token keyword">usize</span><span class="token punctuation">,</span>
  204. <span class="token punctuation">)</span> <span class="token punctuation">-&gt;</span> <span class="token class-name">Result</span><span class="token operator">&lt;</span><span class="token class-name">Arc</span><span class="token operator">&lt;</span><span class="token keyword">dyn</span> <span class="token class-name">IndexNode</span><span class="token operator">&gt;</span><span class="token punctuation">,</span> <span class="token class-name">SystemError</span><span class="token operator">&gt;</span> <span class="token punctuation">{</span>
  205. <span class="token comment">// 若文件系统没有实现此方法,则返回“不支持”</span>
  206. <span class="token keyword">return</span> <span class="token class-name">Err</span><span class="token punctuation">(</span><span class="token class-name">SystemError</span><span class="token punctuation">::</span><span class="token constant">EOPNOTSUPP_OR_ENOTSUP</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  207. <span class="token punctuation">}</span>
  208. <span class="token punctuation">...</span>
  209. <span class="token punctuation">}</span>
  210. </code></pre></div><p>一般情况下,FileSystem和IndexNode是一对一的关系,也就是,一个文件系统对应一种IndexNode。但是,对于某些特殊的文件系统,比如DevFS,根据不同的设备类型,会有不同的IndexNode,因此,FileSystem和IndexNode是一对多的关系。</p> <h3 id="mountfs"><a href="#mountfs" class="header-anchor">#</a> MountFS</h3> <p><code>挂载文件系统</code>是将一个磁盘分区或者远程的存储设备连接到计算机文件系统中的一个过程。当我们需要访问一个磁盘分区或者远程存储设备时,首先要确定其所属的文件系统类型,然后再将它挂载到指定的目录下。这样,在访问该目录时就可以直接读取或写入外部设备上的数据了。</p> <div class="language-rust extra-class"><pre class="language-rust"><code><span class="token keyword">pub</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">MountFS</span> <span class="token punctuation">{</span>
  211. <span class="token comment">// MountFS内部的文件系统</span>
  212. inner_filesystem<span class="token punctuation">:</span> <span class="token class-name">Arc</span><span class="token operator">&lt;</span><span class="token keyword">dyn</span> <span class="token class-name">FileSystem</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
  213. <span class="token comment">/// 用来存储InodeID-&gt;挂载点的MountFS的B树</span>
  214. mountpoints<span class="token punctuation">:</span> <span class="token class-name">SpinLock</span><span class="token operator">&lt;</span><span class="token class-name">BTreeMap</span><span class="token operator">&lt;</span><span class="token class-name">InodeId</span><span class="token punctuation">,</span> <span class="token class-name">Arc</span><span class="token operator">&lt;</span><span class="token class-name">MountFS</span><span class="token operator">&gt;&gt;</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
  215. <span class="token comment">/// 当前文件系统挂载到的那个挂载点的Inode</span>
  216. self_mountpoint<span class="token punctuation">:</span> <span class="token class-name">Option</span><span class="token operator">&lt;</span><span class="token class-name">Arc</span><span class="token operator">&lt;</span><span class="token class-name">MountFSInode</span><span class="token operator">&gt;&gt;</span><span class="token punctuation">,</span>
  217. <span class="token comment">/// 指向当前MountFS的弱引用</span>
  218. self_ref<span class="token punctuation">:</span> <span class="token class-name">Weak</span><span class="token operator">&lt;</span><span class="token class-name">MountFS</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
  219. <span class="token punctuation">}</span>
  220. </code></pre></div><div class="language-rust extra-class"><pre class="language-rust"><code><span class="token comment">/// @brief MountFS的Index Node </span>
  221. <span class="token comment">/// 注意,这个IndexNode只是一个中间层。它的目的是将具体文件系统的Inode与挂载机制连接在一起。</span>
  222. <span class="token keyword">pub</span> <span class="token keyword">struct</span> <span class="token type-definition class-name">MountFSInode</span> <span class="token punctuation">{</span>
  223. <span class="token comment">/// 当前挂载点对应到具体的文件系统的Inode</span>
  224. inner_inode<span class="token punctuation">:</span> <span class="token class-name">Arc</span><span class="token operator">&lt;</span><span class="token keyword">dyn</span> <span class="token class-name">IndexNode</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
  225. <span class="token comment">/// 当前Inode对应的MountFS</span>
  226. mount_fs<span class="token punctuation">:</span> <span class="token class-name">Arc</span><span class="token operator">&lt;</span><span class="token class-name">MountFS</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
  227. <span class="token comment">/// 指向自身的弱引用</span>
  228. self_ref<span class="token punctuation">:</span> <span class="token class-name">Weak</span><span class="token operator">&lt;</span><span class="token class-name">MountFSInode</span><span class="token operator">&gt;</span><span class="token punctuation">,</span>
  229. <span class="token punctuation">}</span>
  230. </code></pre></div><p>虽然其实现了FileSystem和IndexNode这两个trait,但它并不是一个“文件系统”,而是一种机制,用于将不同的文件系统挂载到同一个文件系统树上。所有的文件系统要挂载到文件系统树上,都需要通过<code>MountFS</code>来完成。也就是说,挂载树上的每个文件系统结构体的外面,都套了一层MountFS结构体。</p> <p>对于大部分的操作,MountFS都是直接转发给具体的文件系统,而不做任何处理。同时,为了支持跨文件系统的操作,比如在目录树上查找,每次<code>lookup</code>操作或者是<code>find</code>操作,都会通过<code>MountFSInode</code>的对应方法,判断当前inode是否为挂载点,并对挂载点进行特殊处理。如果发现操作跨越了具体文件系统的边界,MountFS就会将操作转发给下一个文件系统,并执行Inode替换。这个功能的实现,也是通过在普通的Inode结构体外面,套一层MountFSInode结构体来实现的。</p> <h2 id="ramfs"><a href="#ramfs" class="header-anchor">#</a> RamFS</h2> <p>ramfs是vfs下具体实现的一种基于RAM做存储的文件系统,主要实现了以下功能:</p> <ul><li><strong>read_at</strong>:读</li> <li><strong>write_at</strong>:写</li> <li><strong>poll</strong>:获取文件状态</li> <li><strong>resize</strong>:重置用于存放数据的data的大小</li> <li><strong>create_with_data</strong>:创建自带数据的文件</li> <li><strong>link</strong>:链接</li> <li><strong>unlink</strong>:解链接</li> <li>**rmdir:**删除文件夹</li> <li><strong>move_</strong>:移动文件</li> <li><strong>find</strong>:查找文件</li> <li><strong>list</strong>:显示当前文件夹下的内容</li></ul></div> <footer class="page-edit"><!----> <!----></footer> <!----> </main></div><div class="global-ui"></div></div>
  231. <script src="/OS_lab_tutorial/assets/js/app.11bc9cdf.js" defer></script><script src="/OS_lab_tutorial/assets/js/2.3dc1b8de.js" defer></script><script src="/OS_lab_tutorial/assets/js/1.7f771cfb.js" defer></script><script src="/OS_lab_tutorial/assets/js/34.46f5bb23.js" defer></script>
  232. </body>
  233. </html>