FROMLIST: drm/bridge: analogix_dp: Don't read EDID if panel present
[firefly-linux-kernel-4.4.55.git] / fs / sdcardfs / inode.c
index a2cad0f76f14dbfed8692f8d9c52a9845bf09a38..68e615045616e33f0f2c637e1f3ace655bb9998b 100644 (file)
 #include <linux/fs_struct.h>
 
 /* Do not directly use this function. Use OVERRIDE_CRED() instead. */
-const struct cred * override_fsids(struct sdcardfs_sb_info* sbi)
+const struct cred * override_fsids(struct sdcardfs_sb_info* sbi, struct sdcardfs_inode_info *info)
 {
        struct cred * cred;
        const struct cred * old_cred;
+       uid_t uid;
 
        cred = prepare_creds();
        if (!cred)
                return NULL;
 
-       cred->fsuid = make_kuid(&init_user_ns, sbi->options.fs_low_uid);
+       if (info->under_obb)
+               uid = AID_MEDIA_OBB;
+       else
+               uid = multiuser_get_uid(info->userid, sbi->options.fs_low_uid);
+       cred->fsuid = make_kuid(&init_user_ns, uid);
        cred->fsgid = make_kgid(&init_user_ns, sbi->options.fs_low_gid);
 
        old_cred = override_creds(cred);
@@ -61,7 +66,7 @@ static int sdcardfs_create(struct inode *dir, struct dentry *dentry,
        struct fs_struct *saved_fs;
        struct fs_struct *copied_fs;
 
-       if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+       if(!check_caller_access_to_name(dir, &dentry->d_name)) {
                printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
                                                 "  dentry: %s, task:%s\n",
                                                 __func__, dentry->d_name.name, current->comm);
@@ -70,7 +75,7 @@ static int sdcardfs_create(struct inode *dir, struct dentry *dentry,
        }
 
        /* save current_cred and override it */
-       OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred);
+       OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
 
        sdcardfs_get_lower_path(dentry, &lower_path);
        lower_dentry = lower_path.dentry;
@@ -98,6 +103,7 @@ static int sdcardfs_create(struct inode *dir, struct dentry *dentry,
                goto out;
        fsstack_copy_attr_times(dir, sdcardfs_lower_inode(dir));
        fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry));
+       fixup_lower_ownership(dentry, dentry->d_name.name);
 
 out:
        current->fs = saved_fs;
@@ -162,7 +168,7 @@ static int sdcardfs_unlink(struct inode *dir, struct dentry *dentry)
        struct path lower_path;
        const struct cred *saved_cred = NULL;
 
-       if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+       if(!check_caller_access_to_name(dir, &dentry->d_name)) {
                printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
                                                 "  dentry: %s, task:%s\n",
                                                 __func__, dentry->d_name.name, current->comm);
@@ -171,7 +177,7 @@ static int sdcardfs_unlink(struct inode *dir, struct dentry *dentry)
        }
 
        /* save current_cred and override it */
-       OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred);
+       OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
 
        sdcardfs_get_lower_path(dentry, &lower_path);
        lower_dentry = lower_path.dentry;
@@ -269,8 +275,10 @@ static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
        int touch_err = 0;
        struct fs_struct *saved_fs;
        struct fs_struct *copied_fs;
+       struct qstr q_obb = QSTR_LITERAL("obb");
+       struct qstr q_data = QSTR_LITERAL("data");
 
-       if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+       if(!check_caller_access_to_name(dir, &dentry->d_name)) {
                printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
                                                 "  dentry: %s, task:%s\n",
                                                 __func__, dentry->d_name.name, current->comm);
@@ -279,7 +287,7 @@ static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
        }
 
        /* save current_cred and override it */
