summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2004-07-04 21:23:11 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2004-07-04 21:23:11 +0000
commitca47dd6b7a61b970e0c7453c30317879fc8bff6e (patch)
tree3778b960409008187a56a788e60b4bb920f01d10
parent8adcd561f351a9fccaf10dc82dceaeb925358b5b (diff)
downloadfuse-ca47dd6b7a61b970e0c7453c30317879fc8bff6e.tar.gz
fix
-rw-r--r--ChangeLog5
-rw-r--r--kernel/dir.c4
-rw-r--r--kernel/file.c22
-rw-r--r--kernel/fuse_i.h5
4 files changed, 28 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 2940f60..f38ce27 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 d0edd3b..6306795 100644
--- a/kernel/dir.c
+++ b/kernel/dir.c
@@ -611,6 +611,10 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
struct fuse_setattr_in inarg;
struct fuse_setattr_out outarg;
+ /* FIXME: need to fix race between truncate and writepage */
+ if (attr->ia_valid & ATTR_SIZE)
+ fuse_sync_inode(inode);
+
memset(&inarg, 0, sizeof(inarg));
inarg.valid = iattr_to_fattr(attr, &inarg.attr);
diff --git a/kernel/file.c b/kernel/file.c
index ddd80cf..fcb83c5 100644
--- a/kernel/file.c
+++ b/kernel/file.c
@@ -16,13 +16,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)
@@ -65,6 +58,19 @@ static int fuse_open(struct inode *inode, struct file *file)
return out.h.error;
}
+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);
@@ -73,7 +79,7 @@ static int fuse_release(struct inode *inode, struct file *file)
unsigned int s = sizeof(struct fuse_in) + sizeof(struct fuse_open_in);
if(file->f_mode & FMODE_WRITE)
- filemap_fdatawrite(inode->i_mapping);
+ fuse_sync_inode(inode);
in = kmalloc(s, GFP_NOFS);
if(!in)
diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h
index b83f663..de9f92a 100644
--- a/kernel/fuse_i.h
+++ b/kernel/fuse_i.h
@@ -233,6 +233,11 @@ int request_send_nonblock(struct fuse_conn *fc, struct fuse_in *in,
*/
int fuse_do_getattr(struct inode *inode);
+/**
+ * Write dirty pages
+ */
+void fuse_sync_inode(struct inode *inode);
+
/*
* Local Variables:
* indent-tabs-mode: t