Linux文件系统与软硬链接


Linux文件系统与软硬链接

在Linux中,文件分为内存文件和磁盘文件,其中内存文件属于被进程打开的文件,被加载到了内存中,对于内存文件,主要研究它与进程的关系。磁盘文件属于没有被进程打开的文件,磁盘文件存放在磁盘上,文件系统主要就是研究的磁盘文件。

对于磁盘文件,需要关心如下问题

站在单个文件的角度,需要知道:

  1. 这个文件在哪里?
  2. 这个文件的大小?
  3. 这个文件的属性?例如这个文件最后的访问时间(Access time),这个文件的文件内容最后一次被修改的时间(Modify time),这个文件的文件属性最后一次被修改的时间;文件的拥有者,所属组,other等等

站在操作系统的角度,需要知道:

  1. 在磁盘上一共有多少个文件?
  2. 文件的属性保存在哪个位置?
  3. 如何快速在磁盘上找到指定的文件?
  4. 如何对众多的文件进行存储和划分?

磁盘

磁盘的基本结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ohx5p4V6-1670075763076)(C:\Users\19199\Desktop\c++研发\Linux\Linux文件系统与软硬链接.assets\20191123184100632.png)]

  • 磁盘是由多个盘片叠加而成的
  • 一个盘片有2个盘面,即正反两面
  • 每一个盘面被划分为一个一个的磁道,一个磁道对应一个圆形区域。
  • 每一个磁道被划分为若干扇区,数据在磁盘上存储的基本单位就是扇区,一个扇区的大小一般是512Bytes
  • 每一个磁道上存储的数据量是一样的,在内侧的磁道扇区面积最小,存储密度最大,在外侧的磁道扇区面积最大,存储密度最小。
磁盘的寻址方式

磁盘的寻址方式有CHS寻址方式LBA寻址方式

CHS寻址方式是根据(x,y,z)坐标找到磁盘上某一个特定的扇区,x指的是盘面的编号,y指的是磁道的编号,z指的是扇区的编号,Linux文件系统中不直接采用CHS寻址方案,Linux文件系统中采用LBA寻址方案。

LBA寻址是一种逻辑寻址模式,它将磁盘抽象为线性结构,通过逻辑地址访问磁盘上的物理地址,把逻辑地址转化为CHS寻址方式中的(x,y,z),这个转化是通过磁盘控制器来完成的。

磁盘分区

磁盘不是作为一个整块进行使用的,它被划分为若干个分区

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q92dzQeT-1670075763077)(C:\Users\19199\Desktop\c++研发\Linux\Linux文件系统与软硬链接.assets\image-20221203194427358.png)]

磁盘的一个分区由一个启动块(boot block)和若干个块组构成,启动块在每一个分区都有一个,且只有一个。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oKcAqdKK-1670075763078)(C:\Users\19199\Desktop\c++研发\Linux\Linux文件系统与软硬链接.assets\image-20221203194709135.png)]

操作系统要管理好整个磁盘,只需要管理好磁盘的每一个分区即可,而管理好每一个分区,只需要管理好分区中的每一个块组即可。

块组

块组具有如下结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pblsFSuu-1670075763078)(C:\Users\19199\Desktop\c++研发\Linux\Linux文件系统与软硬链接.assets\image-20221203195003109.png)]

  • super block:super block存放整个文件系统的属性信息,super block在每一个块组都有一个,它们的内容是一样的。

  • data blocks:data blocks是多个4KB的小块的集合,data blocks中保存文件的内容数据。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eCqZQYV5-1670075763079)(C:\Users\19199\Desktop\c++研发\Linux\Linux文件系统与软硬链接.assets\image-20221203195620310.png)]

data blocks的使用是按照块为单位进行使用的,磁盘的基本单位是扇区,大小为512Bytes,但Linux系统与磁盘进行I/O的基本单位是4KB。若一个文件的内容数据大小是8KB,那么它的内容数据在磁盘上占用2个块。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMoRqxLP-1670075763079)(C:\Users\19199\Desktop\c++研发\Linux\Linux文件系统与软硬链接.assets\image-20221203200112678.png)]

  • inode table:inode table存放一个块组中所有文件的inode。文件的inode是一个结构体,它里面保存了文件的所有属性,一个inode的大小是128Bytes.

    struct inode{
        size_t file_size;//文件的大小
        int inode_num;//文件的inode编号
        int blocks[NUM];//文件内容数据对应哪些block块(文件内容数据的映射表)
        //......
    };
    

    一般而言,一个文件只有1个inode,里面存放这个文件的所有属性,一个inode中保存一个唯一的inode编号,这个inode编号是由Linux系统自动分配。可以根据inode编号在磁盘上找到对应的inode,根据inode就能得到文件的所有属性。

    查看文件的inode编号可以使用ls -i命令

    [slowstep@localhost day31]$ ls -i
    77088 test.c
    
  • block bitmap:记录块组的data blocks中有哪些块被占用

  • inode bitmap:记录块组的inode table中有哪些inode被占用

  • group descriptor table(GDT):块组描述符,记录块组的信息,例如:块组的大小,块组的data block的使用情况,块组的inode table的使用情况

