create doesn't touch parent director references

上级 7fe2e84a
...@@ -89,6 +89,7 @@ struct inode* dirlookup(struct inode*, char*); ...@@ -89,6 +89,7 @@ struct inode* dirlookup(struct inode*, char*);
struct inode* ialloc(u32, short); struct inode* ialloc(u32, short);
struct inode* namei(inode *cwd, const char*); struct inode* namei(inode *cwd, const char*);
void iput(struct inode*); void iput(struct inode*);
void iput(inode* ip, bool haveref);
struct inode* iget(u32 dev, u32 inum); struct inode* iget(u32 dev, u32 inum);
void ilock(struct inode*, int writer); void ilock(struct inode*, int writer);
void iunlockput(struct inode*); void iunlockput(struct inode*);
......
...@@ -476,6 +476,13 @@ iunlock(struct inode *ip) ...@@ -476,6 +476,13 @@ iunlock(struct inode *ip)
release(&ip->lock); release(&ip->lock);
} }
void
iput(inode* ip, bool haveref)
{
if (haveref)
iput(ip);
}
// Caller holds reference to unlocked ip. Drop reference. // Caller holds reference to unlocked ip. Drop reference.
void void
iput(struct inode *ip) iput(struct inode *ip)
......
...@@ -224,18 +224,23 @@ create(inode *cwd, const char *path, short type, short major, short minor) ...@@ -224,18 +224,23 @@ create(inode *cwd, const char *path, short type, short major, short minor)
{ {
struct inode *ip, *dp; struct inode *ip, *dp;
char name[DIRSIZ]; char name[DIRSIZ];
bool haveref = false;
mt_ascope ascope("%s(%d.%d,%s,%d,%d,%d)", mt_ascope ascope("%s(%d.%d,%s,%d,%d,%d)",
__func__, cwd->dev, cwd->inum, __func__, cwd->dev, cwd->inum,
path, type, major, minor); path, type, major, minor);
retry: retry:
if((dp = nameiparent(cwd, path, name)) == 0) {
scoped_gc_epoch e;
if((dp = __nameiparent(cwd, path, name, &haveref)) == 0)
return 0; return 0;
if(dp->type != T_DIR) if(dp->type != T_DIR)
panic("create"); panic("create");
if((ip = dirlookup(dp, name)) != 0){ if((ip = dirlookup(dp, name)) != 0){
iput(dp); iput(dp, haveref);
ilock(ip, 1); ilock(ip, 1);
if(type == T_FILE && ip->type == T_FILE) if(type == T_FILE && ip->type == T_FILE)
return ip; return ip;
...@@ -265,12 +270,19 @@ create(inode *cwd, const char *path, short type, short major, short minor) ...@@ -265,12 +270,19 @@ create(inode *cwd, const char *path, short type, short major, short minor)
// create race // create race
ip->unlink(); ip->unlink();
iunlockput(ip); iunlockput(ip);
iput(dp); iput(dp, haveref);
goto retry; goto retry;
} }
if (!dp->valid()) {
// XXX(sbw) we need to undo everything we just did
// (at least all the modifications to dp) and retry.
panic("create: race");
}
}
//nc_insert(dp, name, ip); //nc_insert(dp, name, ip);
iput(dp); iput(dp, haveref);
return ip; return ip;
} }
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论