fuse: Grab the fc->lock for inode updates in passthrough

The function fsstack_copy_inode_size uses the inode->i_lock to
serialize the inode updates. This lock is not used in the FUSE
filesystem and thus it is not enough to just grab this lock
before updating a FUSE inode.

Grab the fc->lock for inode updates in passthrough to ensure
that there are no races between inode size updates in 32 bit
architectures with SMP.

Change-Id: I83cb2380b6ca56768c06e70ef1bf9ea3976b514a
Signed-off-by: Nikhilesh Reddy <reddyn@codeaurora.org>
This commit is contained in:
Nikhilesh Reddy 2016-09-20 13:50:30 -07:00 committed by Gerrit - the friendly Code Review server
parent 4b91c1a0f7
commit 6ec3ca7f43

View file

@ -71,10 +71,12 @@ static ssize_t fuse_passthrough_read_write_iter(struct kiocb *iocb,
struct fuse_file *ff;
struct file *fuse_file, *passthrough_filp;
struct inode *fuse_inode, *passthrough_inode;
struct fuse_conn *fc;
ff = iocb->ki_filp->private_data;
fuse_file = iocb->ki_filp;
passthrough_filp = ff->passthrough_filp;
fc = ff->fc;
/* lock passthrough file to prevent it from being released */
get_file(passthrough_filp);
@ -88,7 +90,9 @@ static ssize_t fuse_passthrough_read_write_iter(struct kiocb *iocb,
ret_val = passthrough_filp->f_op->write_iter(iocb, iter);
if (ret_val >= 0 || ret_val == -EIOCBQUEUED) {
spin_lock(&fc->lock);
fsstack_copy_inode_size(fuse_inode, passthrough_inode);
spin_unlock(&fc->lock);
fsstack_copy_attr_times(fuse_inode, passthrough_inode);
}
} else {