此文件系統暫時命名爲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
測試結果: