TpsFs文件系統簡介

1、TpsFs簡介

       TpsFs(True Power Safe File System)是一款掉電安全的文件系統,該文件系統是SylixOS內建文件系統(專利技術)。TpsFs是基於事務的B+樹文件系統:對元數據的修改使用事務提交的機制,保證了文件系統的一致性;使用B+樹管理磁盤空間和文件空間,使得存儲文件數據與定位速度更快、空間管理效率更高。TpsFs的源碼可以在SylixOS Base工程下的"libsylixos/SylixOS/fs/TpsFs/"目錄下查看。

2、TpsFs基本數據結構簡介

       每一種文件系統都有自己特定的數據結構和管理數據的方式,不同的文件系統其數據結構也有所不同,但所有文件系統也有一定的共性。下面介紹TpsFs中用來管理數據的一些結構。

2.1數據單元

       當文件系統在磁盤分區上創建後,就可以進行數據的讀取和存儲了。數據在寫入磁盤或從磁盤讀取時每次操作的數據量稱爲數據單元,它的大小在建立文件系統時確定。數據單元在不同的文件系統中有不同的稱呼方式,例如FAT中的"簇",EXT中的"塊"。一個數據單元由若干個連續物理扇區組成,大小總是2的整數次冪個扇區。存儲數據時,系統以數據單元爲最小單位爲其分配存儲空間。在TpsFs中,數據單元以"塊"爲單位,並且最小不能小於4096字節,塊大小可以在格式化TpsFs文件系統時通過tpsFsFormat函數的參數指定,通常情況下將其設置爲4096字節。tpsFsFormat函數原型如程序清單2- 1所示。

程序清單2- 1 tpsFs格式化函數


errno_t tpsFsFormat (PTPS_DEV pdev, UINT uiBlkSize)


       函數tpsFsFormat原型分析如下:

              函數成功返回ERROR_NONE,失敗返回錯誤號;

              參數pdev是設備對象;

              參數uiBlkSize是塊大小。

       塊號的定義如程序清單2- 2所示。

程序清單2- 2 塊號定義

typedef UINT64 TPS_INUM;


2.2超級塊

       超級塊用來描述一個文件系統的基本信息,例如文件系統塊大小、總塊數、文件系統在磁盤分區內的整體佈局(數據區、日誌區等位置和大小)、已打開文件鏈表等等。TpsFs將超級塊保存在磁盤分區的第0塊內,每一個磁盤分區內只有一個超級塊結構體。超級塊結構體的定義如程序清單2- 3所示。

程序清單2- 3 超級塊結構體定義

typedef struct tps_super_block {
UINT                  SB_uiMagic;                  /*  magic數值                 */
UINT                  SB_uiVersion;                /*  版本                      */
UINT                  SB_uiSectorSize;             /*  塊設備的扇區大小          */
UINT                  SB_uiSectorShift;
UINT                  SB_uiSectorMask;
UINT                  SB_uiSecPerBlk;              /*  每塊扇區數                */
 
UINT                  SB_uiBlkSize;                /*  塊大小                    */
UINT                  SB_uiBlkShift;
UINT                  SB_uiBlkMask;
 
UINT                  SB_uiFlags;                 /*  掛載標識                   */
UINT64                SB_ui64Generation;          /*  標識一次格式化用於系統修復 */
UINT64                SB_ui64TotalBlkCnt;         /*  總塊數                     */
UINT64                SB_ui64DataStartBlk;        /*  數據塊起始                 */
UINT64                SB_ui64DataBlkCnt;          /*  數據塊數量                 */
UINT64                SB_ui64LogStartBlk;         /*  日誌塊起始                 */
UINT64                SB_ui64LogBlkCnt;           /*  日誌塊數量                 */
UINT64                SB_ui64BPStartBlk;          /*  btree塊緩衝表起始塊        */
UINT64                SB_ui64BPBlkCnt;            /*  btree塊緩衝表塊數量        */
TPS_INUM              SB_inumSpaceMng;            /*  空間管理inode號            */
TPS_INUM              SB_inumRoot;                /*  文件系統根inode號          */
TPS_INUM              SB_inumDeleted;             /*  已刪除文件列表             */
PTPS_DEV              SB_dev;                     /*  設備對象指針               */
struct tps_inode     *SB_pinodeSpaceMng;          /*  空間管理inode              */
struct tps_inode     *SB_pinodeRoot;              /*  文件系統根inode            */
struct tps_inode     *SB_pinodeDeleted;           /*   已經刪除的文件            */
struct tps_inode     *SB_pinodeOpenList;          /*  以打開文件鏈表             */
UINT                  SB_uiInodeOpenCnt;          /*  當前打開文件數             */
 
PUCHAR                SB_pucSectorBuf;            /*  磁盤頁面緩衝區             */
struct tps_blk_pool  *SB_pbp;                     /*  btree塊緩衝鏈表            */
struct tps_trans_sb  *SB_ptranssb;                /*  事務系統超級塊             */
} TPS_SUPER_BLOCK;


