模擬文件系統


操作系統課程設計—模擬文件系統

下載地址:模擬操作系統。在 github 上也有源代碼:github 地址
在 Linux 環境下輸入make編譯,可執行文件是./bin/filesystem。進入系統后輸入reformat格式化系統。然后就可以嘗試各種命令了。

一、設計

將一個大文件當作是模擬的硬盤,包括三個區域:superblock, inode, 扇區。

文件 disk.img 共100MB,按照每個扇區 512B 來計算,共有204800個扇區。

二、superblock

記錄inode和扇區的分配情況。占用512(256KB)個扇區,。使用位圖的形式來記錄inode和數據區的分配情況。

256個扇區來記錄inode的分配情況,inode共占用8192個扇區。也就是用了4MB的磁盤來存放inode。

256個扇區來記錄數據扇區的分配情況,數據扇區共131072個扇區。也就是說磁盤中64MB用來存放數據。

類定義及其解析如下:

class superblock{
private:
  bool inode_bitmap[INODE_NUM];
  bool block_bitmap[BLOCK_NUM];

public:
  // 剩余的inode數量
  int remain_inode();

  // 剩余的扇區數量
  int remain_sec();

  // 返回未使用的i節點
  int get_new_inode();

  // 返回未使用的扇區
  int get_new_sec();

  // 回收i節點
  bool recv_inode(int inode_num);

  // 回收扇區
  bool recv_sec(int sec_num);

  // 初始化位圖全都清0
  superblock();

  // 格式化
  bool init();
};

三、inode

記錄文件和目錄的信息,和占用的數據扇區的信息。每個inode節點32字節,一個扇區可以存放16個inode節點。共占用了8192個扇區。

class Inode{
private:
    // inode號
  int _inode_num;
    // 是否是文件
  bool  _is_file;
    // 文件大小,單位為Byte
  int _file_size;                           
    // 數據扇區號碼,只指定第一個,后面的通過指針連接  
  int _sec_beg;                           
    // 占用的數據扇區數量  
  int _sec_num;                    
   // 填充位,目的是將inode大小控制在32個字節       
  char _compensate[12];            

public:
  // 構造函數初始化
  Inode();

  // 構造函數
  Inode(int node_num, bool _is_file, int file_size, int sec_begin);

  // 獲得inode號碼
  int get_inode_num();

  // true->file; false->dir
  bool get_type();

  // 獲得文件長度
  int get_file_size();

  // 獲得起始磁盤扇區號
  int get_sec_beg();

  // 獲得占據的磁盤扇區數量
  int get_sec_num();

  // 設置inode號
  void set_inode_num(int num);

  // 返回Inode對應的扇區號
  int get_inode_sec_num();

  // 從磁盤中讀取inode
  bool read_inode_from_disk(int inode_num, Buffer& buffer);

  // 將inode寫回到磁盤中
  bool write_inode_back_to_disk(Buffer& buffer);

  // 重載復制運算符
  Inode operator = (const Inode& b) {
  }
};

inode包括這樣幾個信息:

  1. inode號碼,這與目錄中的inode號碼對應
  2. 文件類型,是目錄還是文件
  3. 文件大小,文件的具體大小
  4. 文件起始扇區號
  5. 文件占用的扇區數量

其中,0號inode是根目錄/,根據根目錄的數據扇區號,可以找到磁盤中對該文件夾的描述。

四、數據扇區

存放文件和目錄信息,兩者會有比較大的區別。

// 目錄項
struct sector_dir_entry{                                 
    // 目錄名
  char name[28];                                             
    // 目錄項對應的inode號碼
  int inode_num;                             
    // 初始化
  void init(const char* _name, int _num);    
    // 構造函數
  sector_dir_entry();                                        
    // 重載賦值運算符
  sector_dir_entry operator = (const sector_dir_entry& dir);    
    // 和賦值運算符功能一樣
  void clone(const sector_dir_entry& dir);                                  
};

// 512 Bytes.最后一項指示接下來的目錄
class sector_dir{
public:
    // 構造函數
    sector_dir();

    // 將文件結構寫回到磁盤中
    bool write_back_to_disk(Buffer& buffer, int sec_num);

    // 構造函數
    sector_dir operator = (const sector_dir& sec_dir);

    // 每個扇區有16項目錄信息
    sector_dir_entry dirs[16];

    // 從磁盤中讀取扇區,通過緩存buffer實現
    bool read_dir_from_disk(Buffer& buffer, int sec_num);
};

