Lab 9 file system

file system 的 Optional challenge 比較簡(jiǎn)單
前面的題解可以參考這篇博客: https://blog.csdn.net/LostUnravel/article/details/121431163

Support triple-indirect blocks.

首先這部分的代碼 其實(shí)和原要求中的第一題非常類似。只是要額外實(shí)現(xiàn)1層,這樣就可以支持更大的文件。
理論上最大可以支持256*256*256+256*256+256+10 個(gè)block, 一個(gè)block 是1KB的情況下,那么可以支持16.8G的文件。
遠(yuǎn)遠(yuǎn)超過(guò)了這個(gè)LAB文件系統(tǒng)的總?cè)萘俊?br> 根據(jù)param.h, 我們可以發(fā)現(xiàn)我們的文件系統(tǒng)是在200MB的大小。

#ifdef LAB_FS
#define FSSIZE       200000  // size of file system in blocks
#else

那么其實(shí)支持了3層的結(jié)構(gòu),其實(shí)第3層頁(yè)只要使用前2個(gè)條目即可。(256 * 256 * 3 < 200 MB

為了讓代碼更加簡(jiǎn)潔,來(lái)讓我們更容易的拓展到3層。我做了如下改動(dòng):

1708080722486.png

那么當(dāng)我們需要變?yōu)?層的時(shí)候,我們只要更改
#define INDIR_LAYERS 2這個(gè)變量即可,當(dāng)然要更改MAXFILE的大小去看到效果。

下面變更bmapitrunc 為遞歸寫法,來(lái)避免復(fù)制黏貼 重復(fù)的代碼邏輯。

static uint
bmap(struct inode *ip, uint bn)
{
  uint addr, *a;
  struct buf *bp;

  if(bn < NDIRECT){
    if((addr = ip->addrs[bn]) == 0){
      addr = balloc(ip->dev);
      if(addr == 0)
        return 0;
      ip->addrs[bn] = addr;
    }
    return addr;
  }
  bn -= NDIRECT;

  uint prev_base = 1;
  for (int in_layer = 0, base = NINDIRECT; in_layer < INDIR_LAYERS; in_layer++, base *= NINDIRECT) {
    if (bn < base) {
      uint idx = NDIRECT + in_layer;
      if((addr = ip->addrs[idx]) == 0){
        if ((ip->addrs[idx] = addr = balloc(ip->dev)) == 0)
          return 0;
      }
      for (int j = 0; j <= in_layer; j++, bn %= prev_base, prev_base /= NINDIRECT) {
        bp = bread(ip->dev, addr);
        a = (uint*)bp->data;
        idx = bn / prev_base;
        if((addr = a[idx]) == 0){
          if((addr = balloc(ip->dev))){
            a[idx] = addr;
            log_write(bp);
          }
        }
        brelse(bp);
      }
      return addr;
    }
    bn -= base;
    prev_base = base;
  }
  panic("bmap: out of range");
}

// Truncate inode (discard contents).
// Caller must hold ip->lock.
void 
turnc_recur(uint dev, uint *addr, int layer)
{
  struct buf *bp;
  uint *a;

  bp = bread(dev, *addr);
  a = (uint*)bp->data;
  int last_layer = (layer == 0);
  for(int j = 0; j < NINDIRECT; j++){
    if(!a[j]) continue;
    if (!last_layer) turnc_recur(dev, &a[j], layer - 1);
    else bfree(dev, a[j]);
  }
  brelse(bp);
  bfree(dev, *addr);
  *addr = 0;
}
void
itrunc(struct inode *ip)
{
  for(int i = 0; i < NDIRECT; i++){
    if(ip->addrs[i]){
      bfree(ip->dev, ip->addrs[i]);
      ip->addrs[i] = 0;
    }
  }
  for (int in_layer = 0, base = NINDIRECT; in_layer < INDIR_LAYERS; in_layer++, base *= NINDIRECT) {
    int idx = NDIRECT + in_layer;
    if(ip->addrs[idx]){
      turnc_recur(ip->dev, &ip->addrs[idx], in_layer);
    }
  }

  ip->size = 0;
  iupdate(ip);
}

到這里,我們進(jìn)行測(cè)試,確保LAB 9的用例 依然可以通過(guò)。


1708081135087.png

下面,我們只需要做一些小改動(dòng),就可以支持triple-indirect blocks.


1708081201612.png

下面進(jìn)行usertests -q測(cè)試,
我們會(huì)發(fā)現(xiàn)在test writebig:時(shí)會(huì)報(bào) panic: bget: no buffers

原因是因?yàn)槲覀冞@邊單個(gè)文件SIZE達(dá)到200MB,那么這里會(huì)用到valid bit的block 數(shù)為 (200000 / 8096) = 25
也就是這些block, 都會(huì)在bfree的時(shí)候 調(diào)用logwrite 寫進(jìn)log里,但是我們這里是1個(gè)unlock的txn, 所以這些LOG,會(huì)被bpin,這樣就造成這些block bit map 位置在45-69,25個(gè)完全被保留在bcache里

32 (root dir inode)
45 (bit map)
70 (root dir content)
33 (bigfile inode)
46 (bit map)
47 (bit map)
48 (bit map)
49 (bit map)
50 (bit map)
51 (bit map)
52 (bit map)
53 (bit map)
66910 (1st indirect block)
54 (bit map)
55 (bit map)
56 (bit map)
57 (bit map)
58 (bit map)
59 (bit map)
60 (bit map)
61 (bit map)
132704 (2rd indirect block)
62 (bit map)
63 (bit map)
64 (bit map)
65 (bit map)
66 (bit map)
67 (bit map)
68 (bit map)
196441 (3rd direct block)
alloc: 69 (bit map)

根據(jù)上述發(fā)現(xiàn),我們需要把log size 和 buf size 分別調(diào)大1.應(yīng)該就可以跑過(guò)測(cè)試。

#define LOGSIZE      31 // max data blocks in on-disk log
#define NBUF         31  // size of disk block cache

改大1格后測(cè)試順利通過(guò)?;谏鲜銮闆r,正確的做法是要把MAXOPBLOCKS改大

1708095573089.png

綜上,我們?cè)倥芤淮?code>usertests

1708096984710.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容