Linux系统——文件(上)

💁‍♂️个人主页:进击的荆棘

👇作者其它专栏:

《数据结构与算法》《算法》《C++起始之路》《Linux》


目录

1.理解硬件

2.引入文件系统

3.ext2文件系统

4.软硬连接


1.理解硬件

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

●机械磁盘是计算机中唯一的一个机械设备

●磁盘------外设

●慢

●容量大,价格便宜

1.2磁盘物理结构

1.3磁盘的存储结构

扇区:是磁盘存储数据的基本单位,512字节,块设备

如何定义一个扇区?

●可以先定位磁头(header)

●确定磁头要访问哪一个柱面(磁道)(cylinder)

●定位一个扇区(sector)

●CHS地址定位

文件=内容+属性,都是数据,本质是占据几个扇区的问题。能定位一个扇区,能不能定位多个扇区?

●扇区是从磁盘读出和写入信息的最小单位,通常大小为512字节

●磁头(head)数:每个盘片上一般有上下两面,分别对应1个磁头,共2个磁头

●磁道(track)数:磁道是从盘片外圈往内圈编号0磁道,1磁道......,靠近主轴的同心圆用于停靠磁头,不存储数据

●柱面(cylinder)数:磁道构成柱面,数量上等同磁道个数

●扇区(sector)数:每个磁道都被切分为很多扇形区域,每道的扇区数量相同

●圆盘(platter)数:盘片的数量

●磁盘容量=磁头数 X 磁道(柱面)数 X 每道扇区数 X 每扇区字节数

●细节:传动臂上的磁头是共进退的

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

CHS寻址

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

1.4磁盘的逻辑结构

1.4.1理解过程

磁带上面可以存储数据,我们可以把磁带"拉直",形成线性结构

磁盘本质上虽然是硬质的,但是逻辑上可以把磁盘想象为卷在一起的磁带,那么磁盘的逻辑存储结构就类似为:

这样每个扇区就有了一个线性地址(其实就是数组下标),这种地址叫做LBA(Logical Block Address)

1.4.2真实过程

传动臂上的磁盘是共进退的

柱面是一个逻辑上的概念,其实就是每一面上,相同半径的磁道逻辑上构成柱面

所以,磁盘逻辑上分了很多面,但是在我们看来,逻辑上,磁盘整体是由"柱面"卷起来的

所以,磁盘的真实情况是:

磁道:

某个盘面的某一个磁道展开:

即:一维数组

柱面:

正磁盘所有盘面的同一个磁道,即柱面展开:

●柱面上的每个磁盘,扇区个数是一样的

●就像二维数组

整盘:

整个磁盘就是多张二维的扇区数组表(三维数组)

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

因此,在我们看来,其实全部都是一维数组:

所以,每一个扇区都有一个下标,被称为LBA(Logical Block Address)地址,其实就是线性地址。如何得到这个LBA地址?

OS只需要使用LBA就可以了。LBA可以转成CHS地址,CHS可以转成LBA地址。这不需要用户,磁盘自己就可以做。

1.5CHS&&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.引入文件系统

2.1引入"块"概念

其实硬盘是典型的"块"设备,操作系统读取硬盘数据的时候,其实是不会一个一个扇区读取的,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。

硬盘的每个分区是被划分为一个个的"块"。一个"块"的大小是由格式化的时候确定的,并且不可更改,最常见的是4KB,即**连续8个扇区组成一个"块"。"**块"是文件存取的最小单位。

注意:

●磁盘就是一个三维数组,而我们把它看成一个"一维数组",数组下标就是LBA,每个元素都是扇区

●每个扇区都有LBA,那么8个扇区一个块,每一个块的地址也能算出来

●知道LBA:块号=LBA/8

●知道块号:LBA=块号*8+n(n是块内第几个扇区)

2.2引入"分区"概念

其实磁盘是可以被分成多个分区(partition)的,以Windows观点来看,一块磁盘可能被分区为C,D,E盘。C,D,E就是分区。分区从实质上说就是对硬盘的一种格式化。但是Linux的设备都是以文件形式存在,又该如何区分?

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

注:

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

2.3引入"inode"概念

文件=数据+属性,使用ls -l的时候除了能看到文件名,还能看到文件元数据(属性)

复制代码
[sjx@VM-0-6-centos ~]$ ls -l
total 12
-rw-rw-r--  1 sjx sjx  827 Jul 20 18:04 install.sh
drwxrwxr-x 12 sjx sjx 4096 Sep 17 22:00 linux
-rw-rw-r--  1 sjx sjx  625 Sep 10 20:18 Makefile

每行包含7列:

●模式

●硬链接数

●文件所有者

●组

●大小

●最后修改时间

●文件名

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

这个信息除了通过这种方式来读取,还可以使用stat命令看到更多信息

复制代码
[sjx@VM-0-6-centos ~]$ stat Makefile
  File: 'Makefile'
  Size: 625       	Blocks: 8          IO Block: 4096   regular file
