aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog3
-rw-r--r--kernel/file.c9
2 files changed, 7 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index fe3bfdb..ed6a999 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -17,6 +17,9 @@
will allow non root user to specify the 'allow_other' mount option
('-x' option of fusermount)
+ * Fix deadlock between page writeback completion and truncate
+ (bug found by Valient Gough with the fsx-linux utility)
+
2004-07-01 Miklos Szeredi <mszeredi@inf.bme.hu>
* Change passing fuse include dir to 2.6 kernel make system more
diff --git a/kernel/file.c b/kernel/file.c
index d7b61ea..0b75637 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -480,7 +480,6 @@ static void write_buffer_end(struct fuse_conn *fc, struct fuse_req *req)
req->out.h.error = -EPROTO;
}
- lock_page(page);
if (req->out.h.error) {
SetPageError(page);
if (req->out.h.error == -ENOSPC)
@@ -490,7 +489,6 @@ static void write_buffer_end(struct fuse_conn *fc, struct fuse_req *req)
}
end_page_writeback(page);
kunmap(page);
- unlock_page(page);
fuse_put_request(fc, req);
}
@@ -535,10 +533,11 @@ static int fuse_writepage(struct page *page, struct writeback_control *wbc)
/* FIXME: check sync_mode, and wait for previous writes (or
signal userspace to do this) */
if (wbc->nonblocking) {
+ SetPageWriteback(page);
err = write_buffer_nonblock(inode, page, 0, count);
- if (!err)
- SetPageWriteback(page);
- else if (err == -EWOULDBLOCK) {
+ if (err)
+ ClearPageWriteback(page);
+ if (err == -EWOULDBLOCK) {
__set_page_dirty_nobuffers(page);
err = 0;
}