From 6ec3ca7f43cae1aee91e513b20efa4470356cd83 Mon Sep 17 00:00:00 2001 From: Nikhilesh Reddy Date: Tue, 20 Sep 2016 13:50:30 -0700 Subject: [PATCH] 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 --- fs/fuse/passthrough.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c index e8671942c2a0..785af63acabd 100644 --- a/fs/fuse/passthrough.c +++ b/fs/fuse/passthrough.c @@ -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 {