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
This commit is contained in:
parent
8295827beb
commit
817be5a7e2
1 changed files with 14 additions and 8 deletions
|
@ -62,6 +62,7 @@ static ssize_t sdcardfs_write(struct file *file, const char __user *buf,
|
||||||
int err;
|
int err;
|
||||||
struct file *lower_file;
|
struct file *lower_file;
|
||||||
struct dentry *dentry = file->f_path.dentry;
|
struct dentry *dentry = file->f_path.dentry;
|
||||||
|
struct inode *inode = d_inode(dentry);
|
||||||
|
|
||||||
/* check disk space */
|
/* check disk space */
|
||||||
if (!check_min_free_space(dentry, count, 0)) {
|
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);
|
err = vfs_write(lower_file, buf, count, ppos);
|
||||||
/* update our inode times+sizes upon a successful lower write */
|
/* update our inode times+sizes upon a successful lower write */
|
||||||
if (err >= 0) {
|
if (err >= 0) {
|
||||||
fsstack_copy_inode_size(d_inode(dentry),
|
if (sizeof(loff_t) > sizeof(long))
|
||||||
file_inode(lower_file));
|
inode_lock(inode);
|
||||||
fsstack_copy_attr_times(d_inode(dentry),
|
fsstack_copy_inode_size(inode, file_inode(lower_file));
|
||||||
file_inode(lower_file));
|
fsstack_copy_attr_times(inode, file_inode(lower_file));
|
||||||
|
if (sizeof(loff_t) > sizeof(long))
|
||||||
|
inode_unlock(inode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -391,6 +394,7 @@ ssize_t sdcardfs_write_iter(struct kiocb *iocb, struct iov_iter *iter)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct file *file = iocb->ki_filp, *lower_file;
|
struct file *file = iocb->ki_filp, *lower_file;
|
||||||
|
struct inode *inode = file->f_path.dentry->d_inode;
|
||||||
|
|
||||||
lower_file = sdcardfs_lower_file(file);
|
lower_file = sdcardfs_lower_file(file);
|
||||||
if (!lower_file->f_op->write_iter) {
|
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);
|
fput(lower_file);
|
||||||
/* update upper inode times/sizes as needed */
|
/* update upper inode times/sizes as needed */
|
||||||
if (err >= 0 || err == -EIOCBQUEUED) {
|
if (err >= 0 || err == -EIOCBQUEUED) {
|
||||||
fsstack_copy_inode_size(file->f_path.dentry->d_inode,
|
if (sizeof(loff_t) > sizeof(long))
|
||||||
file_inode(lower_file));
|
inode_lock(inode);
|
||||||
fsstack_copy_attr_times(file->f_path.dentry->d_inode,
|
fsstack_copy_inode_size(inode, file_inode(lower_file));
|
||||||
file_inode(lower_file));
|
fsstack_copy_attr_times(inode, file_inode(lower_file));
|
||||||
|
if (sizeof(loff_t) > sizeof(long))
|
||||||
|
inode_lock(inode);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return err;
|
return err;
|
||||||
|
|
Loading…
Reference in a new issue