diff options
| author | Daniel Rosenberg <drosen@google.com> | 2018-02-20 20:25:45 -0800 |
|---|---|---|
| committer | Daniel Rosenberg <drosen@google.com> | 2018-02-23 23:01:54 +0000 |
| commit | 2240ca0fc8b7bc28f679695206c3f3518665a3d9 (patch) | |
| tree | bb4d9ba073225d3844992e24c7640553a2b0b9c3 | |
| parent | de4b647c0124a928b458d7d79927a3cd0a7462e3 (diff) | |
ANDROID: sdcardfs: Hold i_mutex for i_size_write
When we call i_size_write, we must be holding i_mutex to avoid
possible lockups on 32 bit/SMP architectures. This is not
necessary on 64 bit architectures.
Change-Id: Ic3b946507c54d81b5c9046f9b57d25d4b0f9feef
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Bug: 73287721
| -rw-r--r-- | fs/sdcardfs/file.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/fs/sdcardfs/file.c b/fs/sdcardfs/file.c index 5ac0b0bbb0ec..2879d1291a11 100644 --- a/fs/sdcardfs/file.c +++ b/fs/sdcardfs/file.c @@ -62,6 +62,7 @@ static ssize_t sdcardfs_write(struct file *file, const char __user *buf, int err; struct file *lower_file; struct dentry *dentry = file->f_path.dentry; + struct inode *inode = d_inode(dentry); /* check disk space */ if (!check_min_free_space(dentry, count, 0)) { @@ -73,10 +74,12 @@ static ssize_t sdcardfs_write(struct file *file, const char __user *buf, err = vfs_write(lower_file, buf, count, ppos); /* update our inode times+sizes upon a successful lower write */ if (err >= 0) { - fsstack_copy_inode_size(d_inode(dentry), - file_inode(lower_file)); - fsstack_copy_attr_times(d_inode(dentry), - file_inode(lower_file)); + if (sizeof(loff_t) > sizeof(long)) + inode_lock(inode); + fsstack_copy_inode_size(inode, file_inode(lower_file)); + fsstack_copy_attr_times(inode, file_inode(lower_file)); + if (sizeof(loff_t) > sizeof(long)) + inode_unlock(inode); } return err; @@ -391,6 +394,7 @@ ssize_t sdcardfs_write_iter(struct kiocb *iocb, struct iov_iter *iter) { int err; struct file *file = iocb->ki_filp, *lower_file; + struct inode *inode = file->f_path.dentry->d_inode; lower_file = sdcardfs_lower_file(file); if (!lower_file->f_op->write_iter) { @@ -405,10 +409,12 @@ ssize_t sdcardfs_write_iter(struct kiocb *iocb, struct iov_iter *iter) fput(lower_file); /* update upper inode times/sizes as needed */ if (err >= 0 || err == -EIOCBQUEUED) { - fsstack_copy_inode_size(file->f_path.dentry->d_inode, - file_inode(lower_file)); - fsstack_copy_attr_times(file->f_path.dentry->d_inode, - file_inode(lower_file)); + if (sizeof(loff_t) > sizeof(long)) + inode_lock(inode); + fsstack_copy_inode_size(inode, file_inode(lower_file)); + fsstack_copy_attr_times(inode, file_inode(lower_file)); + if (sizeof(loff_t) > sizeof(long)) + inode_lock(inode); } out: return err; |
