一個簡單的文件系統

此文件系統暫時命名爲lxfs。使用B+樹作爲管理結構,但是爲了可以容納更多信息,做了一定的修改。下面是傳統的B+樹,信息全部保存在葉結點中,通過內部節點進行索引,每一個父級節點的元素索引一個子節點。

以下是經過修改的B+樹,每個父節點可以多索引一個子節點。有利於進一步降低樹的高度,容納更多信息。

B+樹的操作有插入、刪除、節點分裂、節點合併、查找、遍歷等。

下面是文件索引結構設計:

//B+樹內部節點,52kb
#define BNODE_NUM 1401
#define BNODE_SIZE 52*1024
#define CHILD_TYPE_BNODE 0	            //childType屬性,內部節點類型
#define CHILD_TYPE_LNODE 3	            //childType屬性,葉節點類型
typedef struct BTreeNode {
	extName name[BNODE_NUM];			//文件名描述符數組
	uint32 child[BNODE_NUM + 1];		//子節點指針數組,可能爲內部節點或葉節點,使用時,要強制轉換爲結點指針後使用
	uint16 name_off[BNODE_NUM - 1];		//記錄每個文件名的起始下標,從第二個文件名開始
	uint32 parent;			            //父節點指針
	uint16 name_off_num:14;				//記錄name_off數組的有效長度
	uint16 childType:2;					//子節點類型,0=內部節點,3=葉節點
	uint16 namenum;						//記錄name數組的長度
}BTreeNode, * _btreenode, * _bn;
 
//B+樹葉節點
#define LNODE_NUM 2409
//葉節點,80kb
#define LNODE_SIZE 80*1024
typedef struct LeafNode {
	fileItems fi[LNODE_NUM];			//文件描述符數組
	uint16 file_off[LNODE_NUM - 1];		//文件偏移數組,描述文件的起始描述符位下標,由於第一個文件項的下標肯定爲0,因此從第二個文件描述符開始。
	uint16 finum;						//fi數組有效項的長度
	uint16 file_off_num;				//file_off數組有效項的數量
	uint32 prev;				        //前驅節點
	uint32 next;				        //後繼節點
	uint32 parent;			            //父節點指針
}LeafNode, * _leafnode, * _ln;

分爲兩種,一個是葉節點用來保存有關文件的信息,一個是內部節點,用來索引葉節點。由於文件信息需要的儲存空間不同,因此在節點結構中設計了偏移數組,用於記錄每一個信息元素的位置。由於增加了這些設計,使B+樹在實現上也變得更加複雜。

lxfs保存文件信息的結構稱爲文件描述符。文件描述符的設計參考了FAT32,但是做了一定修改。如下

//文件屬性/f分區屬性
typedef struct {
    byte dpl : 2;            //文件權限;分區權限 0,1,2,3
    byte extname : 1;        //下一項描述符類型,=0,文件描述符;=1,擴展文件名描述符
    byte isext : 1;            //本描述符是否爲擴展描述符,=1
    byte data : 1;            //=1文件正常,=0此文件可能存在問題;作爲分區描述符時,=1說明此分區是系統分區,
    byte en_folder : 1;        //說明floder項有效,以此文件名作爲後面文件的目錄基準,同目錄下的文件應該只有一個文件的此項爲1
    byte hide : 1;            //=1隱藏文件;=1隱藏分區
    byte del : 1;            //=1已刪除文件,相當於放入回收站,標記刪除,爲了保證可以恢復;=1分區刪除
}fileAtt;
 
//文件日期結構
typedef struct {
    uint32 s : 6;        //秒
    uint32 m : 6;        //分
    uint32 h : 5;        //時
    uint32 day : 5;        //日
    uint32 month : 4;    //月
    uint32 year : 6;    //年,使用是將此值加上基準年份等於時間
}fDate, * _fdate;
 
//用於描述符文件信息的文件描述符
typedef struct {
    byte ms : 7;            //創建時間的10毫秒位,ms*10=大約的創建時間,現在感覺這項沒什麼用
    byte dis : 1;            //=0擴展文件名描述符,=1文件描述符,此項恆等於1
    fileAtt fatt;            //文件屬性
    char name[FTNAME_SIZE];            //文件名,佔用6字節
    fDate createDate;        //創建日期
    fDate lastVisitDate;    //最後訪問日期
    fDate lastModifiedDate;    //最後修改日期
    uint32 size;                //文件長度,單位4kb,因此一個文件最大爲4096GB=4TB
    uint32 position;            //在分區內的偏移位置,單位4kb,最大檢索16tb,因此一個分區的最大爲16tb
    uint16 offset : 12;        //文件佔用的最後一個4kb內的偏移
    uint16 extnum : 4;            //擴展描述符數量,最大爲15個,當此值=15時,應當查看最後一個擴展描述符,確定是否還有擴展描述符
    uint16 folder;                //文件夾包含數量,如果fatt.en_folder=1,說明此文件描述符組爲文件夾描述符,則folder包含了該文件夾的文件數量
}fileTable, * _filetable;
 
//用於儲存文件名的文件名描述符
typedef struct extName {
	byte size : 5;			//本項文本串長度
	byte ext : 1;			//1=有擴展項,此項爲了避免文件描述符指出的15項的限制,以期能夠儲存更多文件項
	byte start : 1;			//=1起始項,爲擴展文件名描述符組的首項
	byte dis : 1;			//=0擴展文件名描述符,=1文件描述符,此項應該恆等於0
	char name[31];			//文件名
}extName, * _extname;
 
//文件項聯合體,一個文件項可能是文件描述符,也可能是擴展文件名描述項
typedef union {
	fileTable ft;			//文件描述符
	extName en;			//擴展文件名描述符
}fileItems, * _fileitems;

fileTable用於儲存文件信息,32字節;

extName用於儲存擴展文件名信息,32字節。

但是一個fileTable可能無法保存文件的所有信息,因此在現有設計中,設計了文件描述符組來儲存信息。一個文件描述符組中描述符的數量是不定的,但是最高允許擁有16個fileTable和15個extName。第一個fileTable稱爲主文件描述符,記錄當前組的描述符,記錄其後屬於同一組的描述符的數量。

另見:https://blog.csdn.net/lindorx/article/details/104015995

github:https://github.com/lindorx/LX-File-System

測試結果:


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