diff options
author | Robert Morris <[email protected]> | 2011-08-15 12:44:20 -0400 |
---|---|---|
committer | Robert Morris <[email protected]> | 2011-08-15 12:44:20 -0400 |
commit | 5053dd6a6d2b481bfcddbd91bacc885b9f0e0ff5 (patch) | |
tree | ca7d000f9996082466bdfe8c7a0c9667341f2dfa /sysfile.c | |
parent | c95ce31c5978bd43e1f0d34e51a4e3d7bcc41b14 (diff) | |
download | xv6-labs-5053dd6a6d2b481bfcddbd91bacc885b9f0e0ff5.tar.gz xv6-labs-5053dd6a6d2b481bfcddbd91bacc885b9f0e0ff5.tar.bz2 xv6-labs-5053dd6a6d2b481bfcddbd91bacc885b9f0e0ff5.zip |
avoid deadlock by calling begin_trans() before locking any inodes
Diffstat (limited to 'sysfile.c')
-rw-r--r-- | sysfile.c | 14 |
1 files changed, 10 insertions, 4 deletions
@@ -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"); |