-       OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred);
+       OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
 
        /* check disk space */
        if (!check_min_free_space(dentry, 0, 1)) {
@@ -343,16 +351,17 @@ static int sdcardfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
        fsstack_copy_inode_size(dir, d_inode(lower_parent_dentry));
        /* update number of links on parent directory */
        set_nlink(dir, sdcardfs_lower_inode(dir)->i_nlink);
-
+       fixup_lower_ownership(dentry, dentry->d_name.name);
        unlock_dir(lower_parent_dentry);
-
-       if ((!sbi->options.multiuser) && (!strcasecmp(dentry->d_name.name, "obb"))
+       if ((!sbi->options.multiuser) && (qstr_case_eq(&dentry->d_name, &q_obb))
                && (pi->perm == PERM_ANDROID) && (pi->userid == 0))
                make_nomedia_in_obb = 1;
 
        /* When creating /Android/data and /Android/obb, mark them as .nomedia */
        if (make_nomedia_in_obb ||
-               ((pi->perm == PERM_ANDROID) && (!strcasecmp(dentry->d_name.name, "data")))) {
+               ((pi->perm == PERM_ANDROID) && (qstr_case_eq(&dentry->d_name, &q_data)))) {
+               REVERT_CRED(saved_cred);
+               OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(d_inode(dentry)));
                set_fs_pwd(current->fs, &lower_path);
                touch_err = touch(".nomedia", 0664);
                if (touch_err) {
@@ -381,7 +390,7 @@ static int sdcardfs_rmdir(struct inode *dir, struct dentry *dentry)
        struct path lower_path;
        const struct cred *saved_cred = NULL;
 
-       if(!check_caller_access_to_name(dir, dentry->d_name.name)) {
+       if(!check_caller_access_to_name(dir, &dentry->d_name)) {
                printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
                                                 "  dentry: %s, task:%s\n",
                                                 __func__, dentry->d_name.name, current->comm);
@@ -390,7 +399,7 @@ static int sdcardfs_rmdir(struct inode *dir, struct dentry *dentry)
        }
 
        /* save current_cred and override it */
-       OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred);
+       OVERRIDE_CRED(SDCARDFS_SB(dir->i_sb), saved_cred, SDCARDFS_I(dir));
 
        /* sdcardfs_get_real_lower(): in case of remove an user's obb dentry
         * the dentry on the original path should be deleted. */
@@ -469,8 +478,8 @@ static int sdcardfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        struct path lower_old_path, lower_new_path;
        const struct cred *saved_cred = NULL;
 
-       if(!check_caller_access_to_name(old_dir, old_dentry->d_name.name) ||
-               !check_caller_access_to_name(new_dir, new_dentry->d_name.name)) {
+       if(!check_caller_access_to_name(old_dir, &old_dentry->d_name) ||
+               !check_caller_access_to_name(new_dir, &new_dentry->d_name)) {
                printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
                                                 "  new_dentry: %s, task:%s\n",
                                                 __func__, new_dentry->d_name.name, current->comm);
@@ -479,7 +488,7 @@ static int sdcardfs_rename(struct inode *old_dir, struct dentry *old_dentry,
        }
 
        /* save current_cred and override it */
-       OVERRIDE_CRED(SDCARDFS_SB(old_dir->i_sb), saved_cred);
+       OVERRIDE_CRED(SDCARDFS_SB(old_dir->i_sb), saved_cred, SDCARDFS_I(new_dir));
 
        sdcardfs_get_real_lower(old_dentry, &lower_old_path);
        sdcardfs_get_lower_path(new_dentry, &lower_new_path);
@@ -516,11 +525,10 @@ static int sdcardfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                sdcardfs_copy_and_fix_attrs(old_dir, d_inode(lower_old_dir_dentry));
                fsstack_copy_inode_size(old_dir, d_inode(lower_old_dir_dentry));
        }
-       /* At this point, not all dentry information has been moved, so
-        * we pass along new_dentry for the name.*/
-       get_derived_permission_new(new_dentry->d_parent, old_dentry, new_dentry);
+       get_derived_permission_new(new_dentry->d_parent, old_dentry, &new_dentry->d_name);
        fixup_tmp_permissions(d_inode(old_dentry));
-       fixup_top_recursive(old_dentry);
+       fixup_lower_ownership(old_dentry, new_dentry->d_name.name);
+       drop_recursive(old_dentry); /* Can't fixup ownership recursively :( */
 out:
        unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
        dput(lower_old_dir_dentry);
@@ -737,7 +745,7 @@ static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry, struct
        if (!err) {
                /* check the Android group ID */
                parent = dget_parent(dentry);
-               if(!check_caller_access_to_name(d_inode(parent), dentry->d_name.name)) {
+               if(!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
                        printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
                                                         "  dentry: %s, task:%s\n",
                                                         __func__, dentry->d_name.name, current->comm);
@@ -750,7 +758,7 @@ static int sdcardfs_setattr(struct vfsmount *mnt, struct dentry *dentry, struct
                goto out_err;
 
        /* save current_cred and override it */
-       OVERRIDE_CRED(SDCARDFS_SB(dentry->d_sb), saved_cred);
+       OVERRIDE_CRED(SDCARDFS_SB(dentry->d_sb), saved_cred, SDCARDFS_I(inode));
 
        sdcardfs_get_lower_path(dentry, &lower_path);
        lower_dentry = lower_path.dentry;
@@ -855,7 +863,7 @@ static int sdcardfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
        int err;
 
        parent = dget_parent(dentry);
-       if(!check_caller_access_to_name(d_inode(parent), dentry->d_name.name)) {
+       if(!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
                printk(KERN_INFO "%s: need to check the caller's gid in packages.list\n"
                                                 "  dentry: %s, task:%s\n",
                                                 __func__, dentry->d_name.name, current->comm);