From 5053dd6a6d2b481bfcddbd91bacc885b9f0e0ff5 Mon Sep 17 00:00:00 2001 From: Robert Morris Date: Mon, 15 Aug 2011 12:44:20 -0400 Subject: avoid deadlock by calling begin_trans() before locking any inodes --- sysfile.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'sysfile.c') diff --git a/sysfile.c b/sysfile.c index ca54013..c9d3594 100644 --- a/sysfile.c +++ b/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"); -- cgit v1.2.3