From: Sage Weil Date: Fri, 19 Apr 2013 17:07:11 +0000 (-0700) Subject: fuse: add exclusion between reads and invalidate X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=55f2cdc6d2cd9d3816c2ace1c374750b6e0ce17e;p=ceph-client.git fuse: add exclusion between reads and invalidate This blocks new reads from starting if an invalidate is in progress... Signed-off-by: Sage Weil --- diff --git a/fs/fuse/file.c b/fs/fuse/file.c index f3ab824fa302..a0dd4f896d49 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -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, diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index e105a53fc72d..e4c8d11056b2 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -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; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 73ca6b72beaf..40dae2de1e10 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -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);