// 512 Bytes
class sector_file{
public:
    // 每個扇區能存放508字節數據
  char data[508];        
    // 指針指向下一個數據節點
  int next;                    

    // 構造函數
  sector_file();

    // 重載賦值運算符        
  sector_file operator = (const sector_file& sec_file);

     // 通過緩存buffer從磁盤中讀取數據    
  bool read_dir_from_disk(Buffer& buffer, int sec_num);

    // 通過緩存將數據寫回磁盤
  bool write_back_to_disk(Buffer& buffer, int sec_num);
};

4.1文件

每個扇區的前508個字節存放數據,最后一個字節指向下一個數據扇區,如果沒有就置為-1。

字節 0 - 507 508 - 511
作用 存放數據 指向下一個數據扇區

4.2目錄

存放該目錄下的文件名稱和對應的文件indoe號碼。例如:

目錄結構示例:
文件或目錄名 對應的inode號碼
. 1
.. 1
bin 2
etc 3
home 4
dev 5
^ ^
next next_num

其中要求文件或目錄名不超過28字節,后四位用來保存inode號碼,如果一個扇區不夠,最后一項指向下一個扇區。

根目錄對應的inode為1。類似的home目錄結構如下:

文件或目錄名 對應的inode號碼
. 4
.. 1
tr 6
^ ^

home自己的inode號為4,home目錄上一層是根目錄,對應inode為1。這個目錄中有一個文件tr,其inode號碼為6。

五、緩存

模擬磁盤的IO全部從這里經過。會動態地檢查節點的狀態,將長時間沒用的緩存寫回磁盤。

/*******************************************
  緩存類, 模擬磁盤的IO全部從這里經過。
  會動態地檢查節點的狀態,將長時間沒用的緩存寫回磁盤
*******************************************/
// 緩存節點
struct BufferNode{
  // 長度                          
  char buffer[SEC_SIZE + 1];            // 長度為512 + 1個字節(為了保存字符串尾0)
  int pri;                                             // 緩存的優先級,緩存滿了會將優先級最低的節點寫回磁盤
  int sec_num;                                   // 對應的扇區號

    // 重載構造函數
  BufferNode operator = (const BufferNode& b) {
    memcpy(buffer, b.buffer, SEC_SIZE + 1);
    pri = b.pri;
    sec_num = b.sec_num;
  }
  BufferNode(){
    memset(buffer, 0, SEC_SIZE);
    pri = 0;
    sec_num = 0;
  }
  void init(int _sec_num) {
    pri = 5;
    sec_num = _sec_num;
  }
  void update(const BufferNode& b) {
    memcpy(buffer, b.buffer, SEC_SIZE + 1);
    pri = b.pri + 1;
    sec_num = b.sec_num;
  }
};

class Buffer{
  public:
      // 構造函數,打開文件
      Buffer();

      // 析構函數,關閉函數
      ~Buffer();

      // 將 buffer 里面的內容寫入扇區中.單位為512KB。放入緩存隊尾部。
      // 如果扇區已經存在於緩存中,則刷新扇區
      bool write_disk(const BufferNode& node);

      // 將扇區中的內容讀入buffer中,首先會從緩存里找有沒有這個節點。
      // 新讀入緩存的節點優先級為5,如果存在於緩存中,則優先級加 1
      bool read_disk(int sec_num, BufferNode& node);

  private:

    // 真正操作文件
    bool real_disk_write(const BufferNode& node);

    // 真正操作文件
    bool real_disk_read(int sec_num, BufferNode& node);

    // 檢查緩存中有沒有給定扇區號的緩存
    int has_sec(int sec_number);

    // 返回優先級最低的緩存號碼,沒滿返回0
    int is_full();


    // 磁盤緩存,共15個節點,滿了之后會將優先級最低的節點寫回磁盤
    vector<BufferNode> cache;
    // 靜態的文件指針
    fstream disk;
};

六、實現以下文件API

void ls();
int fopen(char* name, int mode);
void fclose(int fd);
int fread(int fd, char* buffer, int length);
int fwrite(int fd, char* buffer, int length);
int flseek(int fd, int position);
int fcreat(char* name, int mode);
int fdelete(char* name);

1. ls命令

當前目錄存放在cur_dir里面,所以只需遍歷一邊就可以輸出目錄

// ls: 列出文件夾下所有文件夾及目錄(cur_dir中所有的信息)
bool my_fs::list_dir() {
    for(int i = 2; i < 15; i++) {
        cout << cur_dir.dirs[i].name << " ";
    }
    cout << endl;
    return true;
}
1.1 運行結果演示

ls

2. cd命令

進入某個目錄

// cd: 進入某個文件夾
bool my_fs::change_dir(const char* name) {
    // 1. 得到子目錄的inode號碼
    int dir_inode_num = -1;
    for(int i = 0; i < 15; i++) {
        if(strncmp(name, cur_dir.dirs[i].name, strlen(name)) == 0) {
            dir_inode_num = cur_dir.dirs[i].inode_num;
            cout << "目錄inode號碼為:" << dir_inode_num << endl;
            break;
        }
    }
    if(dir_inode_num == -1) {
        cout << "該目錄不存在" << endl;
        return false;
    }

    // 2. 根據這個inode號碼找到相應的inode
    cur_dir_node.read_inode_from_disk(dir_inode_num, my_cache);

    // 3. 根據inode中的信息區磁盤中讀取目錄信息
    cur_dir.read_dir_from_disk(my_cache, cur_dir_node.get_sec_beg());

    return true;
}
2.1 運行演示

cd

可以看到已經進入到home目錄了

3.mkdir命令

創建文件夾

// mkdir: 創建文件夾
bool my_fs::make_dir(const char* name) {
    cout << "******************************** 創建新文件夾開始 ********************************" << endl;
    // 1. 創建inode
    Inode new_dir_inode(sp.get_new_inode(), false, 0, sp.get_new_sec());

    // 2. 寫回磁盤
    new_dir_inode.write_inode_back_to_disk(my_cache);

    // 3. 建立目錄結構
    sector_dir new_sec_dir;
    new_sec_dir.dirs[0].init(".", new_dir_inode.get_inode_num());
    new_sec_dir.dirs[1].init("..", cur_dir_node.get_inode_num());
    new_sec_dir.write_back_to_disk(my_cache, new_dir_inode.get_sec_beg());

    // 4. 當前目錄中添加一項
    int flag = false;
    for(int i = 2; i < 15; i++) {
        if(cur_dir.dirs[i].inode_num == 0) {
            cur_dir.dirs[i].init(name, new_dir_inode.get_inode_num());
            flag = true;
            break;
        }
    }
    if(flag) {
        // 5. 將修改的目錄寫回磁盤
        cur_dir.write_back_to_disk(my_cache, cur_dir_node.get_sec_beg());
    }

    return flag;
    cout << "******************************** 創建新文件夾結束 ********************************" << endl;
}

3.1 運行演示

4. touch命令

創建文件命令

// touch: 創建文件
bool my_fs::touch(const char* name) {
    cout << "******************************** 創建新文件開始 ********************************" << endl;
    // 1. 創建inode
    Inode new_file_inode(sp.get_new_inode(), true, 1, sp.get_new_sec());
    new_file_inode.write_inode_back_to_disk(my_cache);

    // 2. 當前目錄添加一項
    int flag = false;
    for(int i = 2; i < 15; i++) {
        if(cur_dir.dirs[i].inode_num == 0) {
            cur_dir.dirs[i].init(name, new_file_inode.get_inode_num());
            flag = true;
            break;
        }
    }

    if(flag) {
        cur_dir.write_back_to_disk(my_cache, new_file_inode.get_sec_beg());
    }

    return flag;

    cout << "******************************** 創建新文件結束 ********************************" << endl;
}

4.1 運行演示

5. rm

刪除文件或文件夾,如果是文件夾就遞歸地進入目錄然后調用自身,刪除所有文件。

// rm: 刪除文件或文件夾
bool my_fs::remove_dir(const char* name) {
    // 1. 在當前目錄下尋找這個文件或目錄
    int del_inode_num = -1;
    for(int i = 0; i < 15; i++) {
        if(strncmp(name, cur_dir.dirs[i].name, strlen(name)) == 0) {
            del_inode_num = cur_dir.dirs[i].inode_num;
            cout << "該文件或目錄inode號碼為:" << del_inode_num << endl;
            break;
        }
    }
    if(del_inode_num == -1) {
        cout << "不存在這個文件或目錄" << endl;
        return false;
    }

    // 2. 讀取這個inode節點
    Inode del_node;
    del_node.read_inode_from_disk(del_inode_num, my_cache);

    // cout << "inode對應數據扇區號碼為:" << del_node.get_sec_beg() - BLOCK_BEGIN / 512 << endl;
    // cout << "inode號為:" << del_node.get_inode_num() << endl;

    del_inode(del_node, cur_dir);

    return true;
}

