summaryrefslogtreecommitdiff
path: root/file.c
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2011-08-12 09:25:39 -0400
committerRobert Morris <[email protected]>2011-08-12 09:25:39 -0400
commit2e59046362f532748711b9acaceee1cda969cc50 (patch)
tree82ab693a2fa6021d445915c169354b6833262d24 /file.c
parentbd71a45046eb13797284216c43353b9b6c92f18c (diff)
downloadxv6-labs-2e59046362f532748711b9acaceee1cda969cc50.tar.gz
xv6-labs-2e59046362f532748711b9acaceee1cda969cc50.tar.bz2
xv6-labs-2e59046362f532748711b9acaceee1cda969cc50.zip
log write() data
usertest for big write()s push begin_trans/commit_trans down into syscalls
Diffstat (limited to 'file.c')
-rw-r--r--file.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/file.c b/file.c
index e10b824..7101a50 100644
--- a/file.c
+++ b/file.c
@@ -67,8 +67,11 @@ fileclose(struct file *f)
if(ff.type == FD_PIPE)
pipeclose(ff.pipe, ff.writable);
- else if(ff.type == FD_INODE)
+ else if(ff.type == FD_INODE){
+ begin_trans();
iput(ff.ip);
+ commit_trans();
+ }
}
// Get metadata about file f.
@@ -116,10 +119,30 @@ filewrite(struct file *f, char *addr, int n)
return pipewrite(f->pipe, addr, n);
if(f->type == FD_INODE){
ilock(f->ip);
- if((r = writei(f->ip, addr, f->off, n)) > 0)
+ // write a few blocks at a time to avoid exceeding
+ // the maximum log transaction size, including
+ // i-node, indirect block, allocation blocks,
+ // and 2 blocks of slop for non-aligned writes.
+ // this really belongs lower down, since writei()
+ // might be writing a device like the console.
+ int max = ((LOGSIZE-1-1-2) / 2) * 512;
+ int i = 0;
+ while(i < n){
+ int n1 = n - i;
+ if(n1 > max)
+ n1 = max;
+ begin_trans();
+ r = writei(f->ip, addr + i, f->off, n1);
+ commit_trans();
+ if(r < 0)
+ break;
+ if(r != n1)
+ panic("short filewrite");
f->off += r;
+ i += r;
+ }
iunlock(f->ip);
- return r;
+ return i == n ? n : -1;
}
panic("filewrite");
}