The dumbest scalable inode allocator.

Split the inode space into per-cpu spaces of size IPB that start at the begining of a block. Block awareness is important to avoid contention on blocks themselves when allocating or freeing an inode and updating on-disk structures. That is, I don't want to make bio scalable.
上级 a16be914
...@@ -166,6 +166,17 @@ initinode(void) ...@@ -166,6 +166,17 @@ initinode(void)
if (ins->insert(make_pair(the_root->dev, the_root->inum), the_root) < 0) if (ins->insert(make_pair(the_root->dev, the_root->inum), the_root) < 0)
panic("initinode: insert the_root failed"); panic("initinode: insert the_root failed");
the_root->init(); the_root->init();
if (VERBOSE) {
struct superblock sb;
u64 blocks;
readsb(ROOTDEV, &sb);
blocks = sb.ninodes/IPB;
cprintf("initinode: %lu inode blocks (%lu / core)\n",
blocks, blocks/NCPU);
}
} }
//PAGEBREAK! //PAGEBREAK!
...@@ -174,33 +185,36 @@ initinode(void) ...@@ -174,33 +185,36 @@ initinode(void)
struct inode* struct inode*
ialloc(u32 dev, short type) ialloc(u32 dev, short type)
{ {
int inum;
struct buf *bp; struct buf *bp;
struct dinode *dip; struct dinode *dip;
struct superblock sb; struct superblock sb;
readsb(dev, &sb); readsb(dev, &sb);
for(inum = 1; inum < sb.ninodes; inum++){ // loop over inode blocks for (int k = mycpuid()*IPB; k < sb.ninodes; k += (NCPU*IPB)) {
bp = bread(dev, IBLOCK(inum), 0); for(int inum = k; inum < k+IPB && inum < sb.ninodes; inum++){
dip = (struct dinode*)bp->data + inum%IPB; if (inum == 0)
int seemsfree = (dip->type == 0); continue;
brelse(bp, 0); bp = bread(dev, IBLOCK(inum), 0);
if(seemsfree){ dip = (struct dinode*)bp->data + inum%IPB;
// maybe this inode is free. look at it via the int seemsfree = (dip->type == 0);
// inode cache to make sure. brelse(bp, 0);
struct inode *ip = iget(dev, inum); if(seemsfree){
assert(ip->valid()); // maybe this inode is free. look at it via the
ilock(ip, 1); // inode cache to make sure.
if(ip->type == 0){ struct inode *ip = iget(dev, inum);
ip->type = type; assert(ip->valid());
ip->gen += 1; ilock(ip, 1);
if(ip->nlink() || ip->size || ip->addrs[0]) if(ip->type == 0){
panic("ialloc not zeroed"); ip->type = type;
iupdate(ip); ip->gen += 1;
return ip; if(ip->nlink() || ip->size || ip->addrs[0])
panic("ialloc not zeroed");
iupdate(ip);
return ip;
}
iunlockput(ip);
//cprintf("ialloc oops %d\n", inum); // XXX harmless
} }
iunlockput(ip);
//cprintf("ialloc oops %d\n", inum); // XXX harmless
} }
} }
cprintf("ialloc: 0/%u inodes\n", sb.ninodes); cprintf("ialloc: 0/%u inodes\n", sb.ninodes);
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论