__nameiparent, __namei, and __namex don't acquire refs

上级 cc770209
...@@ -102,6 +102,9 @@ struct inode* nameiparent(inode *cwd, const char*, char*); ...@@ -102,6 +102,9 @@ struct inode* nameiparent(inode *cwd, const char*, char*);
int dirlink(struct inode*, const char*, u32); int dirlink(struct inode*, const char*, u32);
void dir_init(struct inode *dp); void dir_init(struct inode *dp);
void dir_flush(struct inode *dp); void dir_flush(struct inode *dp);
inode* __nameiparent(inode *cwd, const char *path,
char *name, bool* haveref);
inode* __namei(inode *cwd, const char *path, bool* haveref);
// futex.cc // futex.cc
typedef u64* futexkey_t; typedef u64* futexkey_t;
......
...@@ -318,12 +318,14 @@ iget(u32 dev, u32 inum) ...@@ -318,12 +318,14 @@ iget(u32 dev, u32 inum)
bool haveref; bool haveref;
inode* ip; inode* ip;
scoped_gc_epoch e;
retry: retry:
ip = __iget(dev, inum, &haveref); {
if (!haveref) scoped_gc_epoch e;
if (!ip->tryinc()) ip = __iget(dev, inum, &haveref);
goto retry; if (!haveref)
if (!ip->tryinc())
goto retry;
}
return ip; return ip;
} }
...@@ -828,13 +830,16 @@ skipelem(const char **rpath, char *name) ...@@ -828,13 +830,16 @@ skipelem(const char **rpath, char *name)
// If parent != 0, return the inode for the parent and copy the final // If parent != 0, return the inode for the parent and copy the final
// path element into name, which must have room for DIRSIZ bytes. // path element into name, which must have room for DIRSIZ bytes.
static struct inode* static struct inode*
namex(inode *cwd, const char *path, int nameiparent, char *name) __namex(inode *cwd, const char *path, int nameiparent, char *name,
bool* retref)
{ {
// Assumes caller is holding a gc_epoch
struct inode *ip, *next; struct inode *ip, *next;
bool haveref; bool haveref;
int r; int r;
scoped_gc_epoch e;
if(*path == '/') if(*path == '/')
ip = the_root; ip = the_root;
else else
...@@ -858,8 +863,7 @@ namex(inode *cwd, const char *path, int nameiparent, char *name) ...@@ -858,8 +863,7 @@ namex(inode *cwd, const char *path, int nameiparent, char *name)
return 0; return 0;
if(nameiparent && *path == '\0'){ if(nameiparent && *path == '\0'){
// Stop one level early. // Stop one level early.
if (!haveref) *retref = haveref;
idup(ip);
return ip; return ip;
} }
...@@ -883,23 +887,58 @@ namex(inode *cwd, const char *path, int nameiparent, char *name) ...@@ -883,23 +887,58 @@ namex(inode *cwd, const char *path, int nameiparent, char *name)
// mtreadavar("inode:%x.%x", ip->dev, ip->inum); // mtreadavar("inode:%x.%x", ip->dev, ip->inum);
mtwriteavar("inode:%x.%x", ip->dev, ip->inum); mtwriteavar("inode:%x.%x", ip->dev, ip->inum);
if (!haveref) *retref = haveref;
idup(ip);
return ip; return ip;
} }
struct inode* inode*
__namei(inode *cwd, const char *path, bool* haveref)
{
// Assumes caller is holding a gc_epoch
char name[DIRSIZ];
return __namex(cwd, path, 0, name, haveref);
}
inode*
namei(inode *cwd, const char *path) namei(inode *cwd, const char *path)
{ {
char name[DIRSIZ]; char name[DIRSIZ];
struct inode *r = namex(cwd, path, 0, name); bool haveref;
//cprintf("namei: %s -> %x (%d)\n", path, r, r?r->inum:0);
return r; inode* ip;
retry:
{
scoped_gc_epoch e;
ip = __namex(cwd, path, 0, name, &haveref);
if (ip != nullptr && !haveref)
if (!ip->tryinc())
goto retry;
}
return ip;
} }
struct inode* inode*
nameiparent(inode *cwd, const char *path, char *name) __nameiparent(inode *cwd, const char *path, char *name, bool* haveref)
{ {
return namex(cwd, path, 1, name); // Assumes caller is holding a gc_epoch
return __namex(cwd, path, 1, name, haveref);
} }
inode*
nameiparent(inode *cwd, const char *path, char *name)
{
bool haveref;
inode* ip;
retry:
{
scoped_gc_epoch e;
ip = __namex(cwd, path, 1, name, &haveref);
if (ip != nullptr && !haveref)
if (!ip->tryinc())
goto retry;
}
return ip;
}
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论