自己編寫UNIX檔案系統

來源:互聯網
上載者:User

近日有人求助,要寫一個UNIX檔案系統作為暑假作業。這種事情基本是學作業系統的必須要做的或者是做過的,畢竟檔案系統是作業系統課程的一個重要組成部分。要實現這個UNIX檔案系統,很多人就紮進了UNIX V6的的系統源碼,以及《萊昂氏UNIX原始碼分析》和《返璞歸真:UNIX技術內幕》這兩本書,很多人出來了,很多人在裡面迷失了...最終忘了自己只是要實現一個UNIX檔案系統而已。

為何會迷失,因為代碼不是自己寫的,而且年代久遠,編程理念不同了,作者為何那樣寫不一定就能理解,實際上對於任何別人寫的代碼,總是會有一些不易理解的地方,當然,如果作者水平超級高,那麼代碼也就相對容易理解。因此,寫代碼永遠比讀代碼要容易!既然是要寫一個檔案系統,為何要用現成的UNIX V6代碼呢?如果理解了UNIX檔案的布局和結構,自己從零開始不參考任何現有的代碼做一個也不是什麼難事,最根本的是UNIX檔案系統本身,至於說代碼,僅僅是一個實現與使用者操作的一個介面而已。如果代碼是自己一點一點寫的,那麼你肯定能徹底明白每一行的每一個語句的精確含義,至於為何這麼寫,你當然及其明了!

本文留下我倉促間幾個小時寫的一個類UNIX檔案系統的代碼,不是讓別人看的,是為了自己留檔,因為本文已經說了,看別人的代嗎只能學習經驗,不能理解本質,更何況,你看的還得是超級一流的代碼,而我寫的,則是超級垃圾的代碼。我只想說,理解問題的本質要比代碼重要得多,代碼,碼,並不是很多人想象中的那般重要!本文的實現基於Linux系統,即在Linux系統上編寫一個使用者態程式,實現UNIX檔案的IO介面以及操作。

推薦閱讀:

UNIX/Linux 系統管理技術手冊(第四版)高清中文PDF 下載:

UNIX/Linux 系統管理技術手冊(第四版)高清英文PDF 下載見

我一向堅持的原則,那就是任何東西的根本性的,本質上的原理以及背後的思想都是及其簡單的,所謂的複雜性都是最佳化與策略化的擴充帶來的,正如TCP一樣,UNIX的檔案系統也不例外!我們必須知道,什麼是最根本的,什麼是次要的。對於UNIX檔案系統,最根本的就是其布局以及其系統調用介面,一個處在最低層,一個在最上層開放給使用者,如下所示:

系統調用介面:open,write,read,close...

檔案系統布局:引導快,超級塊,inode區表,資料區塊區

所有的在二者中間的部分都是次要的,也就是說那些東西不要也行,比如高速緩衝,快取,VFS層,塊層...因此在我的實現代碼中,並沒有這些東西,我所做到的,僅僅是UNIX檔案系統所要求必須做到的最小集,那就是:

面對一個按照UNIX檔案系統標準布局的“塊裝置”,可以使用open,read,write等介面進行IO操作。

在實現中,我用一個標準的Linux大檔案來類比磁碟塊,這樣塊的操作基本都映射到了Linux標準的write,read等系統調用了。

首先定義必要的結構體:

//超級塊結構
struct filesys {
        unsigned int s_size;        //總大小                                         
        unsigned int s_itsize;        //inode表大小                                       
        unsigned int s_freeinodesize;    //空閑i節點的數量                         
        unsigned int s_nextfreeinode;    //下一個空閑i節點
        unsigned int s_freeinode[NUM];    //空閑i節點數組
        unsigned int s_freeblocksize;    //空閑塊的數量         
        unsigned int s_nextfreeblock;    //下一個空閑塊
        unsigned int s_freeblock[NUM];    //空閑塊數組
        unsigned int s_pad[];        //填充到512位元組 
};
//磁碟inode結構
struct finode {
        int fi_mode;            //類型:檔案/目錄
        int fi_uid_unused;        //uid,由於和進程無關聯,僅僅是類比一個FS,未使用,下同
        int fi_gid_unused;
        int fi_nlink;            //連結數,當連結數為0,意味著被刪除
        long int fi_size;        //檔案大小
        long int fi_addr[BNUM];        //檔案塊一級指標,並未實現多級指標
        time_t  fi_atime_unused;    //未實現
        time_t  fi_mtime_unused;
};
//記憶體inode結構
struct inode {
        struct finode  i_finode;
        struct inode    *i_parent;    //所屬的目錄i節點
        int    i_ino;            //i節點號
        int    i_users;        //引用計數
};
//目錄項結構(非Linux核心的目錄項)
struct direct
{
        char d_name[MAXLEN];        //檔案或者目錄的名字
        unsigned short d_ino;        //檔案或者目錄的i節點號
};
//目錄結構
struct dir
{
        struct direct direct[DIRNUM];    //包含的目錄項數組
        unsigned short size;        //包含的目錄項大小   
};
//抽象的檔案結構
struct file {
        struct inode *f_inode;        //檔案的i節點
        int f_curpos;            //檔案的當前讀寫指標
};

之所以叫做類UNIX檔案系統,是因為我並沒有去精確確認當時的UNIX檔案系統的超級塊以及inode表的結構,只是大致的模仿其布局,比如超級塊中欄位,以及欄位的順序可能和標準的UNIX檔案系統並不完全一致。但是不管怎麼說,當時的UNIX檔案系統基本就是這個一個樣子。另外,可以看到file結構體內容及其少,因為本質上,我只是想表示“一個inode節點相對於一個讀寫者來說,就是一個file”,僅此而已。接下來就是具體的實現了,我的方式是自下而上的,這樣做的好處在於便於今後的擴充。那麼首先要完成的就是i節點的分配和釋放了,我的實現中,是將檔案i節點映射到了記憶體i節點,這樣或許違背了我的初衷,我不是說過不要那麼多“額外”的東西來擾亂視聽嗎?是的,然而比起那些所謂的額外的最佳化,我更不喜歡頻繁的調用read和write。反正,只要自己能控制住局面即可。

在實現中,還有一個大事就是記憶體的分配與釋放,這些也不是本質的,記住,要實現的僅僅是一個UNIX檔案系統,其它的能繞開則繞開!顯然malloc,free等也是我們要繞開的,於是我基本都使用預分配空間的東西-全域數組。以下是全域變數:

//記憶體i節點數組,NUM為該檔案系統容納的檔案數
struct inode g_usedinode[NUM];
//ROOT的記憶體i節點
struct inode *g_root;
//已經開啟檔案的數組
struct file* g_opened[OPENNUM];
//超級塊
struct filesys *g_super;
//類比二級檔案系統的Linux大檔案的檔案描述符
int g_fake_disk = -1;

  • 1
  • 2
  • 下一頁

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.