一.磁盘
磁盘是计算机的主要存储介质,它可以存储大量二进制数据,即使断电后也可以保证数据不会丢失。下面我们将了解磁盘的物理结构、存储结构以及逻辑结构。
磁盘的存储结构
1. 磁盘寻址的时候,基本单位既不是bit也不是byte,而是扇区。
2. 扇区的大小是512字节。512字节是硬件要求,外磁道和内磁道都是一样的,它们只是密度不同。越靠近圆心的比特位越大,否则就越小。
3. 在单面上定位扇区:通过确定磁道,以及确定对应磁道的扇区,来具体确定该区间。确定磁道:.每一个磁道都有自己的编码,磁道周长不同,但是存储大小相同。由于扇区大小是相同的,因此每一个磁道有多少个扇区也是一定的,所以每一个磁道的扇区也是有编号的,因此定位到磁道就能找到对应扇区。
4. 机械硬盘的寻址方式:盘片不断的转动,磁头不断的摆动,就是在确认在哪个磁道。如何确定扇区?盘片的先选择就是让其磁头定位扇区。
5. 柱面:把一系列同心的磁道压在一起,宏观上看成一个整体。一般定位的时候,(磁头、柱面、扇区)与(磁头、磁道、扇区)这两个是等价的。磁头指向的位置就是柱面的边界位置。
6. 在磁盘中定位扇区:先定位在哪个磁道(在哪个柱面),磁道定位后,(因为,所有磁头共同进退)再去定位盘面(磁头),最后确定是哪一个扇区。
总结:在磁盘中定位一个扇区,采用的是硬件级别定位方法(CHS定位法):柱面(Cylinder)——磁头(Head)——扇区(Sector)
二.文件系统与inode
1.文件在磁盘中是如何存储的?
磁盘的空间很大,OS的文件系统会以1KB、2KB、4KB为单位定制多个扇区进行读写,即使读取/修改1bit的内容,也必须将4KB的内容全部加载到内存中进行读取或修改,完成操作后再将其写回磁盘。虽然磁盘访问的基本单位是512字节,但这相对于整个磁盘的大小还是很小的。为了方便管理,我们采用分治的思想,对磁盘空间进行分区:将1个较大的磁盘空间分为多个较小的磁盘空间,再给不同的分区内写入不同的文件系统。
在一个分区内部再进行分组,然后写入文件系统,管理好每一个分组就可以管理好一个分区。
这一过程是”格式化“,在磁盘中写入文件系统。
文件 = 内容 + 属性(也就是数据),文件在磁盘中的存储,本质就是存储文件的内容和文件的属性的数据。
Linux文件系统特定:文件内容和文件的属性数据分开存储
· Data blocks(数据区):存放文件内容
· Block Bitmap(块位图):记录着 Data blocks 中哪个数据块已被占用,哪个没被占用,Block Bitmap里的块有编号,块里的内容表示是否被占用。
· i节点表(inode Table):存放文件属性 如 文件大小,所有者,最近修改时间等。
· inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
· GDT,Group Descriptor Table:块组描述符,描述块组属性信息。
· 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了。(不是每个分组都有的)
Linux中文件的属性是一个固定大小的集合体,inode内部是不包含文件名的,内核层面,每一个文件都要有inode number!我们通过inode号标识一个文件。(我们可以通过指令ls -li
来查询文件对应的inode编号。)
删除文件时并不需要将文件的数据和内容情况,只需要将对应文件的inode在inode bitmap中的比特位 置为0即可(即使不将它们清空也不会影响新文件的存储,因为新文件的数据会直接将原数据覆盖掉)。因此,在删除文件后是可以及时将文件恢复的,恢复文件只需要找到inode的编号,然后将inode bitmap中对应比特位的值由0置为1,再去inode table对应映射表,将blosk bitmap由0置为1即可。
如果在Linux中误删一个文件,还是可以恢复的(前提是文件的inode和data block没有被占用),因此当误删一个文件时最好的做法是什么也不做。
在windows下,删除文件到回收站,实际上是将文件转移到回收站的目录而已,只有在回收站中删除才是真的删除。
为什么我们在目录中查找文件时,用的是文件名而不是inode id?
因为任何一个文件都是创建在目录下的(注意,同一目录下不能出现相同文件名的两个文件),而目录也是一个文件,也有自己的inode,以及data block。目录的数据块(data block)中存储的是当前目录下文件的文件名与文件inode id的对应关系(这也是为啥inode中不保存文件名)。
新增文件要在当前目录的内容(data block)中添加该文件名与inode id的映射关系,所以当我们在一个目录下新增文件时,必须要有对目录的写权限。
罗列当前目录的文件,要有对目录的读权限,想知道目录中的文件,需要根据文件名找到inode,再读取该文件的属性。读目录内容是要拿到文件名,因此,目录必须要有读权限。
三.软硬链接
1.软链接
创建软链接:
ln -s <目标路径> <链接路径>
例如,创建软链接soft_text.txt文件指向text.txt文件
从上图中可以看到,soft_text.txt有自己独立的inode,它是一个独立的文件,具有自己独立的内容。
所谓的软链接标定文件,它并非用文件的inode来标记。
看这个现象:我们删除text.txt然后再去cat soft_text.txt:
软链接的数据块中保存的是指向目标文件的路径,当目标文件被删除时,软链接也就失效了。
可以理解为你电脑桌面的快捷方式
删除软链接:
rm rm -f soft_text.txt//和删除普通文件一样ulink ulink ssoft_text.txt//删除链接
2.硬链接
创建硬链接:
ln <目标路径> <链接路径>
可以发现硬链接的inode和text.txt的相同,它没有独立的inode,用的是目标文件的inode。
硬链接的作用?
当某一个硬链接的文件大小和内容发生变化,那么它对应的目标文件以及所有目标文件的硬链接都会一起发生改变。
硬链接没有创建新的文件,它没有独立的inode、内容。它用的全部是目标文件的inode和内容。
创建硬链接的本质就是在指定的路径下,新增文件名和inode的映射关系。
一个inode可能会被多个文件名所映射,为了方便管理,inode有一个计数器,count的引用计数,也将引用计数称为硬链接数:
当我们删除硬链接后,计数由2变为1.
硬链接的作用
1.为啥创建一个普通文件时,硬链接数是1?
因为,普通文件本身就有一个文件名和inode对应(只要创建文件,就有一个inode的映射关系)。
2.为啥创建一个目录,它的硬链接数是2?
因为目录名与它自己的inode就是一组1映射关系;其次,目录内部的'.'('.'也表示当前目录,它也是文件名)和inode也是一组映射,所以硬链接数是2。特别的,如果在当前目录下再创建一个目录,当前目录的硬链接数就会变为3。这是因为,当前目录下创建的子目录中默认的有一个文件名'..'
('..'
表示上一层目录,它也是文件名)和当前目录的inode也是一组映射。
用户不能给目录建立硬链接
1. 为什么不允许给目录建立硬链接呢?
如果允许给目录建立硬链接,则可能会打破文件系统目录的有向无环图结构,创建目录循环,导致fsck以及其他的遍历文件树的软件出错。可能会出现:你的子目录是你的父目录这种奇怪的现象,即当前目录的子目录是硬链接的当前目录的父目录这种情况,此时很多遍历系统的命令(du, ls -r, pwd等)就无法使用了,因为可能会导致无限循环。
2. 为什么软链接就不会出现循环调用这个情况呢?
上文中,我们了解到软链接所指向的是链接文件本身的信息,而不是链接文件指向的文件的信息;硬链接直接指向的是inode,而不是路径(直接指向链接文件所指向的文件信息)。这就意味着,在遍历的时候,如果是软链接就不会出现环路从而导致死循环。因此不允许用户给目录建立硬链接。