Rejigger some inode code to make it easier to fix some bugs.

上级 aa7051f5
...@@ -59,6 +59,8 @@ struct inode : public rcu_freed { ...@@ -59,6 +59,8 @@ struct inode : public rcu_freed {
u32 size; u32 size;
u32 addrs[NDIRECT+1]; u32 addrs[NDIRECT+1];
static inode* alloc(u32 dev, u32 inum);
void init();
inode(); inode();
~inode(); ~inode();
virtual void do_gc() { delete this; } virtual void do_gc() { delete this; }
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#define min(a, b) ((a) < (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b))
static void itrunc(struct inode*); static void itrunc(struct inode*);
static inode* the_root;
// Read the super block. // Read the super block.
static void static void
...@@ -157,14 +158,14 @@ ino_hash(const pair<u32, u32> &p) ...@@ -157,14 +158,14 @@ ino_hash(const pair<u32, u32> &p)
static xns<pair<u32, u32>, inode*, ino_hash> *ins; static xns<pair<u32, u32>, inode*, ino_hash> *ins;
static struct { atomic<u32> x __mpalign__; } icache_free[NCPU];
void void
initinode(void) initinode(void)
{ {
ins = new xns<pair<u32, u32>, inode*, ino_hash>(false); ins = new xns<pair<u32, u32>, inode*, ino_hash>(false);
for (int i = 0; i < NCPU; i++) the_root = inode::alloc(ROOTDEV, ROOTINO);
icache_free[i].x = NINODE; if (ins->insert(make_pair(the_root->dev, the_root->inum), the_root) < 0)
panic("initinode: insert the_root failed");
the_root->init();
} }
//PAGEBREAK! //PAGEBREAK!
...@@ -261,6 +262,39 @@ iget(u32 dev, u32 inum) ...@@ -261,6 +262,39 @@ iget(u32 dev, u32 inum)
return ip; return ip;
} }
inode*
inode::alloc(u32 dev, u32 inum)
{
inode* ip = new inode();
if (ip == nullptr)
return nullptr;
ip->dev = dev;
ip->inum = inum;
// XXX(sbw)
ip->ref = 0;
snprintf(ip->lockname, sizeof(ip->lockname), "cv:ino:%d", ip->inum);
initlock(&ip->lock, ip->lockname+3, LOCKSTAT_FS);
initcondvar(&ip->cv, ip->lockname);
return ip;
}
void
inode::init(void)
{
struct buf *bp = bread(dev, IBLOCK(inum), 0);
struct dinode *dip = (struct dinode*)bp->data + inum%IPB;
type = dip->type;
major = dip->major;
minor = dip->minor;
nlink = dip->nlink;
size = dip->size;
gen = dip->gen;
memmove(addrs, dip->addrs, sizeof(addrs));
brelse(bp, 0);
flags |= I_VALID;
}
struct inode* struct inode*
igetnoref(u32 dev, u32 inum) igetnoref(u32 dev, u32 inum)
{ {
...@@ -281,34 +315,21 @@ igetnoref(u32 dev, u32 inum) ...@@ -281,34 +315,21 @@ igetnoref(u32 dev, u32 inum)
} }
// Allocate fresh inode cache slot. // Allocate fresh inode cache slot.
struct inode *ip = new inode(); struct inode *ip = inode::alloc(dev, inum);
ip->dev = dev; if (ip == nullptr)
ip->inum = inum; panic("igetnoref: should throw_bad_alloc()");
ip->ref = 0;
// Lock the inode
ip->flags = I_BUSYR | I_BUSYW; ip->flags = I_BUSYR | I_BUSYW;
ip->readbusy = 1; ip->readbusy = 1;
snprintf(ip->lockname, sizeof(ip->lockname), "cv:ino:%d", ip->inum);
initlock(&ip->lock, ip->lockname+3, LOCKSTAT_FS);
initcondvar(&ip->cv, ip->lockname);
if (ins->insert(make_pair(ip->dev, ip->inum), ip) < 0) { if (ins->insert(make_pair(ip->dev, ip->inum), ip) < 0) {
gc_delayed(ip); gc_delayed(ip);
goto retry; goto retry;
} }
ip->init();
struct buf *bp = bread(ip->dev, IBLOCK(ip->inum), 0);
struct dinode *dip = (struct dinode*)bp->data + ip->inum%IPB;
ip->type = dip->type;
ip->major = dip->major;
ip->minor = dip->minor;
ip->nlink = dip->nlink;
ip->size = dip->size;
ip->gen = dip->gen;
memmove(ip->addrs, dip->addrs, sizeof(ip->addrs));
brelse(bp, 0);
ip->flags |= I_VALID;
iunlock(ip); iunlock(ip);
return ip; return ip;
} }
...@@ -401,7 +422,6 @@ iput(struct inode *ip) ...@@ -401,7 +422,6 @@ iput(struct inode *ip)
ins->remove(make_pair(ip->dev, ip->inum), &ip); ins->remove(make_pair(ip->dev, ip->inum), &ip);
gc_delayed(ip); gc_delayed(ip);
icache_free[mycpu()->id].x++;
return; return;
} }
release(&ip->lock); release(&ip->lock);
...@@ -751,7 +771,7 @@ namex(inode *cwd, const char *path, int nameiparent, char *name) ...@@ -751,7 +771,7 @@ namex(inode *cwd, const char *path, int nameiparent, char *name)
scoped_gc_epoch e; scoped_gc_epoch e;
if(*path == '/') if(*path == '/')
ip = igetnoref(ROOTDEV, ROOTINO); ip = the_root;
else else
ip = cwd; ip = cwd;
drop_ref = false; drop_ref = false;
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论