2.3inode節點

       inode節點也被稱作元數據,用於表示一個文件,這裏的文件不只是普通文件,也包括目錄等其他類型的文件,與Linux相似,SylixOS也遵循一切皆文件的原則,文件的類型定義符合UNIX標準,文件類型保存在inode結構體中的IND_iMode成員裏,其類型有以下幾種。

表2- 1 文件類型

IND_iMode

文件類型

S_IFIFO

FIFO文件

S_IFCHR

字符設備

S_IFDIR

目錄

S_IFBLK

塊設備

S_IFREG

普通文件

S_IFLNK

符號鏈接

S_IFSOCK

Socket文件

inode還記錄了文件的大小、創建時間、訪問權限等內容。

2.4目錄項

       如果一個文件的類型爲目錄,那麼這個文件的數據區保存的數據就是目錄項結構,該目錄下的每一個子文件都對應一個目錄項。目錄項記錄了這個子文件的名字、名字長度和該子文件對應的inode節點所在位置,查找文件實際上就是從根節點開始遍歷目錄項的過程。

2.5B+樹

       B+樹可以減少磁盤的訪問次數,提高文件的查找效率,文件系統一般都會採用B/B+樹來對文件數據進行管理。TpsFs內有兩種B+樹,一種是用於管理空閒塊的B+樹,它由空間管理inode進行管理,可以看做是一個大文件,其文件的inode是空間管理inode;另一種是用於管理普通文件空間的B+樹,它用於管理這個文件內的數據塊,即每一個普通文件都會對應一個B+樹來進行數據管理。通過該普通文件對應的inode可以查找到B+樹的根節點,進而可以實現整個B+樹的遍歷。

2.6事務

       TpsFs採用事務提交機制,即每次進行寫操作(寫數據+寫元數據)時,會把各個步驟看做是一個個小事務,整體算一個大事務,TpsFs會把各個小事務先寫進日誌塊區域,日誌全部寫進成功之後,再把它寫進數據塊區域。

3、TpsFs整體佈局


       由上一節可知,TpsFs的整體佈局由超級塊結構體描述,在TpsFs中,超級塊的一些常量定義如程序清單3- 1所示。

程序清單3- 1 超級塊常量

/**************************************************************************
super block常量定義
**************************************************************************/
#define TPS_MIN_LOG_SIZE           (512 * 1024)    /*  最小日誌大小      */
#define TPS_SUPER_BLOCK_SECTOR     0               /*  超級快扇區號      */
#define TPS_SUPER_BLOCK_NUM        0               /*  超級塊號          */
#define TPS_SPACE_MNG_INUM         1               /*  空間管理inode號   */
#define TPS_ROOT_INUM              2               /*  根inode號         */
#define TPS_BPSTART_BLK            3               /*  塊緩衝起始        */
#define TPS_BPSTART_CNT            7               /*  塊緩衝塊數目      */
#define TPS_DATASTART_BLK          10              /*  數據塊起始        */
#define TPS_MIN_BLK_SIZE           4096            /*  最小塊大小限制    */



