Linux:理解文件系統

1.理解硬件

1.1磁盤

  • 機械磁盤是計算機中的?個機械設備
  • 磁盤--- 外設
  • 容量?,價格便宜

1.2磁盤物理結構?

?

1.3磁盤的存儲結構?

扇區:是磁盤存儲數據的基本單位,512字節,塊設備?

?

如何定位?個扇區呢?
確定磁頭要訪問哪?個柱?(磁道)(cylinder)
可以先定位磁頭(header)
定位?個扇區(sector)
柱?(cylinder),磁頭(head),扇區(sector),顯然可以定位數據了,這就是數據定位(尋址)?式之?,CHS尋址?式。
扇區是從磁盤讀出和寫?信息的最?單位,通常??為 512 字節。
磁頭(head)數:每個盤??般有上下兩?,分別對應1個磁頭,共2個磁頭
磁道(track)數:磁道是從盤?外圈往內圈編號0磁道,1磁道...,靠近主軸的同?圓?于停靠磁頭,不存儲數據
柱?(cylinder)數:磁道構成柱?,數量上等同于磁道個數
扇區(sector)數:每個磁道都被切分成很多扇形區域,每道的扇區數量相同
圓盤(platter)數:就是盤?的數量
磁盤容量=磁頭數 × 磁道(柱?)數 × 每道扇區數 × 每扇區字節數
細節:傳動臂上的磁頭是共進退的

?1.4磁盤的邏輯結構

細節:傳動臂上的磁頭是共進退的

?

柱?是?個邏輯上的概念,其實就是每??上,相同半徑的磁道邏輯上構成柱?。
所以,磁盤物理上分了很多?,但是在我們看來,邏輯上,磁盤整體是由“柱?”卷起來的。

?

所以,磁盤的真實情況是:
磁道:
某?盤?的某?個磁道展開:
即:?維數組
柱面:
整個磁盤所有盤?的同?個磁道,即柱?展開:
?
柱?上的每個磁道,扇區個數是?樣的
這不就是?維數組嗎

整盤:?

整個磁盤不就是多張?維的扇區數組表(三維數組?)
所以,尋址?個扇區:先找到哪?個柱?(Cylinder) ,在確定柱?內哪?個磁道(其實就是磁頭位置,Head),在確定扇區(Sector),所以就有了CHS。
我們之前學過C/C++的數組,在我們看來,其實全部都是?維數組:

?

所以,每?個扇區都有?個下標,我們叫做LBA(Logical Block Address)地址,其實就是線性地址。所以怎么計算得到這個LBA地址呢?

?

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.引入文件系統

2.1引?"塊"概念?

其實硬盤是典型的“塊”設備,操作系統讀取硬盤數據的時候,其實是不會?個個扇區地讀取,這樣
效率太低,?是?次性連續讀取多個扇區,即?次性讀取?個”塊”(block)。
硬盤的每個分區是被劃分為?個個的”塊”。?個”塊”的??是由格式化的時候確定的,并且不可
以更改,最常?的是4KB,即連續?個扇區組成?個 ”塊”。”塊”是?件存取的最?單位。
注意:
  • 磁盤就是?個三維數組,我們把它看待成為?個"?維數組",數組下標就是LBA,每個元素都是扇
  • 每個扇區都有LBA,那么8個扇區?個塊,每?個塊的地址我們也能算出來。
  • 知道LBA:塊號 = LBA/8
  • 知道塊號:LBA=塊號*8 + n. (n是塊內第?個扇區)

?

2.2引?"分區"概念?

其實磁盤是可以被分成多個分區(partition)的,以Windows觀點來看,你可能會有?塊磁盤并且將它分區成C,D,E盤。那個C,D,E就是分區。分區從實質上說就是對硬盤的?種格式化。但是Linux的設備都是以?件形式存在,那是怎么分區的呢?

?

柱?是分區的最小單位,我們可以利?參考柱?號碼的?式來進?分區,其本質就是設置每個區的起始柱?和結束柱?號碼。 此時我們可以將硬盤上的柱?(分區)進?平鋪,將其想象成?個?的平?,如下圖所?:

?

2.3引?"inode"概念

之前我們說過 ?件 = 數據 + 屬性 ,我們使? ls -l 的時候看到的除了看到?件名,還能看到?件元
數據(屬性)。

?

[root@localhost linux]# ls -l
總?量 12
-rwxr-xr-x. 1 root root 7438 "9? 13 14:56" a.out
-rw-r--r--. 1 root root 654 "9? 13 14:56" test.c
每?包含7列:
? 模式
? 硬鏈接數
? ?件所有者
?
? ??
? 最后修改時間
? ?件名
ls -l讀取存儲在磁盤上的?件信息,然后顯?出來

其實這個信息除了通過這種?式來讀取,還有?個stat命令能夠看到更多信息?

[root@localhost linux]# stat test.c
File: "test.c"
Size: 654 Blocks: 8 IO Block: 4096 普通?件
Device: 802h/2050d Inode: 263715 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2017-09-13 14:56:57.059012947 +0800
Modify: 2017-09-13 14:56:40.067012944 +0800
Change: 2017-09-13 14:56:40.069012948 +0800

?到這我們要思考?個問題,?件數據都儲存在”塊”中,那么很顯然,我們還必須找到?個地?儲存 ?件的元信息(屬性信息),?如?件的創建者、?件的創建?期、?件的??等等。這種儲存文件元信息的區域就叫做inode,中?譯名為”索引節點”。

ls -li命令

?

每?個?件都有對應的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 */__u16 i_pad1;__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 */__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字節
任何?件的內容??可以不同,但是屬性???定是相同的

兩個問題:

1. 我們已經知道硬盤是典型的“塊”設備,操作系統讀取硬盤數據的時候,讀取的基本單位
是”塊”。“塊”?是硬盤的每個分區下的結構,難道“塊”是隨意的在分區上排布的嗎?那要怎
么找到“塊”呢?
2. 還有就是上?提到的存儲?件屬性的inode,?是如何放置的呢?
?件系統就是為了組織管理這些的!!

3.ext2 文件系統

3.1宏觀認識??

我們想要在硬盤上儲?件,必須先把硬盤格式化為某種格式的?件系統,才能存儲?件。?件系統的?的就是組織和管理硬盤中的?件。在Linux 系統中,最常?的是 ext2 系列的?件系統。其早期版本為 ext2,后來?發展出 ext3 和 ext4。ext3 和 ext4 雖然對 ext2 進?了增強,但是其核?設計并沒有發?變化,我們仍是以較?的 ext2 作為演?對象。
ext2?件系統將整個分區劃分成若?個同樣??的塊組 (Block Group),如下圖所?。只要能管理?個分區就能管理所有分區,也就能管理所有磁盤?件。

?

?

上圖中啟動塊(Boot Block/Sector)的??是確定的,為1KB,由PC標準規定,?來存儲磁盤分區信息和啟動信息,任何?件系統都不能修改啟動塊。啟動塊之后才是ext2?件系統的開始。

3.2Block Group

?ext2?件系統會根據分區的??劃分為數個Block Group。?每個Block Group都有著相同的結構組成。

3.3塊組內部構成

3.3.1超級塊(Super Block)?

存放?件系統本?的結構信息,描述整個分區的?件系統信息。記錄的信息主要有:bolck 和 inode的總量,未使?的block和inode的數量,?個block和inode的??,最近?次掛載的時間,最近?次寫?數據的時間,最近?次檢驗磁盤的時間等其他?件系統的相關信息。Super Block的信息被破壞,可以說整個?件系統結構就被破壞了
( 超級塊在每個塊組的開頭都有?份拷?(第?個塊組必須有,后?的塊組可以沒有)。 為了保證?件系統在磁盤部分扇區出現物理問題的情況下還能正常?作,就必須保證?件系統的super block信息在這種情況下也能正常訪問。所以?個?件系統的super block會在多個block group中進?備份,這些super block區域的數據保持?致。 )
/*
* Structure of the super block
*/
struct ext2_super_block {__le32 s_inodes_count; /* Inodes count */__le32 s_blocks_count; /* Blocks count */__le32 s_r_blocks_count; /* Reserved blocks count */__le32 s_free_blocks_count; /* Free blocks count */__le32 s_free_inodes_count; /* Free inodes count */__le32 s_first_data_block; /* First Data Block */__le32 s_log_block_size; /* Block size */__le32 s_log_frag_size; /* Fragment size */__le32 s_blocks_per_group; /* # Blocks per group */__le32 s_frags_per_group; /* # Fragments per group */__le32 s_inodes_per_group; /* # Inodes per group */__le32 s_mtime; /* Mount time */__le32 s_wtime; /* Write time */__le16 s_mnt_count; /* Mount count */__le16 s_max_mnt_count; /* Maximal mount count */__le16 s_magic; /* Magic signature */__le16 s_state; /* File system state */__le16 s_errors; /* Behaviour when detecting errors */__le16 s_minor_rev_level; /* minor revision level */__le32 s_lastcheck; /* time of last check */__le32 s_checkinterval; /* max. time between checks */__le32 s_creator_os; /* OS */__le32 s_rev_level; /* Revision level */__le16 s_def_resuid; /* Default uid for reserved blocks */__le16 s_def_resgid; /* Default gid for reserved blocks *//*
* These fields are for EXT2_DYNAMIC_REV superblocks only.
*
* Note: the difference between the compatible feature set and
* the incompatible feature set is that if there is a bit set
* in the incompatible feature set that the kernel doesn't
* know about, it should refuse to mount the filesystem.
*
* e2fsck's requirements are more strict; if it doesn't know
* about a feature in either the compatible or incompatible
* feature set, it must abort and not try to meddle with
* things it doesn't understand...
*/__le32 s_first_ino; /* First non-reserved inode */__le16 s_inode_size; /* size of inode structure */__le16 s_block_group_nr; /* block group # of this superblock */__le32 s_feature_compat; /* compatible feature set */__le32 s_feature_incompat; /* incompatible feature set */__le32 s_feature_ro_compat; /* readonly-compatible feature set */__u8 s_uuid[16]; /* 128-bit uuid for volume */char s_volume_name[16]; /* volume name */char s_last_mounted[64]; /* directory where last mounted */__le32 s_algorithm_usage_bitmap; /* For compression *//** Performance hints. Directory preallocation should only* happen if the EXT2_COMPAT_PREALLOC flag is on.*/__u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/__u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */__u16 s_padding1;/** Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.*/__u8 s_journal_uuid[16]; /* uuid of journal superblock */__u32 s_journal_inum; /* inode number of journal file */__u32 s_journal_dev; /* device number of journal file */__u32 s_last_orphan; /* start of list of inodes to delete */__u32 s_hash_seed[4]; /* HTREE hash seed */__u8 s_def_hash_version; /* Default hash version to use */__u8 s_reserved_char_pad;__u16 s_reserved_word_pad;__le32 s_default_mount_opts;__le32 s_first_meta_bg; /* First metablock block group */__u32 s_reserved[190]; /* Padding to the end of the block */
};

