Linux 文件系统底层原理笔记:磁盘结构、ext2 文件系统与软硬链接解析

文章目录

  • 一、理解硬件
    • 1.1 磁盘、服务器、机柜、机房
    • 1.2 磁盘物理结构
    • 1.3 磁盘的存储结构
    • 1.4 磁盘的逻辑结构
      • 1.4.1 理解过程
      • 1.4.2 真实过程
    • 1.5 CHS && LBA地址
  • 二、引入文件系统
    • 2.1 引入"块"概念
    • 2.2 引入"分区"概念
    • 2.3 引入"inode"概念
  • 三、ext2文件系统
    • 3.1 宏观认识
    • 3.2 Block Group
    • 3.3 块组内部构成
      • 3.3.1 超级块(Super Block)
      • 3.3.2 GDT (Group Descriptor Table)
      • 3.3.3 块位图(Block Bitmap)
      • 3.3.4 inode位图(Inode Bitmap)
      • 3.3.5 i 节点表(Inode Table)
      • 3.3.6 Data Block
    • 3.4 inode和datablock映射(弱化)
    • 3.5 目录与文件名
    • 3.6 路径解析
    • 3.7 路径缓存
    • 3.8 挂载分区
      • 3.8.1 一个结论
    • 3.9 文件系统总结
  • 四、软硬连接
    • 4.1硬链接
    • 4.2 软链接
    • 4.3 软硬连接对比
    • 4.4 软硬连接的用途:

一、理解硬件

1.1 磁盘、服务器、机柜、机房

  • 机械磁盘是计算机中唯一的一个机械设备
  • 磁盘外设
  • 容量大,价格便宜

1.2 磁盘物理结构

在这里插入图片描述

1.3 磁盘的存储结构

在这里插入图片描述
扇区:是磁盘存储数据的基本单位,512字节,块设备
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如何定位一个扇区呢?

  • 可以先定位磁头(header)
  • 确定磁头要访问哪一个柱面(磁道)(cylinder)
  • 定位一个扇区(sector)
  • CHS地址定位

文件=内容+属性都是数据,无非就是占据那几个扇区的问题!能定位一个扇区了,能不能定位多个扇区呢?

  • 扇区是从磁盘读出和写入信息的最小单位,通常大小为512字节。
  • 磁头(head)数:每个盘片一般有上下两面,分别对应1个磁头,共2个磁头
  • 磁道(track)数:磁道是从盘片外圈往内圈编号0磁道,1磁道.,靠近主轴的同心圆用于停靠磁头,不存储数据
  • 柱面(cylinder)数:磁道构成柱面,数量上等同于磁道个数
  • 扇区(sector)数:每个磁道都被切分成很多扇形区域,每道的扇区数量相同
  • 圆盘(platter)数:就是盘片的数量
  • 磁盘容量=磁头数X磁道(柱面)数×每道扇区数×每扇区字节数
  • 细节:传动臂上的磁头是共进退的(这点比较重要,后面会说明)

柱面(cylinder),磁头(head),扇区(sector),显然可以定位数据了,这就是数据定位(寻址)方式之一,CHS寻址方式。

CHS寻址
对早期的磁盘非常有效,知道用哪个磁头,读取哪个柱面上的第几扇区就可以读到数据了。
但是CHS模式支持的硬盘容量有限,因为系统用8bit来存储磁头地址,用10bit来存储柱面地址,用6bit来存储扇区地址,而一个扇区共有512Byte,这样使用CHS寻址一块硬盘最大容量为256102463*512B=8064MB(1MB=1048576B)(若按1MB=1000000B来算就是8.4GB)

1.4 磁盘的逻辑结构

1.4.1 理解过程

在这里插入图片描述
磁带上面可以存储数据,我们可以把磁带“拉直”,形成线性结构
在这里插入图片描述
那么磁盘本质上虽然是硬质的,但是逻辑上我们可以把磁盘想象成为卷在一起的磁带,那么磁盘的逻辑存储结构我们也可以类似于:

在这里插入图片描述
这样每一个扇区,就有了一个线性地址(其实就是数组下标),这种地址叫做LBA
在这里插入图片描述

1.4.2 真实过程

一个细节:传动臂上的磁头是共进退的
在这里插入图片描述
柱面是一个逻辑上的概念,其实就是每一面上,相同半径的磁道逻辑上构成柱面。所以,磁盘物理上分了很多面,但是在我们看来,逻辑上,磁盘整体是由“柱面”卷起来的。

