Skip to content

Commit

Permalink
ANDROID: sdcardfs: Hold i_mutex for i_size_write
Browse files Browse the repository at this point in the history
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
  • Loading branch information
drosen-google committed Feb 23, 2018
1 parent 1a19138 commit 7505120
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions fs/sdcardfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = dentry->d_inode;

/* check disk space */
if (!check_min_free_space(dentry, count, 0)) {
Expand All @@ -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(dentry->d_inode,
file_inode(lower_file));
fsstack_copy_attr_times(dentry->d_inode,
file_inode(lower_file));
if (sizeof(loff_t) > sizeof(long))
mutex_lock(&inode->i_mutex);
fsstack_copy_inode_size(inode, file_inode(lower_file));
fsstack_copy_attr_times(inode, file_inode(lower_file));
if (sizeof(loff_t) > sizeof(long))
mutex_unlock(&inode->i_mutex);
}

return err;
Expand Down Expand Up @@ -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) {
Expand All @@ -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))
mutex_lock(&inode->i_mutex);
fsstack_copy_inode_size(inode, file_inode(lower_file));
fsstack_copy_attr_times(inode, file_inode(lower_file));
if (sizeof(loff_t) > sizeof(long))
mutex_unlock(&inode->i_mutex);
}
out:
return err;
Expand Down

0 comments on commit 7505120

Please sign in to comment.