// 根據刪除inode
bool my_fs::del_inode(Inode& node, sector_dir& del_dir) {
    cout << "delete inode, inode num為" << node.get_inode_num() << endl;
    if(node.get_type()) {
        // file, 釋放inode,inode對應的sec, 還要從dir中去除這個項目
        //  1.刪除sec中的這條記錄
        for(int i = 2; i < 15; i++) {
            if(del_dir.dirs[i].inode_num == node.get_inode_num()) {
                cout << "delate inode,刪除sector中對文件的記錄" << endl;
                memset(&del_dir.dirs[i], 0, sizeof(sector_dir_entry));
                del_dir.write_back_to_disk(my_cache, node.get_sec_beg());
                break;
            }
        }

        // 2. 釋放inode和對應的扇區
        sp.recv_sec(node.get_sec_beg() - BLOCK_BEGIN / 512);
        sp.recv_inode(node.get_inode_num());
    }
    else {
        // dir
        // 1.先刪除當前目錄對這個目錄的記錄
        for(int i = 0; i < 15; i++) {
            if(node.get_inode_num() == del_dir.dirs[i].inode_num) {
                cout << "delate inode,刪除sector中對文件的記錄" << endl;
                memset(&del_dir.dirs[i], 0, sizeof(sector_dir_entry));
                del_dir.write_back_to_disk(my_cache, node.get_sec_beg());
                break;
            }
        }
        // 2. 釋放這個目錄的inode和扇區
        sp.recv_sec(node.get_sec_beg() - BLOCK_BEGIN / 512);
        sp.recv_inode(node.get_inode_num());
        // 3. 切換到要刪除的目錄下
        Inode new_node;
        new_node = node;
        sector_dir new_dir;
        new_dir = del_dir;

        new_dir.read_dir_from_disk(my_cache, new_node.get_sec_beg());
        // 4. delete every files and directories recursively
        for(int i = 2; i < 15; i++) {
            if(new_dir.dirs[i].inode_num != 0) {
                new_node.read_inode_from_disk(new_dir.dirs[i].inode_num, my_cache);
                del_inode(new_node, new_dir);
            }
        }
    }
}

6. 將一個文件存入系統

將一張圖片存入系統,圖片如下:

// 將現成文件存入當前目錄中
bool my_fs::move_in() {
    /*
    *  move p1.png into my file system
    */
    // 1. get file size, compute needed block number, allocate block
    ifstream is(IMG, ifstream::binary);
    if(is) {
        is.seekg(0, is.end);
        int length = is.tellg();
        cout << "size of the file:" << length << " bytes" << endl;

        // 2. compute needed blocks
        int needed_block = length / 508;
        if(length % 508 != 0)
            needed_block++;
        int left = length % 508;
        cout << endl << "last node contain " << ((left == 0) ? 508 : left) << "bytes of data" << endl;
        cout << "need " << needed_block << " blocks to store data" << endl;

        Inode new_file_inode(sp.get_new_inode(), true, length, sp.get_new_sec());
        new_file_inode.write_inode_back_to_disk(my_cache);
        cout << "img inode info: #inode: " << new_file_inode.get_inode_num() << endl;
        cout << "file length " << new_file_inode.get_file_size() << endl;
        cout << " #sector begin: " << new_file_inode.get_sec_beg() << endl;

        // 3. add new entry in current directory
        int flag = false;
        for(int i = 2; i < 15; i++) {
            if(cur_dir.dirs[i].inode_num == 0) {
                cur_dir.dirs[i].init(IMG, new_file_inode.get_inode_num());
                flag = true;
                break;
            }
        }
        if(flag) {
            cur_dir.write_back_to_disk(my_cache, cur_dir_node.get_sec_beg());
        }

        // 4. store data into file system
        is.seekg(0, is.beg);
        char buffer[508];
        sector_file img_sectors[needed_block];
        int sec_numbers[needed_block];        
        sec_numbers[0] = new_file_inode.get_sec_beg();
        for(int i = 0; i < needed_block - 1; i++) {
            is.read(buffer, 508);
            sec_numbers[i+1] = sp.get_new_sec();
            memcpy(img_sectors[i].data, buffer, 508);
            img_sectors[i].next = sec_numbers[i+1];
            cout << "#next data sector:" << img_sectors[i].next << endl;
        }
        if(left == 0) {
            is.read(buffer, 508);
            memcpy(img_sectors[needed_block - 1].data, buffer, 508);
            img_sectors[needed_block - 1].next = 0;
        }
        else {
            is.read(buffer, left);
            memcpy(img_sectors[needed_block - 1].data, buffer, left);
            img_sectors[needed_block - 1].next = 0;
        }

        cout << "File pointer location" << is.tellg() << endl;
        cout << "file sectors info" << endl;
        cout << new_file_inode.get_sec_beg();
        for(int i = 0; i < needed_block; i++) {
            cout << " -> " << img_sectors[i].next;
        }
        cout << endl;
        for(int i = 0; i < needed_block; i++) {
            img_sectors[i].write_back_to_disk(my_cache, sec_numbers[i]);
        }        

        is.close();
    }

}
6.1 演示


