操作系统 - 文件系统

Linux文件系统的层次

linux_file_system_01

  • General Block Device Layer: 隐藏不同硬件设备的细节,为内核提供统一的IO操作接口。这样无论什么样的硬盘和驱动,他们所提供的IO接口都没区别,被一视同仁看做块设备来处理。
  • 文件系统: 大多Linux发行版本默认使用的是ext4。 内核支持的文件系统可以通过内核目录树fs目录中的内容来查看。
  • VFS: 不管是什么文件系统,用户都只关心mount/umount, open/close等操作,所以,VFS就把不同的文件系统做一个抽象,提供统一的API访问接口,VFS提供的统一API经过系统调用封装一下,用户空间的应用就可以通过系统调用来操作不同的文件系统。Linux所有文件都建立在虚拟文件系统(Virtual File System VFS)之上。Linux支持每个目录用不同的文件系统,而文件也可能是指磁盘,内存,网卡,输入输出设备等 。

Linux : 一切皆文件

将一个文件系统映射到某个目录的过程叫做挂载(Mount),可以使用mount -l查看已经挂载的文件系统。

sysfs``proc``devtmpfs``tmpfs``ext4都是不同的文件系统

  • sysfs让用户通过文件访问和设置设备驱动信息。
  • proc是一个虚拟文件系统,让用户可以通过文件访问内核中的进程信息。
  • devtmpfs在内存中创造设备文件节点。
  • tmpfs用内存模拟磁盘文件。
  • ext4是一个通常意义上我们认为的文件系统,也是管理磁盘上文件用的系统。

文件系统的结构

文件系统的四个重要组成部分:目录(directory), 索引(index structure), 存储块(storage blocks)和free space map。
linux_file_system_02

当我们在应用中执行open命令,打开一个文件,其实是做了一个命名翻译(Name Translation)将,文件路径名翻译成了一个file number(file descriptor), 通过这个file number来找到真实存在于磁盘块上的数据。如下图:
linux_file_system_03
linux_file_system_04

directory

directory是一个包含<file_name: file_number>映射的文件;其中file_number可以是一个文件或者另外一个directory。每一个<file_name: file_bumber>映射被叫做一个directory entry(dentry)

In-Memory File System Structure如下图
linux_file_system_05

Index Structure

我们有了directory,就有了可以从文件路径到file_number的映射。然而我们的真实数据是存放在磁盘上的,那么就需要一个结构去维护file_number到磁盘块(block)的关系,也就是我们所说的Index Structure。

Case Study FAT

img2

一个类似链表的结构,文件1从块5开始,5->2->9->14->15->-1,-1代表结束,这就是文件1在磁盘块的位置。FAT通过一个链表就解决了文件和物理磁盘块的映射,简单实用。FAT的缺点是非常占有内存,1 T的硬盘,如果块大小是1 K, 需要1 G个FAT条目,占用2-3 G内存空间。

目录结构

img1

/bin : 包含很多用户可以访问的可执行文件,如ls,cp,cd等

/dev : 通常挂载在devtmpfs文件系统上,存放设备文件节点

/etc : 配置文件

/proc : 进程和内核文件

/sbin: 系统二进制文件,系统启动必须的指令

/tmp :临时文件,通常使用tmpfs文件系统,系统重启时会清除/tmp

/var : 可变数据文件, 比如日志通常会放在/var/log下,/var下的文件会长期保存

/boot : 存放Linux内核文件和启动镜像。

/opt : 可选软件,通常第三方软件安装在这个目录

/root : 用户家目录

/home: 用户个人数据

/media :自动挂载的设备,比如插入U盘

/svr :服务数据

/usr:(Unix System Resource), vim编辑器的可执行文件通常放在/usr/bin下,/usr/lib目录存放系统的库文件,比如一些重要对象的动态链接库文件,/usr/share目录下存放文档,比如man的文档

目录遍历

目录遍历

硬盘分块

为了提高性能,会把磁盘分为一个个小块(Block e.g. 4 kb)

Hard Link vs Soft(Symblic) Link

Inode

Inode 即Index node 是索引节点的意思,每个文件都有一个inode, 里面保存着文件的元数据(meta data), 是文件或者目录在文件系统中的唯一标识。

Inode包含的元数据包括:文件类型,访问权限,大小,时间相关信息,硬链接计数,指向数据块指针数组等。以下是inode结构:

