1. 程式人生 > >Linux檔案系統程式碼學習筆記--磁碟格式化&block分配

Linux檔案系統程式碼學習筆記--磁碟格式化&block分配

第一部分——準備知識

磁碟格式化這一步驟到底做了什麼?
為了讀懂程式碼,首先先掌握幾個知識點。

memcpy函式

void *  __cdecl memcpy(_Out_writes_bytes_all_(_Size) void * _Dst, _In_reads_bytes_(_Size) const void * _Src, _In_ size_t _Size);
void *memcpy(void *memTo, const void *memFrom, size_t size)
{
  if((memTo == NULL) || (memFrom == NULL)) //memTo和memFrom必須有效
return NULL;   char *tempFrom = (char *)memFrom; //儲存memFrom首地址   char *tempTo = (char *)memTo; //儲存memTo首地址   while(size -- > 0) //迴圈size次,複製memFrom的值到memTo中   *tempTo++ = *tempFrom++ ;   return memTo; }
struct direct{
    char d_name[DIRSIZ];//目錄名
unsigned int d_ino;//磁碟 i節點識別符號id }; strcpy(dir_buf[0].d_name,"..");//父目錄 dir_buf[0].d_ino = 1; strcpy(dir_buf[1].d_name,".");//當前目錄root dir_buf[1].d_ino = 1; strcpy(dir_buf[2].d_name,"etc");//子目錄etc目錄 dir_buf[2].d_ino = 2; memcpy(disk+DATASTART, &dir_buf, 3*(DIRSIZ+4));//dir_buf中的前3個元素拷貝到磁碟資料區的第1個數據塊

這裡寫圖片描述
dir_buf是一個direct結構體,目錄名是12個位元組,int是4個位元組,一共16個位元組,拷貝到char中的連續的16個元素中,char一個元素就是一個位元組。

memset函式

void *  __cdecl memset(_Out_writes_bytes_all_(_Size) void * _Dst, _In_ int _Val, _In_ size_t _Size);
memset(disk, 0x00, ((DINODEBLK+FILEBLK+2)*BLOCKSIZ));

把_Dst所指記憶體區域的前_Size個位元組設定成字元 _Val。

軟連結和硬連結

  1. 格式化將分割槽分成等大小的資料塊block。
  2. 使用者想要去找一個叫sb的檔案,先去找inode,從inode得知sb存在哪些資料塊。
  3. 硬連結
    假設建立了sb的硬連結檔案叫做bs,bs和sb擁有相同的inode的id號,inode相同,儲存的資料塊也就相同。sb和bs相當於同一個檔案,只不過叫不同的名字。一間教室的前門和後門。如果刪除任何一個,通過另一個也能訪問儲存空間,可以理解成同一個儲存空間的不同入口。
    不能跨分割槽使用,sb和bs需要在同一個分割槽。
    不能針對目錄使用。

這裡寫圖片描述

  1. 軟連結
    假設為csb,有自己的inode和資料塊,使用者訪問csb,先找到csb自己的inode結點,然後找到自己的資料塊,在找到原檔案的inode,再找到原檔案的資料塊。
    修改原檔案,軟連結也變,因為原始資料塊變了。
    修改軟連結,最終也是修改原檔案的資料塊,原檔案也被修改了。
    刪除原檔案,軟連結不能打開了。
    刪除原檔案,硬連結還可以開啟。
    這裡寫圖片描述

第二部分——程式碼解讀

inode解讀

目錄項=檔名+磁碟結點標號
這裡寫圖片描述

檔案系統儲存結構
這裡寫圖片描述

格式化是要將磁碟分成等大小的資料塊,確定inode的數量和資料塊的數量,並做一些初始的寫入工作,比如建立根目錄和一些必要的目錄等等。

    ls -i 檢視檔案的inode結點

0. 整個磁碟被劃分為等大小的塊,稱為物理塊,引導塊佔第0個物理塊,超級塊佔用第1個物理塊,inode結點表佔用接下來的物理塊,資料塊佔用剩下的物理塊。這裡要注意一點,inode結點表是由多個inode結點組成的,inode大小一般小於一個物理塊的大小,因此一個物理塊可能存放多個inode結點。
1. 一個inode對應一個檔案。inode存放的是檔案資訊,不是檔案內容,資料塊存放檔案內容。 Linux一切皆檔案,目錄和裝置都是檔案。當檔案是目錄時,檔案內容就是目錄下的檔案的資訊,當檔案是資料檔案時,檔案內容就是資料。
2.inode中不包含檔案的名字,當用戶要查詢一個檔案時,通過檔名
先查詢目錄項,找到檔案資訊所在的inode結點,在inode中找到檔案的物理塊號。
3. 一個inode可以儲存多個物理塊號(資料塊號),因為一個檔案可能存放在多個物理塊。
4. 磁碟inode和記憶體inode
磁碟inode在檔案建立時就已經建立,存放在磁碟上,記憶體inode 在檔案被開啟時才建立,存放在記憶體中。

format.cpp——格式化

//初始化硬碟
    memset(disk, 0x00, ((DINODEBLK+FILEBLK+2)*BLOCKSIZ));//disk陣列初始化,全為0
    /* 0.initialize the passwd */
    passwd[0].p_uid = 2116;//0使用者uid=2116
    passwd[0].p_gid = 03;//0使用者所屬組gid=03
    strcpy(passwd[0].password, "dddd");//0使用者密碼為dddd

    passwd[1].p_uid = 2117;//1使用者uid=2117
    passwd[1].p_gid = 03;//1使用者所屬組gid=03
    strcpy(passwd[1].password, "bbbb");//1使用者密碼為bbbb

    passwd[2].p_uid = 2118;//2使用者uid
    passwd[2].p_gid = 04;//2使用者所屬組
    strcpy(passwd[2].password, "abcd"); //2使用者密碼 

    passwd[3].p_uid = 2119;//3使用者
    passwd[3].p_gid = 04;
    strcpy(passwd[3].password, "cccc");

    passwd[4].p_uid = 2120;//4使用者
    passwd[4].p_gid = 05;
    strcpy(passwd[4].password, "eeee");

    /* 1.creat the main directory and its sub dir etc and the file password */

    inode = iget(0);   /* 0 empty dinode id*/
    inode->di_number = 1;//關聯檔案數設為1         
    inode->di_mode = DIEMPTY;//許可權設為空許可權
    iput(inode);//回收inode結點

    inode = iget(1);   /* 1 main dir id*/
    inode->di_number = 1;
    inode->di_mode = DEFAULTMODE | DIDIR;
    inode->di_size = 3*(DIRSIZ + 4);
    inode->di_addr[0] = 0; /*block 0# is used by the main directory*/

    strcpy(dir_buf[0].d_name,"..");//父目錄
    dir_buf[0].d_ino = 1;//磁碟inode結點標號為1
    strcpy(dir_buf[1].d_name,".");//根目錄
    dir_buf[1].d_ino = 1;
    strcpy(dir_buf[2].d_name,"etc");//子目錄etc目錄
    dir_buf[2].d_ino = 2;

    memcpy(disk+DATASTART, &dir_buf, 3*(DIRSIZ+4));//dir_buf中的前3個元素拷貝到磁碟資料區的第1個數據塊
    iput(inode);

    inode = iget(2);  /* 2  etc dir id */
    inode->di_number = 1;
    inode->di_mode = DEFAULTMODE | DIDIR;
    inode->di_size = 3*(DIRSIZ + 4);
    inode->di_addr[0] = 1; /*block 1# is used by the etc directory*/

    strcpy(dir_buf[0].d_name,"..");
    dir_buf[0].d_ino = 1;
    strcpy(dir_buf[1].d_name,".");
    dir_buf[1].d_ino = 2;//etc
    strcpy(dir_buf[2].d_name,"password");//子目錄是password
    dir_buf[2].d_ino = 3;

    memcpy(disk+DATASTART+BLOCKSIZ*1, dir_buf, 3*(DIRSIZ+4));//dir_buf中的前3個元素拷貝到磁碟資料區的第2個數據塊
    iput(inode);

    inode = iget(3);  /* 3  password id */
    inode->di_number = 1;
    inode->di_mode = DEFAULTMODE | DIFILE;
    inode->di_size = BLOCKSIZ;
    inode->di_addr[0] = 2; /*block 2# is used by the password file*/

    for (i=5; i<PWDNUM; i++){//設定其餘使用者的屬性
        passwd[i].p_uid = 0;
        passwd[i].p_gid = 0;
        strcpy(passwd[i].password, "            ");  // 密碼為空
    }

    memcpy(pwd, passwd, 32*sizeof(struct pwd));//passwd的內容拷貝到pwd中
    memcpy(disk+DATASTART+BLOCKSIZ*2, passwd, BLOCKSIZ);//passwd的內容拷貝到disk的第3個數據塊(只拷貝一個數據塊的大小)
    iput(inode);
  1. 初始化硬碟
    將硬碟所有的塊(引導塊+超級塊+inode塊+資料塊)的內容全部置為0;
  2. 初始化陣列 passwd
    建立使用者:使用者uid+使用者所屬組gid+使用者密碼;將這些資訊儲存在passwd[]數組裡。
  3. 建立主目錄..+子目錄.+etc目錄+password目錄
    這幾個目錄的關係是 .././etc/passwd
    這裡寫圖片描述
    這一步具體是怎麼建立的,需要細細說明。

1)inode0 用於建立..目錄(/的父目錄)

    inode = iget(0);   /* 0 empty dinode id*/
    inode->di_number = 1;//關聯檔案數設為1         
    inode->di_mode = DIEMPTY;//許可權設為空許可權
    iput(inode);//回收inode結點

兩點是父目錄,一點是當前目錄,為了和Linux系統對應,我們可以這裡的將..理解為根目錄/的父目錄,.理解為根目錄/,etc是根目錄/的子目錄。其實/是沒有父目錄的,之所以為/建立一個父目錄是因為除了/之外,是為了和其他目錄的操作保持一致,其他目錄都有父目錄。
但是由於實際上/沒有父目錄,因此這裡的/的父目錄只是佔用了inode 0,並不佔用block。
2)inode1 & block0 用於建立.目錄(根目錄/)

    inode = iget(1);   /* 1 main dir id*/
    inode->di_addr[0] = 0; /*block 0# is used by the main directory*/