所以,磁盘的真实情况是:
磁道
某一盘面的某一个磁道展开:
在这里插入图片描述
即:一维数组

柱面
整个磁盘所有盘面的同一个磁道,即柱面展开:
在这里插入图片描述
在这里插入图片描述

  • 柱面上的每个磁道,扇区个数是一样的
  • 这不就是二维数组

整盘

在这里插入图片描述
整个磁盘不就是多张二维的扇区数组表(三维数组?)

所以,寻址一个扇区:先找到哪一个柱面(Cylinder),在确定柱面内哪一个磁道(其实就是磁头位置,Head),在确定扇区(Sector),所以就有了CHS。

我们之前学过C/C++的数组,在我们看来,其实全部都是一维数组:
在这里插入图片描述
所以,每一个扇区都有一个下标,我们叫做LBA(Logical BlockAddress)地址,其实就是线性地址。所以怎么计算得到这个LBA地址呢?

在这里插入图片描述
LBA,1OOO,CHS必须要!LBA地址转成CHS地址,CHS如何转换成为LBA地址。

OS只需要使用LBA就可以了!!LBA地址转成CHS地址,CHS如何转换成为LBA地址。谁做啊??磁盘自己来做!固件(硬件电路,伺服系统)

1.5 CHS && LBA地址

CHS转成LBA:

  • 磁头数*每磁道扇区数=单个柱面的扇区总数
  • LBA=柱面号C*单个柱面的扇区总数+磁头号H*每磁道扇区数+扇区号S-1
  • 即:LBA=柱面号C*(磁头数*每磁道扇区数)+磁头号H*每磁道扇区数+扇区号S-1
  • 扇区号通常是从1开始的,而在LBA中,地址是从0开始的
  • 柱面和磁道都是从0开始编号的
  • 总柱面,磁道个数,扇区总数等信息,在磁盘内部会自动维护,上层开机的时候,会获取到这些参数。

LBA转成CHS:

  • 柱面号C=LBA//(磁头数*每磁道扇区数)【就是单个柱面的扇区总数]
  • 磁头号H=(LBA%(磁头数*每磁道扇区数)//每磁道扇区数
  • 扇区号S=(LBA%每磁道扇区数) + 1
  • “//”:表示除取整

所以:从此往后,在磁盘使用者看来,根本就不关心CHS地址,而是直接使用LBA地址,磁盘内部自己转换。所以:
从现在开始,磁盘就是一个元素为扇区的一维数组,数组的下标就是每一个扇区的LBA地址。OS使用磁盘,就可以用一个数字访问磁盘扇区了。

二、引入文件系统

2.1 引入"块"概念

其实硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,其实是不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个”块”(block)。
硬盘的每个分区是被划分为一个个的”块”。一个”块”的大小是由格式化的时候确定的,并且不可以更改,最常见的是4KB,即连续八个扇区组成一个”块”。”块”是文件存取的最小单位

注意:

  • 磁盘就是一个三维数组,我们把它看待成为一个”一维数组”,数组下标就是LBA,每个元素都是扇区
  • 每个扇区都有LBA,那么8个扇区一个块,每一个块的地址我们也能算出来。
  • 知道LBA:块号=LBA/8
  • 知道块号:LAB=块号*8+n.(n是块内第几个扇区)

在这里插入图片描述

2.2 引入"分区"概念

其实磁盘是可以被分成多个分区(partition)的,以Windows观点来看,你可能会有一块磁盘并且将它分区成C,D,E盘。那个C,D,E就是分区。分区从实质上说就是对硬盘的一种格式化。但是Linux的设备都是以文件形式存在,那是怎么分区的呢?

柱面是分区的最小单位,我们可以利用参考柱面号码的方式来进行分区,其本质就是设置每个区的起始柱面和结束柱面号码。此时我们可以将硬盘上的柱面(分区)进行平铺,将其想象成一个大的平面,如下图所示:
在这里插入图片描述
注意:

  • 柱面大小一致,扇区个位一致,那么其实只要知道每个分区的起始和结束柱面号,知道每一个柱面多少个扇区,那么该分区多大,其实和解释LBA是多少也就清楚了。

在这里插入图片描述

2.3 引入"inode"概念

之前我们说过文件=数据+属性,我们使用 ls -l 的时候看到的除了看到文件名,还能看到文件元数据(属性)。

zkp@zkp:~/linux/25/6/8$ ls -l
total 0
-rw-rw-r-- 1 zkp zkp 0 Jun  8 13:43 test.txt

每行包含7列:

  • 模式
  • 硬链接数
  • 文件所有者
  • 大小
  • 最后修改时间
  • 文件名

Is-l 读取存储在磁盘上的文件信息,然后显示出来

在这里插入图片描述
其实这个信息除了通过这种方式来读取,还有一个 stat 命令能够看到更多信息

zkp@zkp:~/linux/25/6/8$ stat test.txt File: test.txtSize: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: fc02h/64514d	Inode: 1321121     Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1002/     zkp)   Gid: ( 1002/     zkp)
Access: 2025-06-08 13:43:12.395211794 +0800
Modify: 2025-06-08 13:43:12.395211794 +0800
Change: 2025-06-08 13:43:12.395211794 +0800Birth: 2025-06-08 13:43:12.395211794 +0800

到这我们要思考一个问题,文件数据都储存在”块”中,那么很显然,我们还必须找到一个地方储存文件的元信息(属性信息),比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做 inode,中文译名为”索引节点”。

在这里插入图片描述
每一个文件都有对应的 inode,里面包含了与该文件有关的一些信息。为了能解释清楚 inode,我们需要是深入了解一下文件系统。

注意:

  • Linux下文件的存储是属性和内容分离存储
  • Linux下,保存文件属性的集合叫做 inode,一个文件,一个inode,inode内有一个唯一的标识符,叫做 inode 号

所以一个文件的属性inode长什么样子呢?

struct ext2_inode {__le16  i_mode;         /* 文件类型和权限 */__le16  i_uid;          /* 所有者用户ID */__le32  i_size;         /* 文件大小(字节) */__le32  i_atime;        /* 最后访问时间 */__le32  i_ctime;        /* 最后inode变更时间 */__le32  i_mtime;        /* 最后修改时间 */__le32  i_dtime;        /* 删除时间 */__le16  i_gid;          /* 所有者组ID */__le16  i_links_count;  /* 硬链接数 */__le32  i_blocks;       /* 占用的数据块数(512字节为单位) */__le32  i_flags;        /* 文件标志(如压缩、不可变等) */__le32  i_osd1;         /* 操作系统特定字段1 */__le32  i_block[15];    /* 数据块指针(直接+间接) */__le32  i_generation;   /* 文件版本(用于NFS) */__le32  i_file_acl;     /* 文件访问控制列表 */__le32  i_dir_acl;      /* 目录访问控制列表 */__le32  i_faddr;        /* 碎片地址 *//* 剩余字段为操作系统特定数据 */__u8    i_osd2[12];     /* 操作系统特定字段2 */
};

注意

  • 文件名属性并未纳入到inode数据结构内部
  • inode的大小一般是128字节或者256,我们后面统一128字节
  • 任何文件的内容大小可以不同,但是属性大小一定是相同的

到目前为止,相信大家还有两个问题:

  1. 我们已经知道硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,读取的基本单位是”块”。“块”又是硬盘的每个分区下的结构,难道“块”是随意的在分区上排布的吗?那要怎么找到“块”呢?
  2. 还有就是上面提到的存储文件属性的inode,又是如何放置的呢?

文件系统就是为了组织管理这些的!!

三、ext2文件系统

3.1 宏观认识

所有的准备工作都已经做完,是时候认识下文件系统了。我们想要在硬盘上储文件,必须先把硬盘格式化为某种格式的文件系统,才能存储文件。文件系统的目的就是组织和管理硬盘中的文件。在Linux系统中,最常见的是ext2系列的文件系统。其早期版本为ext2,后来又发展出ext3和ext4。ext3和ext4虽然对ext2进行了增强,但是其核心设计并没有发生变化,我们仍是以较老的ext2作为演示对象。

ext2文件系统将整个分区划分成若干个同样大小的块组(BlockGroup),如下图所示。只要能管理一个分区就能管理所有分区,也就能管理所有磁盘文件。

在这里插入图片描述
上图中启动块(Boot Block/Sector)的大小是确定的,为1KB,由PC标准规定,用来存储磁盘分区信息和启动信息,任何文件系统都不能修改启动块。启动块之后才是ext2文件系统的开始。

3.2 Block Group

ext2文件系统会根据分区的大小划分为数个BlockGroup。而每个BlockGroup都有着相同的结构组成。政府管理各区的例子

