aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--kernel/dir.c9
-rw-r--r--kernel/file.c24
-rw-r--r--kernel/fuse_i.h5
4 files changed, 32 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index ed6a999..0d7b993 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2004-07-04 Miklos Szeredi <mszeredi@inf.bme.hu>
+
+ * Fix race between truncate and writepage (fsx-linux now runs
+ without error)
+
2004-07-02 Miklos Szeredi <mszeredi@inf.bme.hu>
* Fix kernel hang on mkfifo under 2.4 kernels (spotted and patch
diff --git a/kernel/dir.c b/kernel/dir.c
index aa31295..f0a5aa6 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -724,11 +724,16 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
{
struct inode *inode = entry->d_inode;
struct fuse_conn *fc = INO_FC(inode);
- struct fuse_req *req = fuse_get_request(fc);
+ struct fuse_req *req;
struct fuse_setattr_in inarg;
struct fuse_attr_out outarg;
int err;
-
+
+ /* FIXME: need to fix race between truncate and writepage */
+ if (attr->ia_valid & ATTR_SIZE)
+ fuse_sync_inode(inode);
+
+ req = fuse_get_request(fc);
if (!req)
return -ERESTARTSYS;
diff --git a/kernel/file.c b/kernel/file.c
index 0b75637..4a800e8 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -17,13 +17,6 @@
#ifndef KERNEL_2_6
#define PageUptodate(page) Page_Uptodate(page)
-#ifndef filemap_fdatawrite
-#ifndef NO_MM
-#define filemap_fdatawrite filemap_fdatasync
-#else
-#define filemap_fdatawrite do {} while (0)
-#endif
-#endif
#endif
static int fuse_open(struct inode *inode, struct file *file)
@@ -85,16 +78,29 @@ static int fuse_open(struct inode *inode, struct file *file)
return err;
}
+void fuse_sync_inode(struct inode *inode)
+{
+#ifdef KERNEL_2_6
+ filemap_fdatawrite(inode->i_mapping);
+ filemap_fdatawait(inode->i_mapping);
+#else
+#ifndef NO_MM
+ filemap_fdatasync(inode->i_mapping);
+ filemap_fdatawait(inode->i_mapping);
+#endif
+#endif
+}
+
static int fuse_release(struct inode *inode, struct file *file)
{
struct fuse_conn *fc = INO_FC(inode);
struct fuse_open_in *inarg;
struct fuse_req *req = file->private_data;
+ down(&inode->i_sem);
if (file->f_mode & FMODE_WRITE)
- filemap_fdatawrite(inode->i_mapping);
+ fuse_sync_inode(inode);
- down(&inode->i_sem);
inarg = &req->misc.open_in;
inarg->flags = file->f_flags & ~O_EXCL;
req->in.h.opcode = FUSE_RELEASE;
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
index 59bc0bc..f0c1171 100644
--- a/kernel/fuse_i.h
+++ b/kernel/fuse_i.h
@@ -328,6 +328,11 @@ void request_send_nonblock(struct fuse_conn *fc, struct fuse_req *req,
*/
int fuse_do_getattr(struct inode *inode);
+/**
+ * Write dirty pages
+ */
+void fuse_sync_inode(struct inode *inode);
+
/*
* Local Variables:
* indent-tabs-mode: t