xv6 lab9

Thaudmin發表於2024-12-09

比較簡單的一項實驗
大索引(bigfile):
xv6的單檔案索引有13個,其中只有一個二級索引,檔案最大塊數目是256+12 = 268塊。
現在要給檔案索引改成一個二級帶一個三級索引,最大塊數目就是11+256+256*256 = 65803塊,可以容納下很大的檔案了。
先在fs.h中進行相應的更改:

...

define FSMAGIC 0x10203040

define NDIRECT 11

define NDDIRECT 12

define NINDIRECT (BSIZE / sizeof(uint))

define NINDDIRECT NINDIRECT * NINDIRECT

define MAXFILE (NDIRECT + NINDIRECT + NINDDIRECT)

// On-disk inode structure
struct dinode {

...

再在bmap中進行修改,模仿bmap中原有的索引查詢方式進行索引查詢即可:

...
    brelse(bp);
    return addr;
  }
/*-----------------修改線-----------------*/
  bn -= NINDIRECT;
  if (bn < NINDDIRECT) {
    // doubly-indirect block
    if((addr = ip->addrs[NDDIRECT]) == 0)
      ip->addrs[NDDIRECT] = addr = balloc(ip->dev);
    bp = bread(ip->dev, addr);
    a = (uint*)bp->data;
    if((addr = a[bn / NINDIRECT]) == 0){
      a[bn / NINDIRECT] = addr = balloc(ip->dev);
      log_write(bp);
    }
    brelse(bp);
    cp = bread(ip->dev, addr);
    b = (uint*)cp->data;
    if((addr = b[bn % NINDIRECT]) == 0){
      b[bn % NINDIRECT] = addr = balloc(ip->dev);
      log_write(cp);
    }
    brelse(cp);
    return addr;
  }

/*-----------------修改線-----------------*/

  panic("bmap: out of range");
}
```cpp


這裡因為bigfile太大了,make grade會超時但是單項測試是可以正常無阻塞透過的。

itrunc也類似

/-----------------修改線-----------------/
if(ip->addrs[NDDIRECT]){
bp = bread(ip->dev, ip->addrs[NDDIRECT]);
a = (uint)bp->data;
for(i = 0; i < NINDIRECT; i++){
// doubly-indirect block
if(a[i]) {
cp = bread(ip->dev, a[i]);
b = (uint
)cp->data;
for(j = 0; j < NINDIRECT; j++){
if(b[j])
bfree(ip->dev, b[j]);
}
brelse(cp);
bfree(ip->dev, a[i]);
}
}
brelse(bp);
bfree(ip->dev, ip->addrs[NDDIRECT]);
ip->addrs[NDDIRECT] = 0;
}

/-----------------修改線-----------------/
ip->size = 0;
iupdate(ip);


uint64
sys_symlink(void){
char target[MAXPATH], path[MAXPATH];
struct inode *ip;

if(argstr(0, target, MAXPATH) < 0 || argstr(1, path, MAXPATH) < 0)
return -1;

begin_op();
if((ip = create(path, T_SYMLINK, 0, 0)) == 0){
end_op();
return -1;
}
if(writei(ip, 0, (uint64)target, 0, strlen(target) + 1) <= 0)
panic("sys_symlink: writei");
iunlockput(ip);
end_op();
return 0;
}

symlink系統呼叫如上。

並在sys_open中進行相應的查詢:

ilock(ip);

/-----------------修改線-----------------/
if (!(omode & O_NOFOLLOW)) {
int depth = 10;
for (; ip->type == T_SYMLINK && depth; depth--) {
if((ip->size > MAXPATH) || (readi(ip, 0, (uint64)path, 0, ip->size) != ip->size)){
iunlockput(ip);
end_op();
return -1;
}
iunlockput(ip);

    if((ip = namei(path)) == 0){
      end_op();
      return -1;
    }
    ilock(ip);
  }
  if(depth == 0) {
    iunlockput(ip);
    end_op();
    return -1;
  }
}

/-----------------修改線-----------------/
if (ip->type == T_DIR && omode != O_RDONLY){
iunlockput(ip);
end_op();
return -1;
}


執行OK。