在这次作业中我们将实现增大xv6文件大小的最大值。目前xv6文件被限制拥有140sectors(扇区),这是由于1个xv6的inode含有12直接块序号和1个间接块序号(指向128个块序号),故此总共12+128=140。而我们的任务就是改变实现支持2层间接块序号(每个含有128个原先的间接块序号),导致总共拥有11+128+128*128=16523个扇区,大约8.5M大小。
修改mkfs.c文件,以使文件系统支持更大的文件大小。
int nblocks = 21049;
int nlog = LOGSIZE;
int ninodes = 200;
int size = 21113
原先inode的结构图:
我们将使address11变成原先的间接块,而原先的address间接块变成2层间接块。具体实现可以仿照原有的代码。
static uint
bmap(struct inode *ip, uint bn)
{
uint addr, *a, *b;
struct buf *bp, *bnp;
if(bn < NDIRECT){
if((addr = ip->addrs[bn]) == 0)
ip->addrs[bn] = addr = balloc(ip->dev);
return addr;
}
bn -= NDIRECT;
if(bn < NINDIRECT){
// Load indirect block, allocating if necessary.
if((addr = ip->addrs[NDIRECT]) == 0)
ip->addrs[NDIRECT] = addr = balloc(ip->dev);
bp = bread(ip->dev, addr);
a = (uint*)bp->data;
if((addr = a[bn]) == 0){
a[bn] = addr = balloc(ip->dev);
log_write(bp);
}
brelse(bp);
return addr;
}
bn -= NINDIRECT;
if(bn < NDBINDIRECT){
// Load single indirect block, allocating if necessary.
if((addr = ip->addrs[NDIRECT+1]) == 0)
ip->addrs[NDIRECT+1] = 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);
}
// Load double indirect block, allocating if necessary.
bnp = bread(ip->dev, addr);
b = (uint*)bnp->data;
if ((addr = b[bn%NINDIRECT]) == 0){
b[bn%NINDIRECT] = addr = balloc(ip->dev);
log_write(bnp);
}
brelse(bnp);
brelse(bp);
return addr;
}
}
跟分页机制差不多,判断块序号落在哪个区域,若在直接块序号(0-10)则直接获取访问;若在1层间接块,获取1层间接块的内容,然后再从中得到序号对应的具体物理块。