7. mv_out

將圖片移出

// 如果當前目錄有指定文件,就將這個文件從文件系統中讀出
bool my_fs::move_out(string name) {
    /*
    * move p1.png out of my file system
    */

    // 1. search for inode number
    int inode_num = -1;
    for(int i = 0; i < 15; i++){
        if(strncmp(IMG, cur_dir.dirs[i].name, strlen(IMG)) == 0) {
            inode_num = cur_dir.dirs[i].inode_num;
            cout << "inode of p1.png: " << inode_num << endl;
            break;
        }
    }
    if(inode_num == -1) {
        cout << "pl.png not exists" << endl;
        return false;
    }
    Inode file_node;
    file_node.read_inode_from_disk(inode_num, my_cache);

    cout << "file info: #inode " << file_node.get_inode_num() << endl;
    cout << "file length: " << file_node.get_file_size() << endl;
    cout << "sec number: " << file_node.get_sec_num() << endl;
    cout << "sec_begin: " << file_node.get_sec_beg() << endl << endl;

    // 2. get data of p1.png from my file system
    sector_file data_sec;
    data_sec.read_dir_from_disk(my_cache, file_node.get_sec_beg());
    string file_name = name + ".png";
    fstream os(file_name.c_str(), fstream::in | fstream::out | fstream::app);

    char buffer[508];
    int next_sec = -1, left = file_node.get_file_size() % 508;
    if(os) {
        for(int i = 0; i < file_node.get_sec_num() ; i++) {
            if(i != file_node.get_sec_num() - 1 || left == 0) {
                next_sec = data_sec.next;
                memcpy(buffer, data_sec.data, 508);
                os.write(buffer, 508);
                data_sec.read_dir_from_disk(my_cache, next_sec);
            }
            else {
                memcpy(buffer, data_sec.data, left);
                os.write(buffer, left);
            }
            cout << "size of new file:" << os.tellg() << endl;
        }        
        os.close();
    }

    return true;
}

7.1 演示

指定文件名為 p1-1

再試一次,這次指定文件名為 p1-2

可以看到目錄下已經有了另外兩張圖片

需要完成的功能:

  1. 將宿主機的文件存入虛擬磁盤。
  2. 將虛擬磁盤的文件取出,放在宿主機。要求文件沒有損壞。
  3. 創建新目錄。
  4. 刪除已經存在的目錄。

需要編寫的兩個應用程序:

  1. initialize,用來初始化虛擬磁盤。
  2. testMyFileSystem,接受用戶輸入的文件操作命令,測試文件系統和API。