3.3.2GDT(Group Descriptor Table)

塊組描述符表,描述塊組屬性信息,整個分區分成多個塊組就對應有多少個塊組描述符。每個塊組描述符存儲?個塊組 的描述信息,如在這個塊組中從哪?開始是inode Table,從哪?開始是Data?Blocks,空閑的inode和數據塊還有多少個等等。塊組描述符在每個塊組的開頭都有?份拷?。
// 磁盤級blockgroup的數據結構
/*
* Structure of a blocks group descriptor
*/
struct ext2_group_desc
{__le32 bg_block_bitmap; /* Blocks bitmap block */__le32 bg_inode_bitmap; /* Inodes bitmap */__le32 bg_inode_table; /* Inodes table block*/__le16 bg_free_blocks_count; /* Free blocks count */__le16 bg_free_inodes_count; /* Free inodes count */__le16 bg_used_dirs_count; /* Directories count */__le16 bg_pad;__le32 bg_reserved[3];
};

3.3.3塊位圖(Block Bitmap)?

  • ??作用??:標記??數據塊(Data Block)??的使用狀態。
  • 原理??:
    • 每個比特(bit)對應一個數據塊:
      • 1:塊已被占用(存儲了文件數據)。
      • 0:塊空閑可用。
    • 例如:塊位圖?11100010?表示前3個塊已用,第4-6個塊空閑,第7個塊已用,第8個塊空閑。
  • ??示例??:
    • 若文件系統有 1024 個塊,塊位圖需占用?1024/8 = 128 字節(1字節=8比特)。

3.3.4inode位圖(Inode Bitmap)??

  • ??作用??:標記??Inode 的使用狀態??。
  • ??原理??:
    • 每個比特對應一個 Inode:
      • 1:Inode 已被占用(關聯了文件/目錄)。
      • 0:Inode 空閑。
    • 例如:Inode 位圖?10100000?表示第1、3個 Inode 已用,其余空閑。
  • ??示例??:
    • 若塊組包含 8192 個 Inode,Inode 位圖需占用?8192/8 = 1024 字節
特性塊位圖(Block Bitmap)Inode 位圖(Inode Bitmap)
??管理對象??數據塊(Data Blocks)Inode
??標記內容??數據塊是否被文件占用Inode 是否關聯文件/目錄
??大小計算??總塊數 ÷ 8(字節)總Inode數 ÷ 8(字節)
??分配策略??優先分配連續空閑塊分配第一個空閑 Inode

3.3.5i節點表(Inode Table)

  • 唯一標識文件??:每個區對應一個唯一的 Inode 編號(如?Inode 1053)。
  • ??存儲元數據??:包括權限、所有者、大小、時間戳等。
  • ??數據塊尋址??:通過指針(直接/間接)定位文件內容所在的磁盤塊。
  • 當前分組所有Inode屬性的集合
  • inode編號以分區為單位,整體劃分,不可跨分區
屬性說明
??物理位置??位于文件系統的 ??塊組(Block Group)?? 內,緊鄰 Inode Bitmap。
??存儲單元??多個 Inode 連續存儲,占用一個或多個磁盤塊(Block)。
??大小固定??EXT2/3 中每個 Inode 固定為 ??128字節??,EXT4 可擴展(如 256字節)。

