0 00:00:00,000 --> 00:00:06,920 1 00:00:06,960 --> 00:00:08,000 那我们前面对这个 2 00:00:08,040 --> 00:00:09,000 uCore文件系统结构 3 00:00:09,040 --> 00:00:10,560 有一个大致的了解 4 00:00:10,600 --> 00:00:12,560 接下来我们再进一步深入一下 5 00:00:12,600 --> 00:00:13,840 看看一个具体文件系统 6 00:00:13,880 --> 00:00:17,800 是怎么能够表示出它所需要那些文件 7 00:00:17,840 --> 00:00:20,480 和给用户访问的一些操作的 8 00:00:20,520 --> 00:00:24,320 就是simple file system一个分析 9 00:00:24,360 --> 00:00:25,800 在simple file system里面呢 10 00:00:25,840 --> 00:00:28,040 我们重点关注是一个一般的文件 11 00:00:28,080 --> 00:00:31,440 就是我们说通常的打开 读 写 关闭 12 00:00:31,480 --> 00:00:33,800 这么一个操作用到的文件和目录 13 00:00:33,840 --> 00:00:36,800 它的一个类型所需要涉及到 14 00:00:36,840 --> 00:00:38,320 一些数据结构和操作 15 00:00:38,360 --> 00:00:40,760 这里面需要考虑一系列问题 16 00:00:40,800 --> 00:00:43,080 第一个就是说硬盘上 17 00:00:43,120 --> 00:00:45,200 怎么有效去组织一个文件系统 18 00:00:45,240 --> 00:00:46,360 怎么能够通过文件系统组织 19 00:00:46,400 --> 00:00:49,480 来表示出更具体的文件 20 00:00:49,520 --> 00:00:51,160 硬盘的布局是什么 21 00:00:51,200 --> 00:00:53,240 硬盘上它是以磁盘块为单位 22 00:00:53,280 --> 00:00:55,520 来进行读或者写操作 23 00:00:55,560 --> 00:00:57,720 那怎么去和我们文件的 24 00:00:57,760 --> 00:00:59,800 数据块进行对应 25 00:00:59,840 --> 00:01:03,080 如何去管理这些空闲的磁盘块 26 00:01:03,120 --> 00:01:05,560 怎么去表示一个文件或者目录 27 00:01:05,600 --> 00:01:07,320 到底文件里面包含什么东西 28 00:01:07,360 --> 00:01:08,440 目录包含什么东西 29 00:01:08,480 --> 00:01:12,320 还有这个数据怎么去定位 30 00:01:12,360 --> 00:01:14,080 这些问题就是要 31 00:01:14,120 --> 00:01:15,120 设计一个文件系统里面 32 00:01:15,160 --> 00:01:16,560 需要去考虑的内容 33 00:01:16,600 --> 00:01:18,680 好 我们这里面采取的方法是什么呢 34 00:01:18,720 --> 00:01:21,240 自下而上 从硬盘到内存 35 00:01:21,280 --> 00:01:22,760 观察这个数据结构 36 00:01:22,800 --> 00:01:24,040 它们之间依赖关系 37 00:01:24,080 --> 00:01:25,800 谁包含谁 这么一个方法 38 00:01:25,840 --> 00:01:28,040 来分析我们simple file system 39 00:01:28,080 --> 00:01:31,840 它大致是怎么来组成的 40 00:01:31,880 --> 00:01:33,120 那我们可以看看这幅图 41 00:01:33,160 --> 00:01:34,200 首先我们可以定位一下 42 00:01:34,240 --> 00:01:35,080 simple file system呢 43 00:01:35,120 --> 00:01:37,600 在整个文件系统的这部分 44 00:01:37,640 --> 00:01:38,440 中间这部分 45 00:01:38,480 --> 00:01:40,360 它的主要的内容是 46 00:01:40,400 --> 00:01:41,760 存在我们硬盘上的 47 00:01:41,800 --> 00:01:43,320 就是这一块 48 00:01:43,360 --> 00:01:45,240 整个我们提供虚拟硬盘 49 00:01:45,280 --> 00:01:47,120 这个硬盘呢 它保存了 50 00:01:47,160 --> 00:01:49,640 simple file system整体的一个结构 51 00:01:49,680 --> 00:01:51,960 这里面包含了super block 52 00:01:52,000 --> 00:01:53,480 根目录的inode 53 00:01:53,520 --> 00:01:55,440 freemap 就是表明当前 54 00:01:55,480 --> 00:01:57,120 哪些磁盘块是空闲的 55 00:01:57,160 --> 00:01:59,080 还有一些跟数据相关的 56 00:01:59,120 --> 00:02:02,600 数据块的一些信息 57 00:02:02,640 --> 00:02:04,560 那simple file system当它在内存中 58 00:02:04,600 --> 00:02:07,040 被uCore操作系统进行操作和管理的时候 59 00:02:07,080 --> 00:02:10,880 它会涉及到file 目录 60 00:02:10,920 --> 00:02:12,720 inode和I/O buffer 61 00:02:12,760 --> 00:02:14,120 那么文件和目录呢 62 00:02:14,160 --> 00:02:15,920 它和我们inode有一个交互 63 00:02:15,960 --> 00:02:17,560 我们需要通过inode来表示 64 00:02:17,600 --> 00:02:19,200 这个文件和目录的关系 65 00:02:19,240 --> 00:02:20,960 以及这个文件和目录 66 00:02:21,000 --> 00:02:23,600 它所在的位置和内容 67 00:02:23,640 --> 00:02:25,400 这个I/O buffer主要是用于说 68 00:02:25,440 --> 00:02:28,640 我们需要把文件数据读到内存中来 69 00:02:28,680 --> 00:02:30,080 放到一个buffer里面去 70 00:02:30,120 --> 00:02:32,040 或者把内存中的buffer数据呢 71 00:02:32,080 --> 00:02:34,000 写到我们硬盘中去 72 00:02:34,040 --> 00:02:36,800 这里面就有一个buffer这么一个管理 73 00:02:36,840 --> 00:02:39,400 这是我们说simple file system 74 00:02:39,440 --> 00:02:42,880 它大致涉及的内容 75 00:02:42,920 --> 00:02:45,520 那我们再从硬盘的角度来看一下 76 00:02:45,560 --> 00:02:47,480 这个Simple file system它的组成部分 77 00:02:47,520 --> 00:02:48,880 第一个叫super block 78 00:02:48,920 --> 00:02:50,720 根据这个名字可以看出来超级块 79 00:02:50,760 --> 00:02:52,800 它是对我们整个simple file system 80 00:02:52,840 --> 00:02:54,720 一个总体的一个描述 81 00:02:54,760 --> 00:02:56,880 包含了它一个标识 magic number 82 00:02:56,920 --> 00:02:58,600 然后它整体一个块数 83 00:02:58,640 --> 00:03:00,640 当前还有空闲多少块 84 00:03:00,680 --> 00:03:03,160 还有它的一个字符串信息 85 00:03:03,200 --> 00:03:06,080 这是super block内部的一个内容 86 00:03:06,120 --> 00:03:08,600 我们需要把它读到我们内存中去 87 00:03:08,640 --> 00:03:11,200 通过什么呢 sfs_do_mount 88 00:03:11,240 --> 00:03:13,520 那么这个do_mount要把文件系统 89 00:03:13,560 --> 00:03:16,360 加载到我们uCore kernel里去 90 00:03:16,400 --> 00:03:18,960 使得我们应用可以去访问 91 00:03:19,000 --> 00:03:21,240 那这一步呢 是在开始做 92 00:03:21,280 --> 00:03:22,400 文件系统初始化的时候 93 00:03:22,440 --> 00:03:26,600 需要去完成的工作 94 00:03:26,640 --> 00:03:28,920 紧接着呢 我们会在内存中 95 00:03:28,960 --> 00:03:29,640 建立好一个 96 00:03:29,680 --> 00:03:32,200 simple file system的整体框架 97 00:03:32,240 --> 00:03:34,920 这个框架什么呢 sfs_fs 98 00:03:34,960 --> 00:03:36,080 这个看名字有点怪 99 00:03:36,120 --> 00:03:37,280 就是simple file system的 100 00:03:37,320 --> 00:03:38,600 一个file system 101 00:03:38,640 --> 00:03:39,760 在这个结构里面呢 102 00:03:39,800 --> 00:03:41,320 你可以看到 刚才那个 103 00:03:41,360 --> 00:03:43,240 super block信息已经放到这儿 104 00:03:43,280 --> 00:03:47,080 第二部分呢 是这个文件系统所在的device 105 00:03:47,120 --> 00:03:48,760 也就说它有一个 106 00:03:48,800 --> 00:03:51,400 针对具体一个设备的表述 107 00:03:51,440 --> 00:03:54,040 这一块我们放后面会进一步讲解 108 00:03:54,080 --> 00:03:55,920 第三部分是freemap 109 00:03:55,960 --> 00:03:57,920 就是当前这个文件系统中 110 00:03:57,960 --> 00:04:01,040 还有哪些空闲的数据块 可以去使用 111 00:04:01,080 --> 00:04:03,320 那么通过freemap可以表示出来 112 00:04:03,360 --> 00:04:07,680 这是用一个bit来表示一个data的block 113 00:04:07,720 --> 00:04:11,240 还有就是sfs_buffer 用于缓冲用的 114 00:04:11,280 --> 00:04:13,320 还有呢 inode_list 115 00:04:13,360 --> 00:04:14,960 就是所有这里面的inode 116 00:04:15,000 --> 00:04:18,280 它会通过一个哈希或者是链表的方式 117 00:04:18,320 --> 00:04:19,640 保存在我们内存中 118 00:04:19,680 --> 00:04:21,160 便于我们来检索 119 00:04:21,200 --> 00:04:25,240 属于SFS这个文件系统一些inode情况 120 00:04:25,280 --> 00:04:28,240 那这就是形成一个整体的架构 121 00:04:28,280 --> 00:04:32,800 我们再逐步往下进一步细看 122 00:04:32,840 --> 00:04:34,200 第一个很关键的 123 00:04:34,240 --> 00:04:35,800 在这个硬盘块上面 124 00:04:35,840 --> 00:04:37,120 除了super block之外 125 00:04:37,160 --> 00:04:39,520 就是一个叫root-dir的inode 126 00:04:39,560 --> 00:04:41,240 什么叫root-dir inode 127 00:04:41,280 --> 00:04:43,760 就是根目录的inode的结构 128 00:04:43,800 --> 00:04:45,160 那么根目录表明了 129 00:04:45,200 --> 00:04:46,720 我们一开始访问这个文件系统 130 00:04:46,760 --> 00:04:49,200 可以看到的目录信息 131 00:04:49,240 --> 00:04:50,600 那这个根目录信息里面 132 00:04:50,640 --> 00:04:52,560 包含了直接索引块和间接索引块 133 00:04:52,600 --> 00:04:54,240 它大致的位置在什么地方 134 00:04:54,280 --> 00:04:55,280 就是在这里面 135 00:04:55,320 --> 00:04:58,280 用这个数据结构来表示出来的 136 00:04:58,320 --> 00:05:01,160 同时我们还可以看到对于目录而言 137 00:05:01,200 --> 00:05:04,120 它的数据它是什么呢 138 00:05:04,160 --> 00:05:05,120 包含了这部分内容 139 00:05:05,160 --> 00:05:06,280 就是一个是索引节点 140 00:05:06,320 --> 00:05:08,120 所占数据块的索引 141 00:05:08,160 --> 00:05:09,440 还有就是文件名 142 00:05:09,480 --> 00:05:10,720 这实际上表明一个目录项 143 00:05:10,760 --> 00:05:12,280 就是我们前面在讲 144 00:05:12,320 --> 00:05:14,480 文件系统抽象时候提到的 145 00:05:14,520 --> 00:05:17,080 目录是由一系列目录项组成 146 00:05:17,120 --> 00:05:19,720 在这里面我们是用一个数组方式来表示 147 00:05:19,760 --> 00:05:23,680 通过查找一个目录所在的inode 148 00:05:23,720 --> 00:05:25,400 所对应的它的data 149 00:05:25,440 --> 00:05:27,800 可以找着属于这个目录里 150 00:05:27,840 --> 00:05:29,080 所有的目录项 151 00:05:29,120 --> 00:05:30,080 而每一个目录项呢 152 00:05:30,120 --> 00:05:33,200 包含了关键的文件名 153 00:05:33,240 --> 00:05:37,280 和文件名所对应的inode的那个索引值 154 00:05:37,320 --> 00:05:44,400 OK这就是说我们目录项里面的内容 155 00:05:44,440 --> 00:05:47,080 第二部分呢 是我们文件的数据 156 00:05:47,120 --> 00:05:48,680 那么文件数据放在什么地方呢 157 00:05:48,720 --> 00:05:50,080 就是用这个来表示的 158 00:05:50,120 --> 00:05:53,480 也是一样 是由我们这个inode里面 159 00:05:53,520 --> 00:05:55,200 它的间接索引块和直接索引块 160 00:05:55,240 --> 00:05:58,320 来表明我们的data block在什么地方 161 00:05:58,360 --> 00:05:59,200 对于file而言 162 00:05:59,240 --> 00:06:00,680 这个data block就是它的data 163 00:06:00,720 --> 00:06:03,160 就是我们说文件的具体内容 164 00:06:03,200 --> 00:06:04,480 那我们如果要读写文件 165 00:06:04,520 --> 00:06:07,040 最终这个文件的数据放什么地方呢 166 00:06:07,080 --> 00:06:08,600 就放在这些地方里面 167 00:06:08,640 --> 00:06:11,880 通过inode里面index可以查找 168 00:06:11,920 --> 00:06:14,080 这些data block在所在的位置 169 00:06:14,120 --> 00:06:16,960 然后进一步通过我们硬盘的读写呢 170 00:06:17,000 --> 00:06:18,000 就可以把这个数据 171 00:06:18,040 --> 00:06:24,440 进行相应的读或者写操作 172 00:06:24,480 --> 00:06:26,960 这里面很关键就是inode了 173 00:06:27,000 --> 00:06:29,480 我们可以看看simple file system的inode 174 00:06:29,520 --> 00:06:31,560 包含什么样的信息 175 00:06:31,600 --> 00:06:33,600 它其实包含两个层面的内容 176 00:06:33,640 --> 00:06:35,440 第一个层面是在内存中 177 00:06:35,480 --> 00:06:37,200 它有一个sfs_inode 178 00:06:37,240 --> 00:06:39,880 第二层面是我们硬盘上 也有一个inode 179 00:06:39,920 --> 00:06:42,160 它称之为sfs_disk_inode 180 00:06:42,200 --> 00:06:44,040 可以看出来它们关系是什么 181 00:06:44,080 --> 00:06:52,040 disk_inode呢 是sfs_inode一个成员变量 182 00:06:52,080 --> 00:06:56,960 那我们需要通过这个sfs_disk_inode 183 00:06:57,000 --> 00:07:02,720 来完成进一步针对文件的读写操作 184 00:07:02,760 --> 00:07:05,200 那么这里面会涉及到打开 关闭文件 185 00:07:05,240 --> 00:07:06,080 读 写文件 186 00:07:06,120 --> 00:07:08,520 还有读写inode所对应数据块的 187 00:07:08,560 --> 00:07:10,160 一系列操作 188 00:07:10,200 --> 00:07:14,160 那这些操作是什么 我们可以看看 189 00:07:14,200 --> 00:07:16,440 那么如果说我们知道一个inode 190 00:07:16,480 --> 00:07:18,440 我们希望访问这个inode的数据 191 00:07:18,480 --> 00:07:19,760 那么这里面存在两种情况 192 00:07:19,800 --> 00:07:22,000 一种是这个inode表明是一个目录 193 00:07:22,040 --> 00:07:23,800 或者这个inode表明是个文件 194 00:07:23,840 --> 00:07:26,720 这两者是不一样的 195 00:07:26,760 --> 00:07:30,120 这个函数就是sfs_bmap的一系列操作呢 196 00:07:30,160 --> 00:07:36,080 是关于文件这种情况的数据块读写 197 00:07:36,120 --> 00:07:38,680 而下面这几个函数 (direntry) 198 00:07:38,720 --> 00:07:39,960 就是目录entry呢 199 00:07:40,000 --> 00:07:43,440 它其实涉及到针对目录的 数据的读写 200 00:07:43,480 --> 00:07:46,000 可以看出来它们是不一样的 201 00:07:46,040 --> 00:07:48,240 但是呢 我们有一系列的 202 00:07:48,280 --> 00:07:50,960 高层的 针对file的一些操作 203 00:07:51,000 --> 00:07:53,720 这个操作 其实是和我们后续会讲到的 204 00:07:53,760 --> 00:07:55,160 虚拟文件系统相关 205 00:07:55,200 --> 00:07:58,920 它会把底层的一些函数的细节给屏蔽掉 206 00:07:58,960 --> 00:08:01,920 向上提供一个统一的接口比如open close 207 00:08:01,960 --> 00:08:02,760 这个接口是一样的 208 00:08:02,800 --> 00:08:04,720 但是它具体对应到 209 00:08:04,760 --> 00:08:06,520 simple file system的实现 210 00:08:06,560 --> 00:08:08,360 它这个open file或者close 211 00:08:08,400 --> 00:08:10,400 这些操作是不一样的 212 00:08:10,440 --> 00:08:12,760 通过这些函数呢来完成 213 00:08:12,800 --> 00:08:17,880 对一个文件的打开 关闭 读写操作 214 00:08:17,920 --> 00:08:21,440 紧接着还会通过不太一样的一些操作 215 00:08:21,480 --> 00:08:22,920 比如说opendir 216 00:08:22,960 --> 00:08:24,600 或者getdirectory entry来完成 217 00:08:24,640 --> 00:08:28,560 针对目录读打开 关闭操作 218 00:08:28,600 --> 00:08:29,920 这里面也写一个写 219 00:08:29,960 --> 00:08:32,280 大家仔细考虑一下这里面有写吗 220 00:08:32,320 --> 00:08:33,560 这是留给大家的一个问题 221 00:08:33,600 --> 00:08:35,440 大家可以再考虑一下 222 00:08:35,480 --> 00:08:36,320 这里面只是介绍了 223 00:08:36,360 --> 00:08:37,760 基于index这种方式的 224 00:08:37,800 --> 00:08:39,520 文件系统具体实现 225 00:08:39,560 --> 00:08:40,800 还有其它一些文件系统 226 00:08:40,840 --> 00:08:41,960 大家通过做实验 227 00:08:42,000 --> 00:08:44,160 还可以进一步掌握和了解 228 00:08:44,200 --> 00:08:44,240