文件的内容与属性

在Linux中,文件的内容和文件的属性是分开存储的,文件的内容存放在块组的data blocks中,文件的属性存放在块组的inode table中。一个文件只使用inode table中的一个inode,可能使用data blocks中的多个block。

可以根据文件的inode找到文件的内容,大致原理如下:

struct inode{
    int blocks[100];
};
int main(){
    inode node;
    node.blocks[0]=1;
    node.blocks[5]=1;
    node.blocks[3]=1;
    node.blocks[10]=1;
    //表示这个文件使用了data blocks的第0,3,5,10个block.
    return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cRrIkLfF-1670075763080)(C:\Users\19199\Desktop\c++研发\Linux\Linux文件系统与软硬链接.assets\image-20221203202119610.png)]

data blocks中的每一个block块不仅可以存放文件的内容数据,也可以存放其他的block块的位置,形成一颗类似于多叉树的结构,帮助inode映射找到文件的所有内容数据。

文件名

在Linux系统中,文件的inode不存储文件的文件名,Linux下,文件的文件名是文件所在的目录的内容数据。

Linux下一切皆文件,目录也是文件,目录有自己的inode,保存目录的属性信息,目录的内容数据也保存在对应的block块中,目录的内容保存的是目录下所有文件的文件名和inode编号的对应关系,例如

[slowstep@localhost day31]$ ls -i
77088 test.c

在day31这个目录的block块中保存了77088-test.c这一个对应关系。

站在Linux文件系统的角度理解创建文件、删除文件、查看文件:

在目录下新建一个文件

在目录下新建一个文件,文件系统需要在inode table中为该文件申请一个inode,用于存放该文件的属性,同时要在目录的block块中写入一组映射(新建文件的文件名与它的inode编号之间的映射),因此,在目录下创建一个文件需要有对于该目录的w权限。

有时块组还有空间,但是创建文件失败,可能有2个原因:

  1. inode table中还有可用的inode,但是data blocks中所有的block块都已经被使用
  2. data blocks中还有可用的block块,但是inode table中所有的inode都用完了

删除目录中的一个文件

删除目录中的一个文件,并不需要真正的将文件的inode和block块清空,只需要找到文件的inode在inode table中的位置,然后在inode bitmap中将该位置对应的比特位置为0即可;同理,找到文件的block块在data blocks中对应的位置,然后在block bitmap中将这些位置对应的比特位置为0即可。

完成上面的工作以后,在把这个文件的文件名和inode编号的映射关系从目录中移除,这个过程只需要把目录的block块在block bitmap中的位置置为0即可,表示这些block块没有文件在使用,其他文件可以使用,向其中写入内容。

删除目录中的一个文件需要对目录中的某些block块设置为可写,因此,需要有对目录的w权限。

删除一个文件的本质是将这个文件在block bitmap和inode bitmap中所使用的比特位置0,表示这个文件之前在inode table中申请的inode可以被别人使用,这个文件之前在data blocks中申请的block块可以被别人使用,即这个文件之前申请的inode和block块是可写状态的。

删除的文件进行复原也是这个原理,只要能找到这个文件之前使用的inode的编号,在inode bitmap和block bitmap中将相应位置变为1即可完成文件的恢复。

磁盘的格式化是将inode bitmap和block bitmap全部置空的过程,并非真正的删除了数据。

查看目录中的一个文件

查看目录中的一个文件,本质是通过文件名在目录的block块中找到文件名对应的inode编号,根据文件的inode编号在文件系统中可以找到文件的inode,从而获得文件的相关属性。查看目录中的文件需要访问目录的block块,因此,需要对目录有r权限。

软硬链接

创建软链接使用ln -s,创建硬链接使用ln.

