/* * On success: * fills dentry object appropriate values and returns NULL. * On fail (== error) * returns error ptr * * @dir : Parent inode. It is locked (dir->i_mutex) * @dentry : Target dentry to lookup. we should set each of fields. * (dentry->d_name is initialized already) * @nd : nameidata of parent inode */ struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags) { struct dentry *ret = NULL, *parent; struct path lower_parent_path; int err = 0; struct sdcardfs_sb_info *sbi = SDCARDFS_SB(dentry->d_sb); const struct cred *saved_cred = NULL; parent = dget_parent(dentry); if(!check_caller_access_to_name(parent->d_inode, dentry->d_name.name, sbi->options.derive, 0, 0)) { ret = ERR_PTR(-EACCES); 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); goto out_err; } /* save current_cred and override it */ OVERRIDE_CRED_PTR(SDCARDFS_SB(dir->i_sb), saved_cred); sdcardfs_get_lower_path(parent, &lower_parent_path); /* allocate dentry private data. We free it in ->d_release */ err = new_dentry_private_data(dentry); if (err) { ret = ERR_PTR(err); goto out; } ret = __sdcardfs_lookup(dentry, flags, &lower_parent_path); if (IS_ERR(ret)) { goto out; } if (ret) dentry = ret; if (dentry->d_inode) { fsstack_copy_attr_times(dentry->d_inode, sdcardfs_lower_inode(dentry->d_inode)); /* get drived permission */ get_derived_permission(parent, dentry); fix_derived_permission(dentry->d_inode); } /* update parent directory's atime */ fsstack_copy_attr_atime(parent->d_inode, sdcardfs_lower_inode(parent->d_inode)); out: sdcardfs_put_lower_path(parent, &lower_parent_path); REVERT_CRED(saved_cred); out_err: dput(parent); return ret; }
/* * On success: * fills dentry object appropriate values and returns NULL. * On fail (== error) * returns error ptr * * @dir : Parent inode. It is locked (dir->i_mutex) * @dentry : Target dentry to lookup. we should set each of fields. * (dentry->d_name is initialized already) * @nd : nameidata of parent inode */ struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { struct dentry *ret, *parent; struct path lower_parent_path; int err = 0; OVERRIDE_CRED_PTR(SDCARDFS_SB(dir->i_sb)); parent = dget_parent(dentry); sdcardfs_get_lower_path(parent, &lower_parent_path); /* allocate dentry private data. We free it in ->d_release */ err = new_dentry_private_data(dentry); if (err) { ret = ERR_PTR(err); goto out; } ret = __sdcardfs_lookup(dentry, nd, &lower_parent_path); if (IS_ERR(ret)) { goto out; } if (ret) dentry = ret; if (dentry->d_inode) fsstack_copy_attr_times(dentry->d_inode, sdcardfs_lower_inode(dentry->d_inode)); /* update parent directory's atime */ fsstack_copy_attr_atime(parent->d_inode, sdcardfs_lower_inode(parent->d_inode)); out: sdcardfs_put_lower_path(parent, &lower_parent_path); dput(parent); REVERT_CRED(); return ret; }