Device: fd01h/64769d	Inode: 658165      Links: 1
Access: (0664/-rw-rw-r--)  Uid: ( 1001/     sjx)   Gid: ( 1001/     sjx)
Access: 2026-09-13 21:08:03.034928673 +0800
Modify: 2026-09-10 20:18:12.216482861 +0800
Change: 2026-09-10 20:18:12.216482861 +0800
 Birth: -

此时还要思考一个问题,文件数据都存储在"块"中,所以我们还需要找到一个地方存储文件的元信息(属性信息),如文件的创建者、文件创建日期、文件大小等。这种存储文件元信息的区域叫做inode,也称"索引节点"。

每个文件都有对应的inode,里面包含了与文件有关的信息。

注:

●Linux下文件的存储是属性和内容分离存储的

●Linux下,保存文件属性的集合叫做inode,一个文件对应一个inode,inode内有一个唯一的标识符,叫做inode号

以下为一个文件的属性inode

复制代码
/*
* Structure of an inode on the disk
*/
struct ext2_inode {
    __le16 i_mode; /* File mode */
    __le16 i_uid; /* Low 16 bits of Owner Uid */
    __le32 i_size; /* Size in bytes */
    __le32 i_atime; /* Access time */
    __le32 i_ctime; /* Creation time */
    __le32 i_mtime; /* Modification time */
    __le32 i_dtime; /* Deletion Time */
    __le16 i_gid; /* Low 16 bits of Group Id */
    __le16 i_links_count; /* Links count */
    __le32 i_blocks; /* Blocks count */
    __le32 i_flags; /* File flags */
    union {
        struct {
            __le32 l_i_reserved1;
        } linux1;
        struct {
            __le32 h_i_translator;
        } hurd1;
        struct {
            __le32 m_i_reserved1;
        } masix1;
    } osd1; /* OS dependent 1 */
    __le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
    __le32 i_generation; /* File version (for NFS) */
    __le32 i_file_acl; /* File ACL */
    __le32 i_dir_acl; /* Directory ACL */
    __le32 i_faddr; /* Fragment address */
    union {
        struct {
            __u8 l_i_frag; /* Fragment number */
            __u8 l_i_fsize; /* Fragment size */
            _le16 l_i_uid_high; /* these 2 fields */
            __le16 l_i_gid_high; /* were reserved2[0] */
            __u32 l_i_reserved2;
        } linux2;
        struct {
            __u8 h_i_frag; /* Fragment number */
            __u8 h_i_fsize; /* Fragment size */
            __u16 i_pad1;
            __le16 h_i_mode_high;
            __le16 h_i_uid_high;
            __le16 h_i_gid_high;
            __le32 h_i_author;
        } hurd2;
        struct {
            __u8 m_i_frag; /* Fragment number */
            __u8 m_i_fsize; /* Fragment size */
            __u16 m_pad1;
            __u32 m_i_reserved2[2];
        } masix2;
    } osd2; /* OS dependent 2 */
};
/*
* Constants relative to the data blocks
*/
#define EXT2_NDIR_BLOCKS 12
#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)

备注:EXT2_N_BLOCKS = 15

注:

●文件名属性并未纳入道inode数据结构内部

●inode的大小一般为128字节或256

●任何文件的内容大小可以不同,但属性大小一定是相同的(128)

3.ext2文件系统

3.1宏观认识

**想要在硬盘上存储文件,必须先把硬盘格式化为某种格式的文件系统,才能存储文件。文件系统的目的就是组织和管理硬盘中的文件。**在Linux系统中,最常见的是ext2系列的文件系统。其早期版本为ext2,后来发展除ext3和ext4.ext3和ext4虽然对ext2进行了增强,但是其核心设计并没有改变。

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

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

3.2Block Group

ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有相同的结构组成。

相关推荐
k4m7v2pz2 小时前
ThinkPad E490 风扇 “转两秒就停“ 实录:迟滞曲线 + 最短运转时间
linux·脚本·archlinux·thinkpad·风扇·散热
拂拉氏2 小时前
【知识讲解】 Linux文件系统底层认识
linux·文件系统
承渊政道2 小时前
星空组网排查指南:从设备在线到服务可用的五步检查
运维·星空组网·排查指南
IT大白鼠2 小时前
彭大帅的AI运维助手——自然语言管理 Linux 集群与网络设备——第 1 篇 · 骨架:说人话,跑命令:自然语言 SSH 运维的骨架
linux·运维·人工智能
檀越剑指大厂3 小时前
抽屉里的手机还能开博客?用 Typecho 和 cpolar 搭一台可远程访问的小服务器
运维·服务器·智能手机
牢姐与蒯3 小时前
Linux信号(一).信号产生
linux·运维·服务器·ubuntu
FfHUCisI3 小时前
sync.Once 与 sync.Cond 源码与并发控制陷阱
服务器·开发语言·后端·golang
j7~3 小时前
【Python】(篇六)《基础语法(函数、列表和元组、字典、文件)》---详解
开发语言·python·文件·函数·字典·编程学习·元组与列表
爱签AI电子合同4 小时前
电子合同上手成本怎么测?易用性维度专项测评
服务器·人工智能·智能合约·企业微信