[slowstep@localhost day31]$ ls
test.c
[slowstep@localhost day31]$ ln -s test.c test.sort
[slowstep@localhost day31]$ ll -i
total 0
77088 -rw-rw-r--. 1 slowstep slowstep 0 Dec  3 20:04 test.c
77131 lrwxrwxrwx. 1 slowstep slowstep 6 Dec  3 21:19 test.sort -> test.c
[slowstep@localhost day31]$ ln test.c test.hard
[slowstep@localhost day31]$ ll -i
total 0
77088 -rw-rw-r--. 2 slowstep slowstep 0 Dec  3 20:04 test.c
77088 -rw-rw-r--. 2 slowstep slowstep 0 Dec  3 20:04 test.hard
77131 lrwxrwxrwx. 1 slowstep slowstep 6 Dec  3 21:19 test.sort -> test.c
软链接

一般使用ln生成符号链接文件,指的是通过ln -s命令生成软链接文件,软链接比较常用,经常在动态库中被使用到,软链接是一个独立的文件,它有独立的inode,它的作用类似于快捷方式。

[slowstep@localhost day31]$ ln -s ../day10/radixsort/a.out a.soft
[slowstep@localhost day31]$ ll -i
total 0
77088 lrwxrwxrwx. 1 slowstep slowstep 24 Dec  3 21:27 a.soft -> ../day10/radixsort/a.out
[slowstep@localhost day31]$ ./a.soft 
hello world
硬链接

硬链接没有独立的inode,给一个文件创建一个硬链接,会增加该文件的链接数,使用的是引用计数的原理,创建硬链接可以认为是起别名。

[slowstep@localhost day31]$ ll -i
total 0
77088 -rw-rw-r--. 1 slowstep slowstep 0 Dec  3 21:31 test.txt #链接数为1
[slowstep@localhost day31]$ ln test.txt test.hard
[slowstep@localhost day31]$ ll -i
total 0
77088 -rw-rw-r--. 2 slowstep slowstep 0 Dec  3 21:31 test.hard #链接数为2
77088 -rw-rw-r--. 2 slowstep slowstep 0 Dec  3 21:31 test.txt #链接数为2

创建硬链接的本质是在test.txt所在的目录的block块中新写入了一组映射关系(test.hard-77088),并没有创建新的文件,只是增加了test.txt的计数。在进行删除时,本质是删除映射关系,减少计数,当计数为1时,在进行删除才会根据77088找到对应的inode,将inode bitmap和data blocks中对应的位置0。

unlink

unlink也可以进行删除文件,它的原理也是删除链接数,和rm一样,当链接数为1时,在进行删除才会将inode bitmap和block bitmap中的位置为0.

[slowstep@localhost day31]$ ll -i
total 0
77088 -rw-rw-r--. 2 slowstep slowstep 0 Dec  3 21:31 test.hard
77088 -rw-rw-r--. 2 slowstep slowstep 0 Dec  3 21:31 test.txt
[slowstep@localhost day31]$ unlink test.hard 
[slowstep@localhost day31]$ ll -i
total 0
77088 -rw-rw-r--. 1 slowstep slowstep 0 Dec  3 21:31 test.txt
[slowstep@localhost day31]$ unlink test.txt 
[slowstep@localhost day31]$ ll -i
total 0

目录

目录也是一个文件,默认创建一个目录,它的计数是2,因为默认一个目录除了它自己的目录名作为文件名,还有一个.作为它的文件名。

[slowstep@localhost day31]$ mkdir dir
[slowstep@localhost day31]$ ll -i
total 0
35389131 drwxrwxr-x. 2 slowstep slowstep 6 Dec  3 21:45 dir
[slowstep@localhost day31]$ cd dir/
[slowstep@localhost dir]$ ll -ia
total 0
35389131 drwxrwxr-x. 2 slowstep slowstep  6 Dec  3 21:45 . #这个.就是dir的一个别名,计数是2,同理可在dir下在创建一个目录,该目录下的..也表示dir,此时dir的计数变为3
3600627 drwxrwxr-x. 3 slowstep slowstep 17 Dec  3 21:45 ..

根据上面的规则,一个目录的引用计数-2就是这个目录下含有的目录的个数。

[slowstep@localhost day31]$ tree
.
└── dir
    ├── d1
    ├── d2
    ├── d3
    └── d4

5 directories, 0 files
[slowstep@localhost day31]$ ll -ia
total 4
 3600627 drwxrwxr-x.  3 slowstep slowstep   17 Dec  3 21:45 .
16792644 drwxrwxr-x. 34 slowstep slowstep 4096 Dec  3 19:11 ..
35389131 drwxrwxr-x.  6 slowstep slowstep   46 Dec  3 21:49 dir
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值