block0中的內容為:

檔名     inode編號
..              1
.               1
etc             2

這個地方,..的inode本來是0,原始碼是不是寫錯了?
對於所有目錄來說,我們都能在它的block中找到父目錄的inode編號,它自己對應的inode編號,以及它底下包含的檔案的inode編號。
3)inode2 & block1用於建立etc目錄(/的子目錄)

    inode = iget(2);  /* 2  etc dir id */
    inode->di_addr[0] = 1; /*block 1# is used by the etc directory*/

block1中的內容為:

檔名     inode編號
..              1
.               2
password        3

4)inode3 & block2 用於建立password檔案(/etc目錄下的檔案)

    inode = iget(3);  /* 3  password id */
    inode->di_addr[0] = 2; /*block 2# is used by the password file*/

block2中的內容為:

p_uid   p_gid   password
2116    03      dddd
2117    03      bbbb
2118    04      abcd
2119    04      cccc
2120    05      eeee

對於所有檔案來說,block中存放的就是檔案的資料內容。
4. 初始化超級塊(superblock)
- 空閒inode陣列

/*2. initialize the superblock */

    filsys.s_isize = DINODEBLK;//inode佔用的block塊數32(注意不是inode的個數)
    filsys.s_fsize = FILEBLK;//data block總塊數512

    /*注意:inode存放在block中,共佔用32block,一個inode大小為52,可以計算出inode的總個數*/
    filsys.s_ninode = DINODEBLK * BLOCKSIZ/DINODESIZ - 4;//4塊被 root的父目錄,root,etc,password佔用
    filsys.s_nfree = FILEBLK - 3;//空閒block數:root,etc,password已經佔用了三塊資料塊

    for (i=0; i < NICINOD; i++){
        /* begin with 4,    0,1,2,3, is used by main,etc,password */
        filsys.s_inode[i] = 4+i;//空閒inode陣列
    }

    filsys.s_pinode = 0;//空閒inode指標,指向s_inode的第0個元素
    filsys.s_rinode = NICINOD + 4; //??

    block_buf[NICFREE-1] = FILEBLK+1;  /*FILEBLK+1 is a flag of end*/
    for (i=0; i<NICFREE-1; i++)
        block_buf[NICFREE-2-i] = FILEBLK-i-1;           //從最後一個數據塊開始分配??????

    /*將block map表存放在block中:從最後一個block開始存,每個block存放50個block號,block號和存放的第1個block號相同*/
    memcpy(disk+DATASTART+BLOCKSIZ*(FILEBLK-NICFREE), block_buf, BLOCKSIZ);
    for (i=FILEBLK-2*NICFREE+1; i>2; i-=NICFREE){
        for (j=0; j<NICFREE;j++){
            block_buf[j] = i+j;
        }
        memcpy(disk+DATASTART+BLOCKSIZ*(i-1), block_buf, BLOCKSIZ);
    }
    i += NICFREE;
    j = 1;
    for (; i>3; i--)
    {
        filsys.s_free[NICFREE-j] = i-1; 
        j ++;
    }

    filsys.s_pfree = NICFREE - j+1; //空閒塊指標
    memcpy(disk+BLOCKSIZ, &filsys, sizeof(struct filsys));//filsys的內容存放在超級塊:拷貝在磁碟的第0塊
    return;