示例計算??:

若磁盤塊大小為 4KB,一個塊可存儲?4096/128 = 32?個 Inode。

3.3.6Data Block?

數據區:存放?件內容,也就是?個?個的Block。根據不同的?件類型有以下?種情況:
  • 對于普通?件,?件的數據存儲在數據塊中。
  • 對于?錄,該?錄下的所有?件名和?錄名存儲在所在?錄的數據塊中,除了?件名外,ls -l命令看到的其它信息保存在該?件的inode中。
  • Block 號按照分區劃分,不可跨分區
屬性說明
??作用??存儲文件內容或目錄條目(文件名 + Inode編號映射)。
??大小??通常為 ??1KB、2KB、4KB??(EXT4默認4KB),格式化時確定,不可動態調整。
??分配單位??文件系統以塊為單位分配空間,即使文件只有1字節也占用整個塊。
??尋址方式??通過Inode的??直接/間接指針??定位數據塊。

Data Block?太大可以跨組保存?

?3.4inode和datablock映射

inode內部存在 __le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */ , EXT2_N_BLOCKS =15,就是?來進?inode和block映射的
這樣?件=內容+屬性,就都能找到了。

?

索引級別????管理能力??(假設塊大小=4KB,指針4字節)??圖中對應部分??
??直接塊??12×4KB = ??48KB??圖中左側"12個直接塊"區域
??一級間接??1024指針×4KB = ??4MB??"一級間接塊索引表指針"指向的表格
??二級間接??1024×1024×4KB = ??4GB??二級索引表的多層結構
??三級間接??10243×4KB = ??4TB??圖中最右側的三級指針鏈

?

知道inode號的情況下,在指定分區,請解釋:對?件進?增、刪、查、改是在做什么?
  • 分區之后的格式化操作,就是對分區進?分組,在每個分組中寫?SB、GDT、Block Bitmap、Inode Bitmap等管理信息,這些管理信息統稱: ?件系統
  • 只要知道?件的inode號,就能在指定分區中確定是哪?個分組,進?在哪?個分組確定 是哪?個inode
  • 拿到inode?件屬性和內容就全部都有了

?通過touch?個新?件來看看如何?作。

[root@localhost linux]# touch abc
[root@localhost linux]# ls -i abc
263466 abc

?為了說明問題,我們將上圖簡化:

?

創建?個新?件主要有以下4個操作:
1.存儲屬性
內核先找到?個空閑的i節點(這?是263466)。內核把?件信息記錄到其中。
2.存儲數據
該?件需要存儲在三個磁盤塊,內核找到了三個空閑塊:300,500,800。將內核緩沖區的第?塊數據復制到300,下?塊復制到500,以此類推。
3.記錄分配情況
?件內容按順序300,500,800存放。內核在inode上的磁盤分布區記錄了上述塊列表。

4.添加?件名到?錄

新的?件名abc。linux如何在當前的?錄中記錄這個?件?內核將??(263466,abc)添加到?錄?件。?件名和inode之間的對應關系將?件名和?件的內容及屬性連接起來。
abc → 263466 → 塊300/500/800
操作步驟圖片中的標注證據
??1. 分配Inode??i節點表中的263466條目
??2. 分配數據塊??數據區的塊300, 500, 800
??3. 記錄塊列表??文件所使用的數據塊列表:300,500,800
??4. 添加目錄項??增加到目錄的入口:(263466, abc)

?3.5?錄與?件名?

問題:
我們訪問?件,都是?的?件名,沒?過inode號啊?
?錄是?件嗎?如何理解?
答案:
?錄也是?件,但是磁盤上沒有?錄的概念,只有?件屬性+?件內容的概念。
?錄的屬性不?多說,內容保存的是:?件名和Inode號的映射關系

?

所以,訪問?件,必須打開當前?錄,根據?件名,獲得對應的inode號,然后進??件訪問
所以,訪問?件必須要知道當前?作?錄,本質是必須能打開當前?作?錄?件,查看?錄?件的
內容!

?

local@bite:~/code/test/test$ pwd
/home/local/code/test/test
local@bite:~/code/test/test$ ls -li
total 24
1596260 -rw-rw-r-- 1 local local 814 Oct 28 20:32 test.c
?如:要訪問test.c, 就必須打開test(當前?作?錄),然后才能獲取test.c對應的inode進?對?
件進?訪問。

3.6路徑解析

問題:打開當前?作?錄?件,查看當前?作?錄?件的內容?當前?作?錄不也是?件嗎?我們訪問當前?作?錄不也是只知道當前?作?錄的?件名嗎?要訪問它,不也得知道當前?作?錄的inode嗎?
答案1:所以也要打開:當前?作?錄的上級?錄,上級?錄不也是?錄嗎??不還是上?的問
題嗎?
答案2:所以類似"遞歸",需要把路徑中所有的?錄全部解析,出?是"/"根?錄。
最終答案3:?實際上,任何?件,都有路徑,訪問?標?件,?如:

