比較簡單的一項實驗
大索引(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。