超級塊的初始化重點要理解空閒block堆疊。試想一下假設使用者要建立一個資料夾Lin

mkdir Lin

那麼系統要給Lin資料夾分配一個空的inode和一個空的block,那麼怎麼知道要分配哪一個inode和哪一個block呢?於是在超級塊中就要存放空閒inode陣列和空閒block棧的資訊,以便快速地找到可分配的inode和block。
1)空閒inode陣列的初始化——s_inode[]

這裡寫圖片描述

由於前0,1,2,3inode已經被佔用了,0被..佔用,1被.佔用,2被etc佔用,3被passwd佔用,因此空閒inode從4開始。

for (i=0; i < NICINOD; i++){
        /* begin with 4,    0,1,2,3, is used by main,etc,password */
        filsys.s_inode[i] = 4+i;//空閒inode陣列
    }

2)空閒block棧的初始化——s_free[]
棧大小是50,棧底存放結束標誌,因此棧總共能存放49個block編號。磁碟共512個block,有3塊已經被用了,所以物理塊號從3開始。初始化時從511號(第512塊)block開始,向後數49個(一個棧能存放的大小)block到463號block,將這50個block的編號存放在第463號block中,按照這個規律向後推,462號block到414號block,一共49個block的編號存放在414號block中,按照這個規律一直計算下去,512%49=10,最後剩下10個block不夠一個棧的大小,就存在棧中。

