summaryrefslogtreecommitdiff
path: root/file.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2011-08-15 12:44:20 -0400
committerRobert Morris <[email protected]>2011-08-15 12:44:20 -0400
commit5053dd6a6d2b481bfcddbd91bacc885b9f0e0ff5 (patch)
treeca7d000f9996082466bdfe8c7a0c9667341f2dfa /file.c
parentc95ce31c5978bd43e1f0d34e51a4e3d7bcc41b14 (diff)
downloadxv6-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 'file.c')
-rw-r--r--file.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/file.c b/file.c
index 7101a50..f8a14ad 100644
--- a/file.c
+++ b/file.c
@@ -118,7 +118,6 @@ filewrite(struct file *f, char *addr, int n)
if(f->type == FD_PIPE)
return pipewrite(f->pipe, addr, n);
if(f->type == FD_INODE){
- ilock(f->ip);
// write a few blocks at a time to avoid exceeding
// the maximum log transaction size, including
// i-node, indirect block, allocation blocks,
@@ -131,9 +130,13 @@ filewrite(struct file *f, char *addr, int n)
int n1 = n - i;
if(n1 > max)
n1 = max;
+
begin_trans();
+ ilock(f->ip);
r = writei(f->ip, addr + i, f->off, n1);
+ iunlock(f->ip);
commit_trans();
+
if(r < 0)
break;
if(r != n1)
@@ -141,7 +144,6 @@ filewrite(struct file *f, char *addr, int n)
f->off += r;
i += r;
}
- iunlock(f->ip);
return i == n ? n : -1;
}
panic("filewrite");