avoid deadlock by calling begin_trans() before locking any inodes
This commit is contained in:
parent
c95ce31c59
commit
5053dd6a6d
5 changed files with 66 additions and 15 deletions
14
sysfile.c
14
sysfile.c
|
|
@ -116,14 +116,16 @@ sys_link(void)
|
|||
return -1;
|
||||
if((ip = namei(old)) == 0)
|
||||
return -1;
|
||||
|
||||
begin_trans();
|
||||
|
||||
ilock(ip);
|
||||
if(ip->type == T_DIR){
|
||||
iunlockput(ip);
|
||||
commit_trans();
|
||||
return -1;
|
||||
}
|
||||
|
||||
begin_trans();
|
||||
|
||||
ip->nlink++;
|
||||
iupdate(ip);
|
||||
iunlock(ip);
|
||||
|
|
@ -180,16 +182,21 @@ sys_unlink(void)
|
|||
return -1;
|
||||
if((dp = nameiparent(path, name)) == 0)
|
||||
return -1;
|
||||
|
||||
begin_trans();
|
||||
|
||||
ilock(dp);
|
||||
|
||||
// Cannot unlink "." or "..".
|
||||
if(namecmp(name, ".") == 0 || namecmp(name, "..") == 0){
|
||||
iunlockput(dp);
|
||||
commit_trans();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ip = dirlookup(dp, name, &off)) == 0){
|
||||
iunlockput(dp);
|
||||
commit_trans();
|
||||
return -1;
|
||||
}
|
||||
ilock(ip);
|
||||
|
|
@ -199,11 +206,10 @@ sys_unlink(void)
|
|||
if(ip->type == T_DIR && !isdirempty(ip)){
|
||||
iunlockput(ip);
|
||||
iunlockput(dp);
|
||||
commit_trans();
|
||||
return -1;
|
||||
}
|
||||
|
||||
begin_trans();
|
||||
|
||||
memset(&de, 0, sizeof(de));
|
||||
if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
|
||||
panic("unlink: writei");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue