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
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/84229.shtml
英文地址,請注明出處:http://en.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 項目實戰(四…