文件系統佈局是在磁盤分區格式化時建立的,格式化函數tpsFsFormat建立文件系統佈局的流程如程序清單2- 3所示。

程序清單3- 2 tpsFsFormat函數建立文件系統佈局

errno_t tpsFsFormat (PTPS_DEV pdev, UINT uiBlkSize)
{
    ...
    /*
     * 磁盤最小爲 4MB
     */
    uiSctPerBlk     = uiBlkSize / uiSectorSize;
    uiTotalBlkCnt     = pdev->DEV_SectorCnt(pdev) / uiSctPerBlk;
    if (uiTotalBlkCnt < 1024) {
        return (ENOSPC);
    }
 
    /*
     * logsize爲磁盤的 1/16
     */
    uiLogBlkCnt     = uiTotalBlkCnt >> 4;
    uiLogSize     = uiLogBlkCnt * uiBlkSize;
    if (uiLogSize < TPS_MIN_LOG_SIZE) {
        uiLogSize = TPS_MIN_LOG_SIZE;
    }
 
    /*
     * 結構體賦值
     */
    psb = (PTPS_SUPER_BLOCK)TPS_ALLOC(sizeof(TPS_SUPER_BLOCK));
    if (LW_NULL == psb) {
        return (ENOMEM);
    }
 
    psb->SB_uiMagic            = TPS_MAGIC_SUPER_BLOCK2;
    psb->SB_uiVersion          = TPS_CUR_VERSION;
    psb->SB_ui64Generation     = TPS_UTC_TIME();
    psb->SB_uiSectorSize       = uiSectorSize;
    psb->SB_uiSectorShift      = (UINT)archFindMsb((UINT32)uiSectorSize) - 1;
    psb->SB_uiSectorMask       = ((1 << psb->SB_uiSectorShift) - 1);
    psb->SB_uiSecPerBlk        = uiSctPerBlk;
    psb->SB_uiBlkSize          = uiBlkSize;
    psb->SB_uiBlkShift         = (UINT)archFindMsb((UINT32)psb->SB_uiBlkSize) - 1;
    psb->SB_uiBlkMask          = ((1 << psb->SB_uiBlkShift) - 1);
    psb->SB_uiFlags            = TPS_MOUNT_FLAG_READ | TPS_MOUNT_FLAG_WRITE;
    psb->SB_ui64TotalBlkCnt    = uiTotalBlkCnt;
    psb->SB_ui64DataStartBlk   = TPS_DATASTART_BLK;
    psb->SB_ui64DataBlkCnt     = uiTotalBlkCnt - TPS_DATASTART_BLK - uiLogBlkCnt;
    psb->SB_ui64LogStartBlk    = uiTotalBlkCnt - uiLogBlkCnt;
    psb->SB_ui64LogBlkCnt      = uiLogBlkCnt;
    psb->SB_ui64BPStartBlk     = TPS_BPSTART_BLK;
    psb->SB_ui64BPBlkCnt       = TPS_BPSTART_CNT;
    psb->SB_inumSpaceMng       = TPS_SPACE_MNG_INUM;
    psb->SB_inumRoot           = TPS_ROOT_INUM;
    psb->SB_inumDeleted        = 0;
    psb->SB_pinodeOpenList     = LW_NULL;
    psb->SB_dev     = pdev;
    psb->SB_uiInodeOpenCnt     = 0;
    psb->SB_pinodeDeleted      = LW_NULL;
    psb->SB_pbp                = LW_NULL;
    ...
}



       由程序清單3- 2可以看出,tpsFsFormat函數根據磁盤分區的扇區數量,塊大小以及超級塊常量來構建文件系統,格式化完成後,文件系統在磁盤分區內的佈局如圖3- 1所示。

圖3- 1 文件系統佈局

4、總結

       本文主要介紹了TpsFs的整體框架,TpsFs的讀寫流程,事務提交,B+樹管理機制等將在後續文檔介紹。

5、參考資料

      《SylixOS應用程序開發手冊》

        SylixOS內核源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章