struct m_inode {
    unsigned short i_mode;/*文件类型和属性,ls查看的结果,比如drwx------*/
    unsigned short i_uid;/*文件宿主id*/
    unsigned long i_size;
    unsigned long i_mtime;/*文件内容上一次变动的时间*/
    unsigned char i_gid;/*groupid:宿主所在的组id*/
    unsigned char i_nlinks; /*链接数:有多少个其他的文件夹链接到这里*/
    unsigned short i_zone[9];/*文件映射的逻辑块号*/
/* these are in memory also */
    struct task_struct * i_wait;/*等待该inode节点的进程队列*/
    unsigned long i_atime;/*文件上一次打开的时间*/
    unsigned long i_ctime;/*文件的inode上一次变动的时间*/
    unsigned short i_dev;/*设备号*/
    unsigned short i_num;
    /* 多少个进程在使用这个inode*/
    unsigned short i_count;
    unsigned char i_lock;/*互斥锁*/
    unsigned char i_dirt;
    unsigned char i_pipe;
    unsigned char i_mount;
    unsigned char i_seek;
    /*
    数据是否是最新的,或者说有效的,
    update代表数据的有效性,dirt代表文件是否需要回写,
    比如写入文件的时候,a进程写入的时候,dirt是1,因为需要回写到硬盘,
    但是数据是最新的,update是1,这时候b进程读取这个文件的时候,可以从
    缓存里直接读取。
      */
    unsigned char i_update;
};

查看文件的inode

查看一个文件的 inode,可以用 stat 命令,或者 ls -i 选项来查看。下面分别用这两个命令来查看一个文件 myfile.txt 的 inode 号为 102171635
inode_2

和元数据对应的就是用户数据(user data),或者也叫做文件数据块(data block), 存放的是文件的真实内容。我们通过文件名可以查到它的inode, 再通过inode查看文件内容。 如下图:

inode_1

硬链接

当多个文件名指向同一个inode时,这种链接就被叫做硬链接, 如下图,我们为原始文件myfile.txt创建了两个链接,都指向同一个inode。硬链接的作用:

  • 节省服务器的磁盘空间
  • 防止误删,因为inode会有硬链接的计数,只有硬链接等于0的时候,才会把文件内容的数据块删除
    inode_3

创建硬链接

可以用ln [option] [src file] [link file]来创建,注意硬链接只能对已存在的文件进行创建,并且不能够跨文件系统。

软链接

软链接也被叫做符号链接(symbolic link)。linux中的软链接和Windows中的快捷方式非常相似,软链接的inode和原文件不同,软链接inode指向的数据块存储的是源文件的路径。如下图。软链接的作用:

  • 方便文件管理,比如原文件路径比较复杂,可以在简单的路径下创建软链接便于访问。
    但一旦源文件被删除了,软链接就成了一个死链接,指向一个不存在的文件。
    inode_4

创建软链接

软链接可以用命令 ln -s [源文件名或目录] [软链接文件名] 来进行创建。和硬链接不同之处在于,对不存在的文件也可以创建软链接,可以跨文件系统,对文件或者目录都可以创建软链接。

硬链接软链接区别比较

inode_5

Linux下删除文件

unlink函数

对于硬链接来说,unlink来删除目录项会把inode的硬链接计数减一,直到inode引用计数为0时,才会真正删除文件(操作系统决定何时真正删除磁盘块上的文件);
对于软链接来说,unlink直接删除软链接,对源文件没有任何副作用。

删除文件

大家都很熟悉的rm -rf命令,用来删除文件。但是执行该操作不一定真的把文件删除掉了。在删除文件时,系统有两个变量来控制,一个是i_link代表文件硬链接数量,一个是i_count代表文件的引用计数,删除文件的前提是i_link和i_count都为0。在磁盘中的文件,只需要让i_link=0就可以把文件删除了,即你找不到这个文件了。但如果这个文件正在被程序打开,还需要把运行的程序给kill掉,或者让它释放这个文件,使i_count=0才可以达到删除文件的目的。

真正地删除文件

假设你一不小心把非常重要的数据删除掉了,这将意味着你的数据就永远也找不回来了,从而造成无法挽回的损失了,由此可见数据的重要性,因此操作系统不会轻易把数据从磁盘中真正的删除掉。

实际上所谓的右键删除操作只是把文件的inode索引号与磁盘中的block的关联断开了而已,但文件的数据并没有真正的被删除掉。如果你想真的删除数据的话,要么把磁盘格式化,要么把原先的数据删除掉,然后写入新的数据覆盖掉,当然,你也可以选择格式化和数据覆盖双重保险,这个时候你的数据想要恢复基本上是非常困难的,即便可以顶多只能恢复一部分数据了吧。

参考资料:
https://www.cnblogs.com/jfzhu/p/12945358.html
https://cloud.tencent.com/developer/article/1725964
https://blog.csdn.net/yuexiaxiaoxi27172319/article/details/45241923

posted @ 2023-01-29 16:05  rachel_aoao  阅读(132)  评论(0编辑  收藏  举报