當要分配block時就從棧頂開始分配block號,當棧為空,就從磁碟block中依次讀出一個block存放的block編號,以供後續block的分配,然後棧再為空,又再從磁碟讀入block編號。

後續在block分配的程式碼中,我們可以看到這種存放方式,使得一組新的block編號的載入變得很簡單。因為每一組的第一block就是用來存放這一組block編號的,例如 463號block就存放463-511這組block編號,414號block就存放414-462這組block編號。

一組block編號(一組的大小就是棧的大小)
這裡寫圖片描述
這裡寫圖片描述

初始化後的空閒block棧
這裡寫圖片描述

ballfre.cpp——分配block




static unsigned int block_buf[BLOCKSIZ];
/**********************************************************
函式:balloc
功能:維護超級塊中的空閒資料棧,分配空閒資料塊,並返回其塊號
***********************************************************/
unsigned int balloc(){
    unsigned int free_block;
    int i;

    //如果沒有空閒盤塊
    if (filsys.s_nfree == 0){
        printf("\nDisk Full!!!\n");
        return DISKFULL;
    }
    free_block = filsys.s_free[filsys.s_pfree]; //取堆疊中的盤塊號(從3號物理塊開始分配)
    if (filsys.s_pfree == NICFREE-1){           //如果堆疊只剩一個塊
        memcpy(block_buf,disk+DATASTART+(free_block)*BLOCKSIZ,BLOCKSIZ);
        //從中讀取下一組塊號
        for (i=0; i<NICFREE; i++)
            filsys.s_free[i] = block_buf[i];
        filsys.s_pfree = 0;             //設定堆疊指標
    }else{//如果堆疊中大於一個盤塊
        filsys.s_pfree++;               //修改堆疊指標
    }
    filsys.s_nfree --;                  //修改總塊數
    filsys.s_fmod = SUPDATE;
    return free_block;  
}

磁碟格式化後,由於已經用掉了3個block,因此空閒block的編號從3開始。s_free空閒block棧如下所示,棧大小為50,棧底s_free[49]=12,盤塊號為12,棧頂s_free[40]=3,即盤塊號為3,一共有9個物理塊號。s_pfree空閒block棧指標值為40,即指向3號盤塊的下標。
這裡寫圖片描述
那麼,當用戶登入,開始進行第一次建立時,假設執行命令