8.初始化磁盤
// 初始化文件系統
bool my_fs::format_file_system() {
    /*
    *  1. 格式化superblock
    */
    cout << "******************************** 初始化磁盤開始 ********************************" << endl;
    sp.init();

    /*
    * 2. 申請根目錄的一系列inode。包括根目錄
    *     根目錄下面的bin、etc、home、dev
    *     home目錄下面的tangrui目錄
    */
    Inode root_node(sp.get_new_inode(), false, 0, sp.get_new_sec());
    Inode bin_node(sp.get_new_inode(), false, 0, sp.get_new_sec());
    Inode etc_node(sp.get_new_inode(), false, 0, sp.get_new_sec());
    Inode home_node(sp.get_new_inode(), false, 0, sp.get_new_sec());
    Inode dev_node(sp.get_new_inode(), false, 0, sp.get_new_sec());
    Inode tangrui_node(sp.get_new_inode(), false, 0, sp.get_new_sec());
    cout << "1. 申請inode" << endl;
    /*
    *   3. 將inode寫回到磁盤中
    */
    root_node.write_inode_back_to_disk(my_cache);
    bin_node.write_inode_back_to_disk(my_cache);
    etc_node.write_inode_back_to_disk(my_cache);
    home_node.write_inode_back_to_disk(my_cache);
    dev_node.write_inode_back_to_disk(my_cache);
    tangrui_node.write_inode_back_to_disk(my_cache);
    cout << "2. inode寫回磁盤" << endl;
    /*
    *   4. 建立數據扇區中的目錄結構
    */
    sector_dir root_sec_dir;
    root_sec_dir.dirs[0].init(".", 1);
    root_sec_dir.dirs[1].init("..", 1);
    root_sec_dir.dirs[2].init("bin", bin_node.get_inode_num());
    root_sec_dir.dirs[3].init("etc", etc_node.get_inode_num());
    root_sec_dir.dirs[4].init("home", home_node.get_inode_num());
    root_sec_dir.dirs[5].init("dev", dev_node.get_inode_num());

    sector_dir bin_sec_dir;
    bin_sec_dir.dirs[0].init(".", bin_node.get_inode_num());
    bin_sec_dir.dirs[1].init("..", root_node.get_inode_num());

    sector_dir etc_sec_dir;
    etc_sec_dir.dirs[0].init(".", etc_node.get_inode_num());
    etc_sec_dir.dirs[1].init("..", root_node.get_inode_num());

    sector_dir home_sec_dir;
    home_sec_dir.dirs[0].init(".", home_node.get_inode_num());
    home_sec_dir.dirs[1].init("..", root_node.get_inode_num());
    home_sec_dir.dirs[2].init("tangrui", tangrui_node.get_inode_num());

    sector_dir dev_sec_dir;
    dev_sec_dir.dirs[0].init(".",  dev_node.get_inode_num());
    dev_sec_dir.dirs[1].init("..", root_node.get_inode_num());

    sector_dir tangrui_sec_dir;
    tangrui_sec_dir.dirs[0].init(".",  tangrui_node.get_inode_num());
    tangrui_sec_dir.dirs[1].init("..", home_node.get_inode_num());

    cout << "3. 目錄創建完成" << endl;
    /*
    *  5. 將文件夾對應的扇區寫入到磁盤中
    */
    root_sec_dir.write_back_to_disk(my_cache, root_node.get_sec_beg());
    bin_sec_dir.write_back_to_disk(my_cache, bin_node.get_sec_beg());
    etc_sec_dir.write_back_to_disk(my_cache, etc_node.get_sec_beg());
    home_sec_dir.write_back_to_disk(my_cache, home_node.get_sec_beg());
    dev_sec_dir.write_back_to_disk(my_cache, dev_node.get_sec_beg());
    tangrui_sec_dir.write_back_to_disk(my_cache, tangrui_node.get_sec_beg());
    cout << "4.目錄創建完成" << endl;
    /*
    *  6. 修改系統當前目錄位置為根目錄
    */
    cur_dir = root_sec_dir;
    cur_dir_node = root_node;
    cout << "******************************** 初始化磁盤結束 ********************************" << endl;
    return true;
}
8.1 演示

再次輸入ls命令就可以看到磁盤已經格式化成功

9. Makefile

filesystem : ./src/main.cpp control.o buffer.o superblock.o sector.o inode.o
	g++ -o ./bin/filesystem ./src/main.cpp ./obj/control.o ./obj/buffer.o \
	./obj/superblock.o ./obj/sector.o ./obj/inode.o

inode.o : ./src/inode.cpp
	g++ -c ./src/inode.cpp -o ./obj/inode.o

control.o : ./src/control.cpp
	g++ -c ./src/control.cpp -o ./obj/control.o

test : buffer.o test.cpp superblock.o
	g++ -o test test.cpp ./obj/buffer.o ./obj/superblock.o

sector.o : ./src/sector.cpp
	g++ -c ./src/sector.cpp -o ./obj/sector.o

buffer.o : ./src/buffer.cpp
	g++ -c ./src/buffer.cpp -o ./obj/buffer.o

superblock.o : ./src/superblock.cpp
	g++ -c ./src/superblock.cpp -o ./obj/superblock.o

clean :
	rm -f  ./bin/filesystem test ./obj/* ./bin/* p1-1.png

七、需要提交的材料

  1. Makefile 文件
  2. README.md 文件
  3. 項目設計報告


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM