]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
fuse: add exclusion between reads and invalidate historic/wip-fuse
authorSage Weil <sage@inktank.com>
Fri, 19 Apr 2013 17:07:11 +0000 (10:07 -0700)
committerSage Weil <sage@inktank.com>
Fri, 19 Apr 2013 17:07:11 +0000 (10:07 -0700)
This blocks new reads from starting if an invalidate is in progress...

Signed-off-by: Sage Weil <sage@inktank.com>
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c

index f3ab824fa302bcae5909adf5c676c4bbb9417743..a0dd4f896d49045c8a25c9b438db25cbe65114c9 100644 (file)
@@ -704,6 +704,7 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
 {
        struct inode *inode = iocb->ki_filp->f_mapping->host;
        struct fuse_conn *fc = get_fuse_conn(inode);
+       int ret;
 
        /*
         * In auto invalidate mode, always update attributes on read.
@@ -717,8 +718,10 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
                if (err)
                        return err;
        }
-
-       return generic_file_aio_read(iocb, iov, nr_segs, pos);
+       mutex_lock(&fc->invalidate_mutex);
+       ret = generic_file_aio_read(iocb, iov, nr_segs, pos);
+       mutex_unlock(&fc->invalidate_mutex);
+       return ret;
 }
 
 static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff,
index e105a53fc72df6c08c116bec56d82b7eda9ce56b..e4c8d11056b237b5de787232617acb4a0ce0a7a4 100644 (file)
@@ -328,6 +328,7 @@ struct fuse_conn {
 
        /** Mutex protecting against directory alias creation */
        struct mutex inst_mutex;
+       struct mutex invalidate_mutex;
 
        /** Refcount */
        atomic_t count;
index 73ca6b72beafa0d19f5997bf7627b5046459c492..40dae2de1e1032767ac9e960597f1322d9d5e45c 100644 (file)
@@ -314,6 +314,7 @@ int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid,
        struct inode *inode;
        pgoff_t pg_start;
        pgoff_t pg_end;
+       struct fuse_conn *fc;
 
        inode = ilookup5(sb, nodeid, fuse_inode_eq, &nodeid);
        if (!inode)
@@ -321,6 +322,8 @@ int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid,
 
        fuse_invalidate_attr(inode);
        if (offset >= 0) {
+               fc = get_fuse_conn(inode);
+               mutex_lock(&fc->invalidate_mutex);
                pg_start = offset >> PAGE_CACHE_SHIFT;
                if (len <= 0)
                        pg_end = -1;
@@ -328,6 +331,7 @@ int fuse_reverse_inval_inode(struct super_block *sb, u64 nodeid,
                        pg_end = (offset + len - 1) >> PAGE_CACHE_SHIFT;
                invalidate_inode_pages2_range(inode->i_mapping,
                                              pg_start, pg_end);
+               mutex_unlock(&fc->invalidate_mutex);
        }
        iput(inode);
        return 0;
@@ -562,6 +566,7 @@ void fuse_conn_init(struct fuse_conn *fc)
        memset(fc, 0, sizeof(*fc));
        spin_lock_init(&fc->lock);
        mutex_init(&fc->inst_mutex);
+       mutex_init(&fc->invalidate_mutex);
        init_rwsem(&fc->killsb);
        atomic_set(&fc->count, 1);
        init_waitqueue_head(&fc->waitq);