mkdir Lin

第一次分配block的具體過程說明如下:
1)檢視空閒block數s_nfree,s_nfree>0,表明還有空閒block
2)查詢空閒塊棧s_free,通過s_pfree找到盤塊號3
3)空閒block數s_nfree減1
4)返回空閒block編號,即3
此時,Lin資料夾所用的block就是3號block。

第9次分配block的具體過程說明如下:
1)檢視空閒block數s_nfree,s_nfree>0,表明還有空閒block
2)查詢空閒塊棧s_free,通過s_pfree找到盤塊號12
3)棧中只剩下一個盤塊,從磁碟中讀取下一組塊號,盤塊號從13開始,到62,共50個物理塊號,到棧中。
這裡寫圖片描述
….

這裡寫圖片描述
4)空閒block數s_nfree減1
5)返回空閒block編號,即12
inode的分配和block的分配區別不大。

第三部分— 錯誤修復和程式碼完善

  1. Run-Time Check Failure #2 - Stack around the variable ‘passwd’ was corrupted.
    把 project->配置屬性->c/c++->程式碼生成->基本執行時檢查 為 預設值 就不會報本異常。具體原因正在研究中。。。
    如果改為其他就有exception。
  2. log.cpp/logout增加
user[i].u_uid = 0;
user[i].u_gid = 0;

相關推薦

Linux檔案系統程式碼學習筆記--磁碟格式化&block分配

第一部分——準備知識 磁碟格式化這一步驟到底做了什麼? 為了讀懂程式碼,首先先掌握幾個知識點。 memcpy函式 void * __cdecl memcpy(_Out_writes_bytes_all_(_Size) void * _Dst,

linux嵌入式根檔案系統製作學習筆記

根檔案製作方法1.取得busybox原始碼,編譯並安裝根檔案    1)在busybox主目錄下執行make menuconfig  選擇元件編譯        make menuconfig     2)修改busybox主目錄下的makefile,使用交叉編譯器進行編譯 

Linux檔案系統被佔用,磁碟使用量與實際不一致

客戶某應用系統反饋出現一個奇怪的現象,df -h 查詢的容量已經要到警戒值,但實際該目錄使用只有15%左右,具體見下圖:OS版本為RHEL4.5資源佔用率也很正常      執行命令lsof -n | grep deleted印出所有針對已刪除檔案的讀寫操作,這類操作是

Linux學習筆記14——認識 Linux 檔案系統

系統管理員很重要的任務之一就是管理好自己的磁碟檔案系統,每個分割槽不可太大也不能太小, 太大會造成磁碟容量的浪費,太小則會產生檔案無法儲存的困擾。此外,我們在前面幾章談到的檔案許可權與屬性中, 這些許可權與屬性分別記錄在檔案系統的哪個區塊內?這就得要談到 filesystem 中的 inode 與

linux檔案系統磁碟格式化

