目录
👉前言👈
👉磁盘👈
磁盘的物理结构
磁盘是计算机中唯一的一个机械结构,又因为磁盘是外设,所以磁盘访问会很慢!(CPU 是纳秒级别,内存是微秒级别,磁盘是毫秒级别的)我们目前是很少见到磁盘了,但是在企业里,磁盘存储依旧是主流。
注:一片盘片有两面,两面都能够读写数据,每一面都有一个磁头,磁头是悬浮在盘片上。磁盘的盘面是充满磁的,其上面存在着许多非常细小的 N、S级,磁盘是通过 N、S级来表示 0 和 1。通过充磁和消磁技术,来调转 N、S 级,从而达到 0 和 1 的写入,那么就可以表示数据了。
磁盘的存储结构
磁盘的逻辑结构
👉文件系统👈
Linux ext2 文件系统,上图为磁盘文件系统图(内核内存映像肯定有所不同)。磁盘是典型的块设备,硬盘分区被划分为一个个的 block,一个block的大小是由格式化的时候确定的,并且不可以更改。例如:mke2fs 的 -b 选项可以设定 block 大小为1024、2048或4096字节,而上图中启动块(Boot Block)的大小是确定的。
inode 和 data block
我们知道:文件等于文件内容加文件属性,而文件内容和文件属性是分开存储的。文件属性是保存在 inode 中的, inode 是固定大小的(通常是128字节,视具体文件系统而定)。一般情况下,有一个文件就会有一个 inode。文件几乎所有属性都储存在 inode 中,文件名并不在 inode 中存储!文件内容存储在 data block 中,其大小随着应用类型的变化而变化。
inode 为了进行区分彼此,每个 inode 都会有自己的 ID 编号。
inode Table 中保存了分组内部所有可用的 inode,可用的 inode 是包括已经使用的和未被使用的。 Data blocks 中保存的是分组内部所有文件的数据块,以4KB为基本单位。创建文件时,先在 inode Table 中找到没有被使用的 inode 将文件的属性写进去;内容也是找到没有被使用的数据块,然后再将数据写入数据块中。查找 inode 位图和数据块位图就可以知道哪些 inode 和数据块没有被使用。位图结构用比特位来代表有没有被使用,1 代表被使用,0 代表没有被使用。inode 位图比特位的位置和当前文件对应的 inode 的位置是一一对应的,数据块位图中的比特位和文件对应的数据块位置也是一一对应的。
块组描述表(Group Descriptor Table)保存的是对应分组的宏观的属性信息,如:该块组有多少 inode 和数据块,inode 被用了多少等等。
同一个分区的 inode 编号是不会重复的,是统一编号的。查找一个文件的时候,统一使用的是 inode 编号。有了文件的 inode 编号,先确定其在哪一个分组,再去 inode Bitmap 中查找对应的比特位是不是 1。是 1 则有效,再去 inode Table 中查找指定的 inode 编号,就可以找到文件的属性信息了。inode 本质是一个结构体,其中包含了一个数据块数组。该数据块数组中存储的就是文件的数据块编号。
如果想要查看一个文件,就可以通过 inode 编号找到该文件的数据块数组 blocks[15],进而找到该文件的数据块,组合成整个文件。从 blocks[12] 开始,其指向的是一个数据块。该数据块中保存的是其他的数据块编号,这些块也可以存储别的数据块编号,进而 blocks[15] 表示的就不止 15 个数据块了,可以是很多个。也就是说一个文件的数据块可以很多,文件的大小可以很大。
删除文件只需要找到 inode 在 inode Bitmap 中的比特位和 Block Bitmap 的比特位,将这两个比特位改成 0,文件就算删除了。恢复文件则与该过程相反,知道删除文件的 inode,再将 inode Bitmap 和 block Bitmap 中对应的比特位改成 1 即可恢复文件。删除文件的 inode 可以通过日志来查到。误删文件后,千万不要新建文件。以防误删文件的 inode 编号和数据块被占用,无法恢复误删文件!
而我们查看文件使用的是文件名,并没有使用 inode 来查看文件。其实文件名和 inode 存在一一映射的关系,目录的数据块放的就是当前目录文件名和 inode 的映射关系。所以同一个目录下,不可以存在同名的文件。因为文件名就是一个 key 值,通过该 key 值找到对应的 inode 编号,进而找到该文件!!!所以在一个目录里创建文件,必须要有该目录的写入权限。因为要将文件名和 inode 的映射关系写入到目录的数据块中。
软硬链接
ln -s 现有文件 目标文件 #将目标文件与现有文件进行软链接
ln 现有文件 目标文件 #将目标文件与现有文件进行硬链接
unlink 文件名 #删除软链接文件
硬链接就是相当于给原有文件取别名,硬链接生成的文件和原有文件对应的 inode 是相同的。原有文件删除,并不会影响硬链接生成的文件,只是 inode 中的引用计数减去了 1。但软链接却不同,软链接并不是使用 inode 编号来表示的,而是通过文件名来标识的。软链接生成的文件有独立的 inode,也就有自己的数据块,其数据块中保存了原有文件的路径。如果删除了原有文件,那么软链接就失效了。但是如果在新建相同名字的文件,软链接会再次生效。但文件的内容肯定是不一样的,这相当于偷梁换柱。
软链接的优势:软链接就相当于 Windows 系统下的快捷方式,它能够帮助我们快速地找到指定路径的文件。
理解创建普通文件和目录文件的默认硬链接数
为什么创建一个普通文件的默认硬链接数是 1 呢?因为一个普通文件,自身就和该普通文件的 inode 建立一个映射关系,所以创建一个普通文件的默认硬链接数就是 1 了。
那为什么创建一个目录文件的默认链接数是 2 呢?其实是当前路径 lesson21 的目录文件 empty 的 inode 编号为790346
,目录文件 empty 中的当前目录.
的 inode 编号也是790346
。所以,创建一个目录文件的默认链接数就是 2 了。如果在 empty 中再创建一个目录 Test,那么790346
的引用计数(硬链接数)又会增加一。因为 Test 中的上级目录..
的 inode 编号也是790346
。
Linux 是不允许普通用户给目录建立硬链接的。原因是引入了对目录的硬连接就有可能在目录中引入循环,在目录遍历的时候系统就会陷入无限循环当中,这样导致无法定位到访问目录。Linux 的目录结构是一棵以 “/” 为根节点的树,如果允许自定义硬连接,则很有可能会破坏这个结构,甚至形成循环;而一旦形成循环,对于需要遍历目录树的命令,是致命的。所以为了避免对目录树结构的破坏,Linux 不允许用户自定义硬连接在目录上。
但是可以为目录建立软链接,因为软链接生成的文件会有独立的 inode 且该文件的类型为l
。注:.
和 ..
是操作系统给目录建立的硬链接。