?/home/local/code/test/test/test.c

都要從根?錄開始,依次打開每?個?錄,根據?錄名,依次訪問每個?錄下指定的?錄,直到訪問到test.c。這個過程叫做Linux路徑解析。

所以,我們知道了:訪問?件必須要有?錄+?件名=路徑的原因
根?錄固定?件名,inode號,?需查找,系統開機之后就必須知道
可是路徑誰提供?
? 你訪問?件,都是指令/?具訪問,本質是進程訪問,進程有CWD!進程提供路徑。
? 你open?件,提供了路徑
可是最開始的路徑從哪?來?
? 所以Linux為什么要有根?錄, 根?錄下為什么要有那么多缺省?錄?
? 你為什么要有家?錄,你??可以新建?錄?
? 上?所有?為:本質就是在磁盤?件系統中,新建?錄?件。?你新建的任何?件,都在你或者系統指定的?錄下新建,這不就是天然就有路徑了嘛!
? 系統+??共同構建Linux路徑結構.

3.7路徑緩存

問題1:Linux磁盤中,存在真正的?錄嗎?
答案:不存在,只有?件。只保存?件屬性+?件內容
問題2:訪問任何?件,都要從/?錄開始進?路徑解析?
答案:原則上是,但是這樣太慢,所以Linux會緩存歷史路徑結構
問題3:Linux?錄的概念,怎么產?的?
答案:打開的?件是?錄的話,由OS??在內存中進?路徑維護

?

Linux中,在內核中維護樹狀路徑結構的內核結構體叫做: struct dentry?

struct dentry {atomic_t d_count;unsigned int d_flags; /* protected by d_lock */spinlock_t d_lock; /* per dentry lock */struct inode* d_inode; /* Where the name belongs to - NULL is* negative *//** The next three fields are touched by __d_lookup. Place them here* so they all fit in a cache line.*/struct hlist_node d_hash; /* lookup hash list */struct dentry* d_parent; /* parent directory */struct qstr d_name;struct list_head d_lru; /* LRU list *//** d_child and d_rcu can share memory*/union {struct list_head d_child; /* child of parent list */struct rcu_head d_rcu;} d_u;struct list_head d_subdirs; /* our children */struct list_head d_alias; /* inode alias list */unsigned long d_time; /* used by d_revalidate */struct dentry_operations* d_op;struct super_block* d_sb; /* The root of the dentry tree */void* d_fsdata; /* fs-specific data */
#ifdef CONFIG_PROFILINGstruct dcookie_struct* d_cookie; /* cookie, if any */
#endifint d_mounted;unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
};

?dentry找到了,inode就找到了?

注意:
? 每個?件其實都要有對應的dentry結構,包括普通?件。這樣所有被打開的?件,就可以在內存中形成整個樹形結構
? 整個樹形節點也同時會?屬于LRU(Least Recently Used,最近最少使?)結構中,進?節點淘汰 ? 整個樹形節點也同時會?屬于Hash,?便快速查找
? 更重要的是,這個樹形結構,整體構成了Linux的路徑緩存結構,打開訪問任何?件,都在先在這
棵樹下根據路徑進?查找,找到就返回屬性inode和內容,沒找到就從磁盤加載路徑,添加dentry
結構,緩存新路徑

操作????無緩存????有緩存??
??首次訪問?/path/abc??需讀取圖中所有目錄塊和Inode表。僅第一次需訪問磁盤。
??重復訪問??每次重復解析路徑。直接從緩存返回Inode,零磁盤I/O。
??刪除/重命名文件??需同步更新緩存和圖中磁盤結構。緩存失效,觸發重新解析。

3.8掛載分區

我們已經能夠根據inode號在指定分區找?件了,也已經能根據?錄?件內容,找指定的inode了,在指定的分區內,我們可以為所欲為了。可是:

問題:inode不是不能跨分區嗎?Linux不是可以有多個分區嗎?我怎么知道我在哪?個分區???

?3.8.1?個實驗

$ dd if=/dev/zero of=./disk.img bs=1M count=5 #制作?個?的磁盤塊,就當做?個分區#創建5MB的空白鏡像#通過dd命令創建的disk.img就是典型的??磁盤鏡像文件??
$ mkfs.ext4 disk.img # 格式化寫??件系統
$ mkdir /mnt/mydisk # 建?空?錄
$ df -h # 查看可以使?的分區
Filesystem Size Used Avail Use% Mounted on
udev 956M 0 956M 0% /dev
tmpfs 198M 724K 197M 1% /run
/dev/vda1 50G 20G 28G 42% /
tmpfs 986M 0 986M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 986M 0 986M 0% /sys/fs/cgroup
tmpfs 198M 0 198M 0% /run/user/0
tmpfs 198M 0 198M 0% /run/user/1002
$ sudo mount -t ext4 ./disk.img /mnt/mydisk/ # 將分區掛載到指定的?錄$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 956M 0 956M 0% /dev
tmpfs 198M 724K 197M 1% /run
/dev/vda1 50G 20G 28G 42% /
tmpfs 986M 0 986M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 986M 0 986M 0% /sys/fs/cgroup
tmpfs 198M 0 198M 0% /run/user/0
tmpfs 198M 0 198M 0% /run/user/1002
/dev/loop0 4.9M 24K 4.5M 1% /mnt/mydisk$ sudo umount /mnt/mydisk # 卸載分區
local@bite:/mnt$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 956M 0 956M 0% /dev
tmpfs 198M 724K 197M 1% /run
/dev/vda1 50G 20G 28G 42% /
tmpfs 986M 0 986M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 986M 0 986M 0% /sys/fs/cgroup
tmpfs 198M 0 198M 0% /run/user/0
tmpfs 198M 0 198M 0% /run/user/1002

?注意:

/dev/loop0 在Linux系統中代表第?個循環設備(loop device)。循環設備,也被稱為
回環設備或者loopback設備,是?種偽設備(pseudo-device),它允許將?件作為塊設備
(block device)來使?。這種機制使得可以將?件(?如ISO鏡像?件)掛載(mount)為
?件系統,就像它們是物理硬盤分區或者外部存儲設備?樣
最多可以同時掛載8個不同的磁盤鏡像文件??(每個鏡像需要獨占一個loop設備)
local@bite:/mnt$ ls /dev/loop* -l
brw-rw---- 1 root disk 7, 0 Oct 17 18:24 /dev/loop0
brw-rw---- 1 root disk 7, 1 Jul 17 10:26 /dev/loop1
brw-rw---- 1 root disk 7, 2 Jul 17 10:26 /dev/loop2
brw-rw---- 1 root disk 7, 3 Jul 17 10:26 /dev/loop3
brw-rw---- 1 root disk 7, 4 Jul 17 10:26 /dev/loop4
brw-rw---- 1 root disk 7, 5 Jul 17 10:26 /dev/loop5
brw-rw---- 1 root disk 7, 6 Jul 17 10:26 /dev/loop6
brw-rw---- 1 root disk 7, 7 Jul 17 10:26 /dev/loop7
crw-rw---- 1 root disk 10, 237 Jul 17 10:26 /dev/loop-control

?df?命令(最直接)快速判斷當前所在分區

.?表示當前目錄??,輸出顯示其所在設備(如?/dev/vda1)和掛載點(/home)。?

$ df -h .
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        50G   20G   28G  42% /home

?

3.8.2一個結論

分區寫??件系統,?法直接使?,需要和指定的?錄關聯,進?掛載才能使?。
所以,可以根據訪問?標?件的"路徑前綴"準確判斷我在哪?個分區。

?4.軟硬鏈接

4.1硬鏈接?

??基本概念??

  • ??硬鏈接?? 是文件系統中??指向同一個 inode 的多個文件名??,即多個路徑指向同一份數據。
  • 所有硬鏈接??地位平等??,沒有“原始文件”和“鏈接文件”之分。
  • 刪除任意一個硬鏈接,只要還有其他鏈接存在,文件數據就不會被釋放。

特點?

??1.共享 inode??

  • 所有硬鏈接指向同一個 inode,因此:
    • 修改任一硬鏈接的內容,其他硬鏈接也會同步變化。
    • 它們的文件屬性(權限、所有者、時間戳等)完全相同。

2.不跨文件系統??

  • 硬鏈接必須在??同一個文件系統??內創建(因為 inode 是文件系統局部的)。

3.不能鏈接目錄??(超級用戶除外)

  • 普通用戶無法用?ln?創建目錄的硬鏈接,防止形成循環引用(但內核允許?.?和?..?這樣的特殊硬鏈接)。

4.??刪除不影響數據??

  • 只有當??所有硬鏈接都被刪除??,且沒有進程占用文件時,數據才會真正釋放。

?創建硬鏈接?

ln 源文件 硬鏈接名
ln file.txt hardlink_to_file.txt

此時?file.txt?和?hardlink_to_file.txt?指向同一個 inode,修改其中一個會影響另一個。

查看硬鏈接??

ls -i?? 查看 inode 號(相同 inode 表示是硬鏈接):?

ls -i file.txt hardlink_to_file.txt
//輸出示例:
123456 file.txt
123456 hardlink_to_file.txt  # inode 相同

?

263563 - rw - r--r--. 2 root root 0 9? 15 17:45 abc
263563 - rw - r--r--. 2 root root 0 9? 15 17:45 abc-hard//2是多個新的文件名指向目標文件,硬連接數//增加inode引用計數的數字  