千萬注意:分割槽格式化磁碟前確保你磁碟的資料備份好了,要不可能就沒了。 1、傻瓜式磁碟分割槽,最直接的方式(先fdisk後parted)。不用瞭解檔案系統的原理。此處將對兩種分割槽機制磁碟進行分割槽格式化(MBR型別磁碟——用fdisk###GPT型別磁碟——用parted

Linux系統程式設計學習筆記(1)-檔案的I/O操作

概述 在Linux系統下,通常以一個非負整數來代指一個開啟的檔案,這些檔案可以包括終端,socket,裝置,普通檔案等等。規定的三個標準的檔案描述符為0,1,2下面分別介紹(在互動式shell中,這些檔案描述符通常指向shell執行所在的終端): 檔案描述

PowerShell 學習筆記-- 3 -- 格式化輸出,檔案系統

四個cmdlet使用者格式化輸出。Format-ListFormat-CustomFormat-TableFormat-Wide例如:  get-service | format-list  -property  *         gwmi win32_share | fo

LS8-linux系統呼叫方式檔案程式設計之學習筆記

linux系統呼叫方式檔案程式設計 定義/功能:檔案描述符 在Linux系統中,所有開啟的檔案對應一個數字,這個數字由系統分配,稱之為:檔案描述符。(可類似理解為:省份證號與你本人的關係),通過檔案描述符便可以對檔案進行操作。 開啟檔案 1.1 函式名

Linux學習筆記Linux檔案系統

Linux檔案系統root      存放root使用者相關檔案home    存放普通使用者的相關檔案bin         存放普通命令檔案的目錄sbin        具有一定權才能使用的命令的目錄mnt        掛載軟碟機,光碟機的地方etc         存

《Unix&Linux大小教程》學習筆記6——Unix文件系統

文件類型 src pos strong ron 輸出 lin post 二進制文件 1:Unix文件類型——3種 普通文件(常規文件):文本文件(純文本、腳本、源程序、配置文件、html等)、二進制文件(多媒體文件、數據庫等) 目錄:用於組織文件 偽文件:不存儲數據,目的是

《鳥哥的linux私房菜》學習筆記2-檔案與目錄管理與查閱(思維導圖)

1、常見處理目錄的命令:cd,pwd,mkdir,rmdir 2、檔案與目錄的管理:ls(https://blog.csdn.net/weixin_42610712/article/details/83032052),cp,rm,mv,touch 3、檔案內容查閱——cat 4、檔案內容

Linux系統程式設計學習筆記

PDB的常用的除錯命令: 程式先寫完的情況的呼叫方式: 1、 python3  -m pdb test.py  #斷點的過程  b 7     ## 後面的數字是 行數  ## = 清楚斷點的

linux運維筆記-linux檔案系統

Linux檔案系統運維常見問題總結1,描述GPT是什麼,應該怎麼使用GPT意為GUID分割槽表,他是一個逐漸取代MBR的新標準。他最多可以支援128個GPT分割槽,而且你還不要建立擴充套件分割槽。在MBR磁碟上,分割槽和啟動資訊是儲存在一起的。如果這部分資料被覆蓋或破壞,事情就麻煩了。相對的,GPT在整個磁碟

linux中proc檔案系統 -- ldd3讀書筆記

     1./proc 檔案系統概述      /proc 檔案系統是由軟體建立,被核心用來向外界報告資訊的一個檔案系統。/proc 下面的每一個檔案都和一個核心函式相關聯,當檔案的被讀取時,與之對應的核心函式用於產生檔案的內容。我們已經見到了很多這樣的檔案,例如,/pr

【鳥叔的Linux私房菜】學習筆記(1)——Linux系統入門

雖然現在工作一直在用Xshell 一些 基本的命令、常用的還可以, 但總感覺對Linux瞭解的知之甚少,偶爾改個檔案還需要請教同事,真是慚愧。 所以決定從今天開始重新學習下Linux,查漏補缺,並將學習的結果作為筆記和大家一塊交流和進步,就開始我們今天的學習吧。 一

程式碼參考網上的】linux串列埠程式設計學習筆記

1.串列埠通訊:同步通訊:將很多字元組成一個資訊組進行傳送非同步通訊:一個字元一符的傳送。(可靠性高,但是效率相對降低) 2.通過echo和cat來測試串列埠通訊 echo “Hello” >/dev/ttyS0   cat /dev/ttyS1 3.直接通過read

linux檔案系統&磁碟操作常用命令

1. 檢視系統磁碟 fdisk -l fdisk -lu 2.對磁碟進行分割槽 fdisk /dev/sda 3. 分割槽格式化 mkfs.ext2  /de/sda1 4. 掛載裝置 mount  /dev/sda1  /目錄 5.檢視檔案系統掛載情況 mount 6.檢

Linux檔案系統操作與磁碟管理

一、基本操作 1.1 檢視磁碟和目錄的容量 使用 df 命令檢視磁碟的容量 $ df 在實驗樓的環境中你將看到如下的輸出內容: 但在實際的物理主機上會更像這樣: 一般使用情況下,我們更多隻是關心第一行的內容也就是環境中的rootfs或者物理主機上的/dev/sda2

筆記 Linux檔案系統的初始化

uboot結束時呼叫start_kernel(/3.1.10/init/main.c)函式啟動linux start_kernel做記憶體初始化,作業系統資料結構初始化,排程系統初始化,各種資源初始化之後會呼叫vfs_caches_init初始化檔案系統(/3.1.10/

Linux指令碼攻略學習筆記之臨時檔案命名與隨機數

最適合儲存臨時資料的位置是 /tmp(該目錄中的內容在系統重啟後會被清空) mktemp 命令的用法非常簡單。它生成一個臨時檔案並返回其檔名(如果建立的是目錄,則返回目錄名)。如果提供了定製模板, X