3.3 块组内部构成

3.3.1 超级块(Super Block)

存放文件系统本身的结构信息,描述整个分区的文件系统信息。记录的信息主要有:bolck和inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。SuperBlock的信息被破坏,可以说整个文件系统结构就被破坏了

超级块在每个块组的开头都有一份拷贝(第一个块组必须有,后面的块组可以没)。为了保证文件系统在磁盘部分扇区出现物理问题的情况下还能正常工作,就必须保证文件系统的superblock信息在这种情况下也能正常访问。所以一个文件系统的superblock会在多个blockgroup中进行备份,这些super block区域的数据保持一致。

struct ext2_super_block {__le32  s_inodes_count;       /* inode 总数 */__le32  s_blocks_count;       /* 块总数 */__le32  s_r_blocks_count;     /* 保留块总数 */__le32  s_free_blocks_count;  /* 空闲块数 */__le32  s_free_inodes_count;  /* 空闲 inode 数 */__le32  s_first_data_block;   /* 第一个数据块编号 */__le32  s_log_block_size;     /* log2(块大小),单位为字节 */__le32  s_log_frag_size;      /* log2(碎片大小),单位为字节 */__le32  s_blocks_per_group;   /* 每组块数 */__le32  s_frags_per_group;    /* 每组碎片数 */__le32  s_inodes_per_group;   /* 每组 inode 数 */__le32  s_mtime;              /* 最后挂载时间 */__le32  s_wtime;              /* 最后写入时间 */__le16  s_mnt_count;          /* 挂载次数 */__le16  s_max_mnt_count;      /* 最大挂载次数(超过则检查文件系统) */__le16  s_magic;              /* 魔数(0xEF53 标识 Ext2 文件系统) */__le16  s_state;              /* 文件系统状态(正常/错误等) */__le16  s_errors;             /* 错误处理方式 */__le16  s_minor_rev_level;    /* 次版本号 */__le32  s_lastcheck;          /* 最后检查时间 */__le32  s_checkinterval;      /* 检查间隔时间(秒) */__le32  s_creator_os;         /* 创建文件系统的操作系统 */__le32  s_rev_level;          /* 主版本号 */__le16  s_def_resuid;         /* 默认保留用户 UID */__le16  s_def_resgid;         /* 默认保留组 GID *//* 以下字段为扩展功能字段(根据版本可能包含更多属性) */__le32  s_first_ino;          /* 第一个非保留 inode 编号 */__le16  s_inode_size;         /* inode 结构体大小(字节) */__le16  s_block_group_nr;     /* 所在块组编号 */__le32  s_feature_compat;     /* 兼容特性标志 */__le32  s_feature_incompat;   /* 不兼容特性标志 */__le32  s_feature_ro_compat;  /* 只读兼容特性标志 */__le32  s_uuid[2];            /* 文件系统 UUID */char    s_volume_name[16];     /* 卷名 */char    s_last_mounted[64];    /* 最后挂载点 */__le32  s_algorithm_usage_bitmap; /* 哈希算法使用位图 *//* 更多扩展字段(如 Journal 相关、64 位支持等) */__u8    s_prealloc_blocks;     /* 预分配块数 */__u8    s_prealloc_dir_blocks; /* 目录预分配块数 */__u16   s_padding1;           /* 填充字段 */__le32  s_default_mount_opts; /* 默认挂载选项 */__le32  s_first_meta_bg;      /* 第一个元数据块组 */__u32   s_mkfs_time;          /* 创建时间 *//* 其他可能的扩展字段(随内核版本增加) */
};

3.3.2 GDT (Group Descriptor Table)

块组描述符表,描述块组属性信息,整个分区分成多个块组就对应有多少个块组描述符。每个块组描述符存储一个块组的描述信息,如在这个块组中从哪里开始是inodeTable,从哪里开始是Data Blocks,空闲的inode和数据块还有多少个等等。块组描述符在每个块组的开头都有一份拷贝。

struct ext2_group_desc {__le32  bg_block_bitmap;      /* 块位图所在块号 */__le32  bg_inode_bitmap;      /* inode 位图所在块号 */__le32  bg_inode_table;       /* inode 表所在块号 */__le16  bg_free_blocks_count; /* 空闲块计数 */__le16  bg_free_inodes_count; /* 空闲 inode 计数 */__le16  bg_used_dirs_count;   /* 目录 inode 计数 */__le16  bg_pad;               /* 填充字段 */__u32   bg_reserved[3];       /* 保留字段 */
};