?創建目錄后發現是2,是因為目錄里.也是硬鏈接

目錄里..是3是因為上級目錄和上級目錄里的.和當前目錄里的..是同一inode

?4.2軟鏈接

基本概念??

軟鏈接(Symbolic Link,又稱符號鏈接)是 Linux/Unix 系統中的一種特殊文件類型,它??存儲的是另一個文件或目錄的路徑??,類似于 Windows 的“快捷方式”。

創建軟鏈接??

ln -s 目標文件或目錄 軟鏈接名稱
ln -s /var/log/syslog my_log_link  # 創建指向系統日志的軟鏈接

?此時?my_log_link?是一個獨立文件,內容為路徑?/var/log/syslog

識別軟鏈接??

ls -l?? 顯示軟鏈接及其指向的目標:?

ls -l my_log_link
//輸出示例:
lrwxrwxrwx 1 user group 13 Jan 1 12:00 my_log_link -> /var/log/syslog
//首字母 l 表示軟鏈接。
//-> 后是目標路徑。

?

gcc myapp.c -o /.../myapp  # 編譯并輸出到目標路徑
ln -s /.../myapp exe  # 創建軟鏈接 exe

現在目錄下有一個名為?exe?的軟鏈接,指向?/.../myapp

直接運行?exe

./exe??

  1. Shell 會先解析?./exe?的路徑:
    • ?./?表示當前目錄,所以 Shell 查找當前目錄下的?exe
  2. 發現?exe?是一個軟鏈接,指向?/.../myapp
  3. Shell 最終執行?/.../myapp

4.3軟硬連接對?

軟連接是獨??件
硬鏈接只是?件名和?標?件inode的映射關系

?

4.4軟硬連接的?途:?

硬鏈接
. .. 就是硬鏈接
?件備份
軟連接
類似快捷?式

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/83167.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83167.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83167.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

用 openssl 測試 tls 連接

以 baidu 為例,命令行為: openssl s_client -tlsextdebug -connect baidu.com:443 得到的輸出為: CONNECTED(00000003) TLS server extension "renegotiation info" (id65281), len1 0000 - 00 …

今日行情明日機會——20250515

上證指數縮量收陰線,個股跌多漲少,上漲波段4月9日以來已有24個交易日,時間周期上處于上漲末端,注意風險。 深證指數縮量收陰線,日線上漲結束的概率在增大,注意風險。 2025年5月15日漲停股主要行業方向分…

Axure RP9:列表新增

文章目錄 列表新增思路新增按鈕操作說明保存新增交互設置列表新增 思路 利用中繼器新增行實現列表新增功能 新增按鈕操作說明 工具欄中添加新增圖標及標簽,在圖標標簽基礎上添加熱區;對熱區添加鼠標單擊時交互事件,同步插入如下動作:顯示/隱藏動作,設置目標元件為新增窗…

ArcGIS Pro調用多期歷史影像

一、訪問World Imagery Wayback,基本在我國范圍 如下圖: 二、 放大到您感興趣的區域 三、 查看影像版本信息 點擊第二步的按鈕后,便可跳轉至World Imagery (Wayback 2025-04-24)的相關信息。 四 、點擊上圖影像版本信息,頁面跳轉…

提高成功率!課題中的立項依據深度寫作

1. 戰略定位:在宏觀愿景中界定課題坐標 立項依據的第一重任務,是回答“為什么要做”——但這一問并非局限于學術好奇,而要升維到國家戰略、行業痛點與學科前沿的交匯點。教師在申報時,應先掃描上位政策(如國家中長期科…

【FileZilla】Client端的線程模型 (一)

CMainFrame構造---》CFileZillaEngineContex構造--》引起其成員變量lmpl構造--》引起fz::event_loop的構造,其中創建了兩個線程(指針) task_和 timer_task_。 // In event_loop.cpp event_loop::event_loop(thread_pool & pool): sync_(false) {task_ std::ma…

什么是Agentic AI(代理型人工智能)?

什么是Agentic AI(代理型人工智能)? 一、概述 Agentic AI(代理型人工智能)是一類具備自主決策、目標導向性與持續行動能力的人工智能系統。與傳統AI系統依賴外部輸入和顯式命令不同,Agentic AI在設定目標…

Windows平臺OpenManus部署及WebUI遠程訪問實現

前言:繼DeepSeek引發行業震動后,Monica.im團隊最新推出的Manus AI 產品正席卷科技圈。這款具備自主思維能力的全能型AI代理,不僅能精準解析復雜指令并直接產出成果,更顛覆了傳統人機交互模式。盡管目前仍處于封閉測試階段&#xf…

Springboot3自定義starter筆記

場景&#xff1a;抽取聊天機器人場景&#xff0c;它可以打招呼。 效果&#xff1a;任何項目導入此 starter 都具有打招呼功能&#xff0c;并且問候語中的人名需要可以在配置文件中修改。 創建自定義 starter 項目&#xff0c;引入 spring-boot-starter 基礎依賴。 <dependen…

Nginx與Tomcat負載均衡集群配置指南

目錄 一、資源清單 二、基礎環境 三、安裝配置Tomcat 四、安裝配置Nginx 一、資源清單 主機 操作系統 IP地址 tomcat1 OpenEuler24.03 192.168.16.142 tomcat2 OpenEuler24.03 192.168.16.143 Nginx OpenEuler24.03 192.168.16.144 二、基礎環境 hostnamectl …

【數據處理】xarray 數據處理教程:從入門到精通

目錄 xarray 數據處理教程&#xff1a;從入門到精通一、簡介**核心優勢** 二、安裝與導入1. 安裝2. 導入庫 三、數據結構&#xff08;一&#xff09;DataArray&#xff08;二&#xff09; Dataset&#xff08;三&#xff09;關鍵說明 四、數據操作&#xff08;一&#xff09;索…

網站漏洞存在哪些危害,該如何做好預防?

網站漏洞的危害及預防措施 一、網站漏洞的主要危害 網站漏洞是攻擊者利用系統、應用或配置中的缺陷&#xff0c;實施惡意行為的入口。其危害包括但不限于以下方面&#xff1a; 數據泄露與隱私侵犯 危害&#xff1a;攻擊者通過SQL注入、XSS等漏洞竊取用戶數據&#xff08;如密…

WEB攻防-PHP漏洞解析

Web攻防之PHP漏洞解析 目錄結構 引言 1.1 PHP在CTF Web方向的核心地位1.2 報告目標與結構說明1.3 PHP安全研究的方法論代碼執行漏洞 2.1 漏洞原理與歷史演進2.2 危險函數全解析與利用鏈2.3 繞過過濾的20種高級技巧2.4 實戰案例&#xff1a;從CVE到CTF賽題復現2.5 防御方案與安…

YOLO11解決方案之距離計算探索

概述 Ultralytics提供了一系列的解決方案&#xff0c;利用YOLO11解決現實世界的問題&#xff0c;包括物體計數、模糊處理、熱力圖、安防系統、速度估計、物體追蹤等多個方面的應用。 測量兩個物體之間的間距被稱為特定空間內的距離計算&#xff0c;YOLO11使用兩個邊界框的中心…

mongodb處理時區轉換問題

1. 程序查詢直接使用&#xff08;java&#xff09;Date即可, 因為直接支持 2. 若方便查看日期需要進行格式和時區轉換 db.task.aggregate([{ $match: {userId: 113633}},{ $project: {userId: 1,endTime: 1,formattedDate: {$dateToString: {format: "%Y-%m-%d %H:%M:%S&…

基于中心點預測的視覺評估與可視化流程

基于中心點預測的視覺評估與可視化流程 基于中心點預測的視覺評估與可視化流程一、腳本功能概覽二、可視化與評分機制詳解1. 真實框解析2. 調用模型處理幀3. 預測中心點與真實值的對比4. 打分策略5. 圖像可視化三、目錄結構要求四、運行方式五、應用場景與拓展思路六、總結七,…

Comparator 比較器

在Java中&#xff0c;Comparator.comparingInt(String::length) 是一個用于創建比較器&#xff08;Comparator&#xff09;的靜態方法調用&#xff0c;它的核心作用是定義一個比較規則&#xff0c;使對象按照特定屬性&#xff08;這里是字符串長度&#xff09;進行比較。下面從…

無人設備遙控器之無線通訊技術篇

無人設備遙控器的無線通訊技術是確保遙控操作準確、穩定、高效進行的關鍵。以下是對無人設備遙控器無線通訊技術的詳細解析&#xff1a; 一、主要無線通訊技術類型 Wi-Fi通訊技術 原理&#xff1a;基于IEEE 802.11標準&#xff0c;通過無線接入點&#xff08;AP&#xff09;…

Android Coli 3 ImageView load two suit Bitmap thumb and formal,Kotlin(七)

Android Coli 3 ImageView load two suit Bitmap thumb and formal&#xff0c;Kotlin&#xff08;七&#xff09; 在 Android Coli 3 ImageView load two suit Bitmap thumb and formal&#xff0c;Kotlin&#xff08;六&#xff09;-CSDN博客 的基礎上改進&#xff0c;主要是…

ET EntityRef EntityWeakRef 類分析

EntityRef EntityWeakRef 相同點 也是這兩個的作用&#xff1a;這兩個都是用來表示一個實體引用。一般來說使用一個對象&#xff0c;直接持有對象就可以&#xff0c;但是如果對象來自于對象池&#xff0c;這個時候直接持有對象不合適&#xff0c;對象可能已經被對象池回收&…