From: Miklos Szeredi <miklos@szeredi.hu>

Don't change mtime/ctime/atime to local time on read/write.  Rather invalidate
file attributes, so next stat() will force a GETATTR call.  Bug reported by
Ben Grimm.

Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 fs/fuse/dir.c   |    2 ++
 fs/fuse/file.c  |   10 ++++++----
 fs/fuse/inode.c |    1 +
 3 files changed, 9 insertions(+), 4 deletions(-)

diff -puN fs/fuse/dir.c~fuse-dont-update-file-times fs/fuse/dir.c
--- devel/fs/fuse/dir.c~fuse-dont-update-file-times	2005-07-29 23:26:14.000000000 -0700
+++ devel-akpm/fs/fuse/dir.c	2005-07-29 23:26:14.000000000 -0700
@@ -552,6 +552,7 @@ static int fuse_readdir(struct file *fil
 				    filldir);
 
 	__free_page(page);
+	fuse_invalidate_attr(inode); /* atime changed */
 	return err;
 }
 
@@ -585,6 +586,7 @@ static char *read_link(struct dentry *de
 		link[req->out.args[0].size] = '\0';
  out:
 	fuse_put_request(fc, req);
+	fuse_invalidate_attr(inode); /* atime changed */
 	return link;
 }
 
diff -puN fs/fuse/file.c~fuse-dont-update-file-times fs/fuse/file.c
--- devel/fs/fuse/file.c~fuse-dont-update-file-times	2005-07-29 23:26:14.000000000 -0700
+++ devel-akpm/fs/fuse/file.c	2005-07-29 23:26:14.000000000 -0700
@@ -240,6 +240,7 @@ static int fuse_readpage(struct file *fi
 	fuse_put_request(fc, req);
 	if (!err)
 		SetPageUptodate(page);
+	fuse_invalidate_attr(inode); /* atime changed */
  out:
 	unlock_page(page);
 	return err;
@@ -308,6 +309,7 @@ static int fuse_readpages(struct file *f
 	if (!err && data.req->num_pages)
 		err = fuse_send_readpages(data.req, file, inode);
 	fuse_put_request(fc, data.req);
+	fuse_invalidate_attr(inode); /* atime changed */
 	return err;
 }
 
@@ -376,8 +378,8 @@ static int fuse_commit_write(struct file
 			clear_page_dirty(page);
 			SetPageUptodate(page);
 		}
-	} else if (err == -EINTR || err == -EIO)
-		fuse_invalidate_attr(inode);
+	}
+	fuse_invalidate_attr(inode);
 	return err;
 }
 
@@ -469,8 +471,8 @@ static ssize_t fuse_direct_io(struct fil
 		if (write && pos > i_size_read(inode))
 			i_size_write(inode, pos);
 		*ppos = pos;
-	} else if (write && (res == -EINTR || res == -EIO))
-		fuse_invalidate_attr(inode);
+	}
+	fuse_invalidate_attr(inode);
 
 	return res;
 }
diff -puN fs/fuse/inode.c~fuse-dont-update-file-times fs/fuse/inode.c
--- devel/fs/fuse/inode.c~fuse-dont-update-file-times	2005-07-29 23:26:14.000000000 -0700
+++ devel-akpm/fs/fuse/inode.c	2005-07-29 23:26:14.000000000 -0700
@@ -173,6 +173,7 @@ struct inode *fuse_iget(struct super_blo
 		return NULL;
 
 	if ((inode->i_state & I_NEW)) {
+		inode->i_flags |= S_NOATIME|S_NOCMTIME;
 		inode->i_generation = generation;
 		inode->i_data.backing_dev_info = &fc->bdi;
 		fuse_init_inode(inode, attr);
_