3.3.3 块位图(Block Bitmap)

  • Block Bitmap中记录着DataBlock中哪个数据块已经被占用,哪个数据块没有被占用

3.3.4 inode位图(Inode Bitmap)

  • 每个bit表示一个inode是否空闲可用。

3.3.5 i 节点表(Inode Table)

  • 存放文件属性如文件大小,所有者,最近修改时间等
  • 当前分组所有Inode属性的集合
  • inode编号以分区为单位,整体划分,不可跨分区

3.3.6 Data Block

数据区:存放文件内容,也就是一个一个的Block。根据不同的文件类型有以下几种情况:

  • 对于普通文件,文件的数据存储在数据块中。
  • 对于目录,该目录下的所有文件名和目录名存储在所在目录的数据块中,除了文件名外,Is-l命令看到的其它信息保存在该文件的inode中。
  • Block号按照分区划分,不可跨分区

3.4 inode和datablock映射(弱化)

  • inode内部存在__le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */,EXT2_N_BLOCKS=15,就是用来进行inode和block映射的
  • 这样文件=内容+属性,就都能找到了。

在这里插入图片描述
思考:

  • 请解释:知道inode号的情况下,在指定分区,请解释:对文件进行增、删、查、改是在做什么?

结论:

  • 分区之后的格式化操作,就是对分区进行分组,在每个分组中写入SB、GDT、Block、Bitmap、Inode Bitmap等管理信息,这些管理信息统称:文件系统
  • 只要知道文件的inode号,就能在指定分区中确定是哪一个分组,进而在哪一个分组确定是哪一个inode
  • 拿到inode文件属性和内容就全部都有了

下面,通过touch一个新文件来看看如何工作。

zkp@zkp:~/linux/25/6/8$ touch abc
zkp@zkp:~/linux/25/6/8$ ls -i abc
363466 abc

在这里插入图片描述
创建一个新文件主要有以下4个操作:

  1. 存储属性
    内核先找到一个空闲的i节点(这里是263466)。内核把文件信息记录到其中。
  2. 存储数据
    该文件需要存储在三个磁盘块,内核找到了三个空闲块:300,500,800。将内核缓冲区的第一块数据复制到300,下一块复制到500,以此类推。
  3. 记录分配情况
    文件内容按顺序300,500,800存放。内核在inode上的磁盘分布区记录了上述块列表。
  4. 添加文件名到目录
    新的文件名abc。linux如何在当前的目录中记录这个文件?内核将入口(263466,abc)添加到目录文件。文件名和inode之间的对应关系将文件名和文件的内容及属性连接起来。

3.5 目录与文件名

问题:

  • 我们访问文件,都是用的文件名,没用过inode号啊?
  • 目录是文件吗?如何理解?

答案:

  • 目录也是文件,但是磁盘上没有目录的概念,只有文件属性+文件内容的概念。
  • 目录的属性不用多说,内容保存的是:文件名和inode号的映射关系

3.6 路径解析

问题:打开当前工作目录文件,查看当前工作目录文件的内容?当前工作目录不也是文件吗?我们访问当前工作目录不也是只知道当前工作目录的文件名吗?要访问它,不也得知道当前工作目录的inode吗?

答案1:所以也要打开:当前工作目录的上级目录,额,上级目录不也是目录吗??不还是上面的问题吗?

答案2:所以类似"递归”,需要把路径中所有的目录全部解析,出口是”/"根目录。最终答案3:而实际上,任何文件,都有路径,访问目标文件,比如:/home/whb/code/test/test/test.c

都要从根目录开始,依次打开每一个目录,根据目录名,依次访问每个目录下指定的目录,直到访问到test.c。这个过程叫做Linux路径解析

注意:

  • 所以,我们知道了:访问文件必须要有目录+文件名=路径的原因
  • 根目录固定文件名,inode号,无需查找,系统开机之后就必须知道

可是路径谁提供?

  • 你访问文件,都是指令/工具访问,本质是进程访问,进程有CWD!进程提供路径。
  • 你open文件,提供了路径

可是最开始的路径从哪里来?

  • 所以Linux为什么要有根目录,根目录下为什么要有那么多缺省目录?
  • 你为什么要有家目录,你自己可以新建目录?
  • 上面所有行为:本质就是在磁盘文件系统中,新建目录文件。而你新建的任何文件,都在你或者系统指定的目录下新建,这不就是天然就有路径了嘛!
  • 系统+用户共同构建Linux路径结构.

3.7 路径缓存

问题1:Linux磁盘中,存在真正的目录吗?
答案:不存在,只有文件。只保存文件属性+文件内容
问题2:访问任何文件,都要从/目录开始进行路径解析?
答案:原则上是,但是这样太慢,所以Linux会缓存历史路径结构
问题2:Linux目录的概念,怎么产生的?
答案:打开的文件是目录的话,由OS自己在内存中进行路径维护

Linux中,在内核中维护树状路径结构的内核结构体叫做:struct dentry

struct dentry {/* 哈希链表节点,用于 dentry 缓存(dcache) */struct hlist_node d_hash;/* 父目录的 dentry(NFS 等场景可能为 NULL) */struct dentry *d_parent;/* 目录项对应的 inode(可能为 NULL,如未挂载的文件系统) */struct inode *d_inode;  /* 目录项名称(d_name 是一个复合结构体) */struct qstr d_name;/* 引用计数:d_count > 0 表示被引用,0 可释放 */atomic_t d_count;/* 状态标志(如 DCACHE_OP_HASHED、DCACHE_NEED_AUTOFS 等) */unsigned int d_flags;/* 指向目录项所在的 vfsmount(文件系统挂载点) */struct vfsmount *d_mount;/* 操作函数集合(如创建、删除、重命名目录项等) */const struct dentry_operations *d_op;/* 回写机制:用于同步目录项修改到磁盘 */unsigned long d_time;/* 与 inode 关联的目录项缓存(dcache)锁 */struct rcu_head d_rcu;/* 以下字段为扩展功能字段(随内核版本增加) */void *d_fsdata;         /* 文件系统私有数据 */unsigned char d_iname[DNAME_INLINE_LEN]; /* 短名称内联存储 */const struct super_block *d_sb; /* 所属超级块 *//* 其他可能的字段(如 NFS 客户端的缓存信息等) */
};

注意:

  • 每个文件其实都要有对应的dentry结构,包括普通文件。这样所有被打开的文件,就可以在内存中形成整个树形结构
  • 整个树形节点也同时会隶属于LRU(LeastRecentlyUsed,最近最少使用)结构中,进行节点淘汰
  • 整个树形节点也同时会隶属于Hash,方便快速查找
  • 更重要的是,这个树形结构,整体构成了Linux的路径缓存结构,打开访问任何文件,都在先在这棵树下根据路径进行查找,找到就返回属性inode和内容,没找到就从磁盘加载路径,添加dentry结构,缓存新路径

在这里插入图片描述

3.8 挂载分区

我们已经能够根据inode号在指定分区找文件了,也已经能根据目录文件内容,找指定的inode了,在指定的分区内,我们可以为所欲为了。可是:
问题:inode不是不能跨分区吗?Linux不是可以有多个分区吗?我怎么知道我在哪一个分区???

3.8.1 一个结论

  • 分区写入文件系统,无法直接使用,需要和指定的目录关联,进行挂载才能使用
  • 所以,可以根据访问目标文件的=="路径前缀”==准确判断我在哪一个分区。

3.9 文件系统总结

  • 下面用几张图总结
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

四、软硬连接

4.1硬链接

我们看到,真正找到磁盘上文件的并不是文件名,而是inode。其实在linux中可以让多个文件名对应于同一个inode

zkp@zkp:~/linux/25/6/8$ touch abc
zkp@zkp:~/linux/25/6/8$ ln abc def
zkp@zkp:~/linux/25/6/8$ ls -li abc def
1321122 -rw-rw-r-- 2 zkp zkp 0 Jun  8 14:18 abc
1321122 -rw-rw-r-- 2 zkp zkp 0 Jun  8 14:18 def
  • abc和def的链接状态完全相同,他们被称为指向文件的硬链接。内核记录了这个连接数,inode 1321122的硬连接数为2。
  • 我们在删除文件时干了两件事情:1.在目录中将对应的记录删除,2.将硬连接数-1,如果为0,则将对应的磁盘释放。

4.2 软链接

硬链接是通过inode引l用另外一个文件,软链接是通过名字引用另外一个文件,但实际上,新的文件和被引用的文件的inode不同,应用常见上可以想象成一个快捷方式。在shell中的做法

