sdcardfs: Move directory unlock before touch
authorDaniel Rosenberg <drosen@google.com>
Mon, 26 Sep 2016 21:48:22 +0000 (14:48 -0700)
committerStricted <info@stricted.net>
Thu, 11 Oct 2018 16:03:18 +0000 (18:03 +0200)
This removes a deadlock under low memory conditions.
filp_open can call lookup_slow, which will attempt to
lock the parent.

Change-Id: I940643d0793f5051d1e79a56f4da2fa8ca3d8ff7
Signed-off-by: Daniel Rosenberg <drosen@google.com>
fs/sdcardfs/inode.c

index 9842a92856a36f0e48a6aa4c3e790fb421824ffe..49554269f955b33464782ffb2dd08d9b97d83de4 100644 (file)
@@ -296,14 +296,17 @@ static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
        copied_fs = copy_fs_struct(current->fs);
        if (!copied_fs) {
                err = -ENOMEM;
+               unlock_dir(lower_parent_dentry);
                goto out_unlock;
        }
        current->fs = copied_fs;
        current->fs->umask = 0;
        err = vfs_mkdir(lower_parent_dentry->d_inode, lower_dentry, mode);
 
-       if (err)
+       if (err) {
+               unlock_dir(lower_parent_dentry);
                goto out;
+       }
 
        /* if it is a local obb dentry, setup it with the base obbpath */
        if(need_graft_path(dentry)) {
@@ -325,14 +328,18 @@ static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
        }
 
        err = sdcardfs_interpose(dentry, dir->i_sb, &lower_path, pi->userid);
-       if (err)
+       if (err) {
+               unlock_dir(lower_parent_dentry);
                goto out;
+       }
 
        fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
        fsstack_copy_inode_size(dir, lower_parent_dentry->d_inode);
        /* update number of links on parent directory */
        set_nlink(dir, sdcardfs_lower_inode(dir)->i_nlink);
 
+       unlock_dir(lower_parent_dentry);
+
        if ((!sbi->options.multiuser) && (!strcasecmp(dentry->d_name.name, "obb"))
                && (pi->perm == PERM_ANDROID) && (pi->userid == 0))
                make_nomedia_in_obb = 1;
@@ -352,7 +359,6 @@ out:
        current->fs = saved_fs;
        free_fs_struct(copied_fs);
 out_unlock:
-       unlock_dir(lower_parent_dentry);
        sdcardfs_put_lower_path(dentry, &lower_path);
 out_revert:
        REVERT_CRED(saved_cred);