On 06/13/2012 03:02 AM, Sabyasachi Ruj wrote:
>> So maybe the time when you gain an exclusive lock on a file is the
>> appropriate time to flush your local cache?
> 
> I used exclusive lock is just for a simplified demonstration. In
> reality, a shared read lock will be used when just reading from the
> file is enough. I that case, the right time to flush local cache would
> be whenever any *lock* is obtained.

FWIW, here are a couple fuse patches that allow your test program to work:

- The first has been posted upstream and fixes an issue where fuse
wouldn't invalidate cache of a file unless the file size has changed:

http://thread.gmane.org/gmane.comp.file-systems.fuse.devel/11589

- The second I just cooked up to always invoke the revalidation in the
read path. It currently only revalidates if a read is attempted beyond
EOF (to ensure the size attribute is valid). I've only lightly tested so
far to see how it behaves with your test. The patch is attached. Note
that AFAICS this would still be a problem when using splice.

Brian

>From 4570c8af582cc4e8857e9966af106a3544060c15 Mon Sep 17 00:00:00 2001
From: Brian Foster <[email protected]>
Date: Wed, 13 Jun 2012 11:19:54 -0400
Subject: [PATCH] fuse: update attributes on aio_read

A fuse-based network filesystem might allow for the inode
and/or file data to change unexpectedly. A local client
that opens and repeatedly reads a file might never pick
up on such changes and indefinitely return stale data.

Always invoke fuse_update_attributes() in the read path
to cause an attr revalidation when the attributes expire.
This leads to a page cache invalidation if necessary and
ensures fuse issues new read requests to the fuse client.

Signed-off-by: Brian Foster <[email protected]>
---
 fs/fuse/file.c |   14 ++++----------
 1 files changed, 4 insertions(+), 10 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index b321a68..0bb01bd 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -702,18 +702,12 @@ out:
 static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
 				  unsigned long nr_segs, loff_t pos)
 {
+	int err;
 	struct inode *inode = iocb->ki_filp->f_mapping->host;
 
-	if (pos + iov_length(iov, nr_segs) > i_size_read(inode)) {
-		int err;
-		/*
-		 * If trying to read past EOF, make sure the i_size
-		 * attribute is up-to-date.
-		 */
-		err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL);
-		if (err)
-			return err;
-	}
+	err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL);
+	if (err)
+		return err;
 
 	return generic_file_aio_read(iocb, iov, nr_segs, pos);
 }
-- 
1.7.7.6

_______________________________________________
Gluster-users mailing list
[email protected]
http://gluster.org/cgi-bin/mailman/listinfo/gluster-users

Reply via email to