zkp@zkp:~/linux/25/6/8$ ln -s abc abc.s
zkp@zkp:~/linux/25/6/8$ ls -li
total 0
1321122 -rw-rw-r-- 2 zkp zkp 0 Jun  8 14:18 abc
1321123 lrwxrwxrwx 1 zkp zkp 3 Jun  8 14:24 abc.s -> abc
1321122 -rw-rw-r-- 2 zkp zkp 0 Jun  8 14:18 def
1321121 -rw-rw-r-- 1 zkp zkp 0 Jun  8 13:43 test.txt

在这里插入图片描述

acm
下面再提一下文件的三个时间:

  • Access最后访问时间
  • Modify文件内容最后修改时间
  • Change属性最后修改时间

4.3 软硬连接对比

  • 软连接是独立文件
  • 硬链接只是文件名和目标文件inode的映射关系

4.4 软硬连接的用途:

硬链接

  • ... 就是硬链接
  • 文件备份

软连接

  • 类似快捷方式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/bicheng/84229.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

75Qt窗口_Qt窗口概览

Qt 窗⼝ 是通过 QMainWindow类 来实现的。 QMainWindow 是⼀个为⽤⼾提供主窗⼝程序的类,继承⾃ QWidget 类,并且提供了⼀个预定义的布局。 QMainWindow 包含 ⼀个菜单栏(menu bar)、多个⼯具栏(tool bars)、多个浮动窗⼝&#x…

Appium+python自动化(九)- 定位元素工具

简介 环境搭建好了,其他方面的知识也准备的差不多了,那么就开始下一步元素定位,元素定位主要介绍如何使用uiautomatorviewer,通过定位到页面上的元素,然后进行相应的点击等操作. 此外在介绍另一款工具:Insp…

apipost将token设置为环境变量

右上角 可以新增或者是修改当前的环境 环境变量增加一个token,云端值和本地值可以不用写 在返回token的接口里设置后执行操作,通常是登录的接口 右侧也有方法提示 //设置环境变量 apt.environment.set("token", response.json.data.token); 在需要传t…

【Docker 02】Docker 安装

🌈 一、各版本的平台支持情况 ⭐ 1. Server 版本 Server 版本的 Docker 就只有个命令行,没有界面。 Platformx86_64 / amd64arm64 / aarch64arm(32 - bit)s390xCentOs√√Debian√√√Fedora√√Raspbian√RHEL√SLES√Ubuntu√√√√Binaries√√√ …

青少年编程与数学 01-011 系统软件简介 08 Windows操作系统

青少年编程与数学 01-011 系统软件简介 08 Windows操作系统 1. Windows操作系统的起源与发展1.1 早期版本(1985-1995)1.2 Windows 9x系列(1995-2000)1.3 Windows NT系列(1993-2001)1.4 Windows XP及以后版…

微服务架构的性能优化:链路追踪与可观测性建设

📋 目录 引言:微服务性能挑战微服务架构性能瓶颈分析可观测性体系概述链路追踪技术深度解析性能监控指标体系日志聚合与分析分布式追踪系统实现性能优化策略与实践自动化性能调优故障诊断与根因分析最佳实践与案例研究未来发展趋势 引言 随着微服务架…

ubuntu屏幕复制

在ubnuntu20中没有办法正常使用镜像功能,这里提供一下复制屏幕的操作. 使用xrandr查看所有的显示器情况 这里我发现自己的电脑没有办法直接设置分辨率,但是外接的显示器可以设置,从命令行来说就是设置: xrandr --output HDMI-0 --mode 1920x1080那怎么样才能将原生电脑屏幕换…

Android 线性布局中常见的冲突属性总结

1. gravity vs layout_gravity 冲突原因:两者作用对象不同,混用会导致行为异常。 区别: android:gravity:父容器的属性,控制子元素在容器内的对齐方式。android:layout_gravity:子元素的属性,控…

0x-4-Oracle 23 ai-sqlcl 25.1.1 独立安装-配置和优化

一、独立安装sqlcl 1. ​安装 Java 环境​ SQLcl 需要 Java 1.8.0_220 或更高版本, Oracle Linux9.6 上已经默认安装Oracle 23ai后Java 是11 lts版本 如果java jdk安装错误将遇上SQLcl困扰n多人的bug sql /nolog 错误:找不到或加载主类 oracle.dbto…

如何评价华为最新长焦专利技术?能否颠覆手机长焦摄影的目前限制?

击上方关注 “终端研发部” 设为“星标”,和你一起掌握更多数据库知识 目前透露的消息来看是3.7倍和10倍!!! 据悉,华为即将发布的Pura 80系列手机将率先采用这一革命性的专利技术。 华为的伸缩专利让镜头模组学会了&qu…

基于SpringBoot实现的大创管理系统设计与实现【源码+文档】

基于SpringBootVue实现的大创管理系统采用前后端分离架构方式,系统设计了管理员、学生、指导老师、院系管理员两种角色,系统实现了用户登录与注册、个人中心、学生管理、指导老师管理、院系管理员管理、优秀项目管理、项目类型管理、项目信息管理、项目申…

4-C#的不同窗口传值

C#的不同窗口传值 1.通过构造函数传值 this.Hide(); Form1 form01 new Form1(textBox2.Text); //Application.Run(form01); form01.Show();public Form1(string aaa) {InitializeComponent();label12.Text aaa; }2.全局类传值 namespace WindowsFormsApp1 {public class G…

CentOS 7 如何pip3安装pyaudio?

CentOS 7 如何pip3安装pyaudio&#xff1f; # 先将yum软件源改为阿里云镜像源 http://mirrors.aliyun.com/centos-vault/7.9.2009/ bash <(curl -sSL https://linuxmirrors.cn/main.sh) # 基于一键换源脚本&#xff0c;全部回车即可# pip3安装模块是从源码构建&#xff08;…

低代码采购系统搭建:鲸采云+能源行业订单管理自动化案例

在能源行业数字化转型浪潮下&#xff0c;某大型能源集团通过鲸采云低代码平台&#xff0c;仅用3周时间就完成了采购订单管理系统的定制化搭建。本文将揭秘这一成功案例的实施路径与关键成效。 项目背景与挑战 该企业面临&#xff1a; 供应商分散&#xff1a;200供应商使用不同…

基于机器学习的智能故障预测系统:构建与优化

前言 在现代工业生产中&#xff0c;设备故障不仅会导致生产中断&#xff0c;还会带来巨大的经济损失。传统的故障检测方法依赖于人工巡检和定期维护&#xff0c;这种方式效率低下且难以提前预测潜在故障。随着工业物联网&#xff08;IIoT&#xff09;和机器学习技术的发展&…

Android启动时长优化(kernel部分)

硬件平台&#xff1a;QCS6115 软件平台&#xff1a;Android13 Vendor Android14 Qssi 需求&#xff1a;设备从logo到进入Home页面持续时间过长&#xff0c;接近60s&#xff0c;遂需要优化。首先尝试内核部分的配置优化及有关裁剪&#xff0c;具体改动如下&#xff1a; diff …

若依添加添加监听容器配置(删除键,键过期)

1、配置Redis的键触发事件 # 基础配置 bind 0.0.0.0 # 允许所有IP连接 protected-mode no # 关闭保护模式&#xff08;生产环境建议结合密码使用&#xff09; port 6379 # 默认端口 daemonize no …

vb监测Excel两个单元格变化,达到阈值响铃

需求 在Excel中实现监控两个单元格之间的变化范围&#xff0c;当达到某个设定的值的范围内时&#xff0c;实现自动响铃提示。 实现&#xff1a; 首先设置Excel&#xff0c;开启宏、打开开发者工具&#xff0c;点击visual Basic按钮&#xff0c;然后在左侧双击需要监测的shee…

用 Melos 解决 Flutter Monorepo 的依赖冲突:一个真实案例

在 Flutter 项目开发中&#xff0c;尤其是采用 Monorepo 架构管理多个相互关联的包时&#xff0c;依赖冲突是一个常见且令人头疼的问题。不同的包可能依赖同一个库的不同版本&#xff0c;导致项目无法编译或运行时出现难以调试的错误。 本文将基于一个 真实的 Flutter Monorep…

Spring AI 项目实战(五):Spring Boot + AI + DeepSeek + Redis 实现聊天应用上下文记忆功能(附完整源码)

系列文章 序号文章名称1Spring AI 项目实战(一):Spring AI 核心模块入门2Spring AI 项目实战(二):Spring Boot + AI + DeepSeek 深度实战(附完整源码)3Spring AI 项目实战(三):Spring Boot + AI + DeepSeek 打造智能客服系统(附完整源码)4Spring AI 项目实战(四…