^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * fs/sdcardfs/lookup.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2013 Samsung Electronics Co. Ltd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Sunghwan Yun, Sungjong Seo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This program has been developed as a stackable file system based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * the WrapFS which written by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (c) 1998-2011 Erez Zadok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Copyright (c) 2009 Shrikar Archak
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (c) 2003-2011 Stony Brook University
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Copyright (c) 2003-2011 The Research Foundation of SUNY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * This file is dual licensed. It may be redistributed and/or modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * under the terms of the Apache 2.0 License OR version 2 of the GNU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * General Public License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "sdcardfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "linux/delay.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* The dentry cache is just so we have properly sized dentries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) static struct kmem_cache *sdcardfs_dentry_cachep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) int sdcardfs_init_dentry_cache(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) sdcardfs_dentry_cachep =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) kmem_cache_create("sdcardfs_dentry",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) sizeof(struct sdcardfs_dentry_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 0, SLAB_RECLAIM_ACCOUNT, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return sdcardfs_dentry_cachep ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) void sdcardfs_destroy_dentry_cache(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) kmem_cache_destroy(sdcardfs_dentry_cachep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) void free_dentry_private_data(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) kmem_cache_free(sdcardfs_dentry_cachep, dentry->d_fsdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) dentry->d_fsdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /* allocate new dentry private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) int new_dentry_private_data(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct sdcardfs_dentry_info *info = SDCARDFS_D(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* use zalloc to init dentry_info.lower_path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) info = kmem_cache_zalloc(sdcardfs_dentry_cachep, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) spin_lock_init(&info->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) dentry->d_fsdata = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct inode_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct inode *lower_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) userid_t id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static int sdcardfs_inode_test(struct inode *inode, void *candidate_data/*void *candidate_lower_inode*/)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct inode *current_lower_inode = sdcardfs_lower_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) userid_t current_userid = SDCARDFS_I(inode)->data->userid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (current_lower_inode == ((struct inode_data *)candidate_data)->lower_inode &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) current_userid == ((struct inode_data *)candidate_data)->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return 1; /* found a match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return 0; /* no match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int sdcardfs_inode_set(struct inode *inode, void *lower_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* we do actual inode initialization in sdcardfs_iget */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct inode *sdcardfs_iget(struct super_block *sb, struct inode *lower_inode, userid_t id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct sdcardfs_inode_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct inode_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct inode *inode; /* the new inode to return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (!igrab(lower_inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return ERR_PTR(-ESTALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) data.id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) data.lower_inode = lower_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) inode = iget5_locked(sb, /* our superblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * hashval: we use inode number, but we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * also use "(unsigned long)lower_inode"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) lower_inode->i_ino, /* hashval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) sdcardfs_inode_test, /* inode comparison function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) sdcardfs_inode_set, /* inode init function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) &data); /* data passed to test+set fxns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (!inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) iput(lower_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* if found a cached inode, then just return it (after iput) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (!(inode->i_state & I_NEW)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) iput(lower_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* initialize new inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) info = SDCARDFS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) inode->i_ino = lower_inode->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) sdcardfs_set_lower_inode(inode, lower_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) inode_inc_iversion_raw(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* use different set of inode ops for symlinks & directories */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (S_ISDIR(lower_inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) inode->i_op = &sdcardfs_dir_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) else if (S_ISLNK(lower_inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) inode->i_op = &sdcardfs_symlink_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) inode->i_op = &sdcardfs_main_iops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /* use different set of file ops for directories */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (S_ISDIR(lower_inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) inode->i_fop = &sdcardfs_dir_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) inode->i_fop = &sdcardfs_main_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) inode->i_mapping->a_ops = &sdcardfs_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) inode->i_atime.tv_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) inode->i_atime.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) inode->i_mtime.tv_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) inode->i_mtime.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) inode->i_ctime.tv_sec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) inode->i_ctime.tv_nsec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* properly initialize special inodes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) init_special_inode(inode, lower_inode->i_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) lower_inode->i_rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* all well, copy inode attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) sdcardfs_copy_and_fix_attrs(inode, lower_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) fsstack_copy_inode_size(inode, lower_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unlock_new_inode(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Helper interpose routine, called directly by ->lookup to handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * spliced dentries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static struct dentry *__sdcardfs_interpose(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct path *lower_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) userid_t id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct inode *lower_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct super_block *lower_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct dentry *ret_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) lower_inode = d_inode(lower_path->dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) lower_sb = sdcardfs_lower_super(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* check that the lower file system didn't cross a mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (lower_inode->i_sb != lower_sb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ret_dentry = ERR_PTR(-EXDEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * We allocate our new inode below by calling sdcardfs_iget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * which will initialize some of the new inode's fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /* inherit lower inode number for sdcardfs's inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) inode = sdcardfs_iget(sb, lower_inode, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ret_dentry = ERR_CAST(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ret_dentry = d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) dentry = ret_dentry ?: dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (!IS_ERR(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) update_derived_permission_lock(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return ret_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * Connect an sdcardfs inode dentry/inode with several lower ones. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * the classic stackable file system "vnode interposition" action.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * @dentry: sdcardfs's dentry which interposes on lower one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * @sb: sdcardfs's super_block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * @lower_path: the lower path (caller does path_get/put)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) int sdcardfs_interpose(struct dentry *dentry, struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct path *lower_path, userid_t id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct dentry *ret_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret_dentry = __sdcardfs_interpose(dentry, sb, lower_path, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) return PTR_ERR(ret_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct sdcardfs_name_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct dir_context ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) const struct qstr *to_find;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) bool found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static int sdcardfs_name_match(struct dir_context *ctx, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int namelen, loff_t offset, u64 ino, unsigned int d_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct sdcardfs_name_data *buf = container_of(ctx, struct sdcardfs_name_data, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct qstr candidate = QSTR_INIT(name, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (qstr_case_eq(buf->to_find, &candidate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) memcpy(buf->name, name, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) buf->name[namelen] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) buf->found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * Main driver function for sdcardfs's lookup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * Returns: NULL (ok), ERR_PTR if an error occurred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * Fills in lower_parent_path with <dentry,mnt> on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static struct dentry *__sdcardfs_lookup(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) unsigned int flags, struct path *lower_parent_path, userid_t id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct vfsmount *lower_dir_mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct dentry *lower_dir_dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct dentry *lower_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) const struct qstr *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct path lower_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct dentry *ret_dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct sdcardfs_sb_info *sbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) sbi = SDCARDFS_SB(dentry->d_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* must initialize dentry operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) d_set_d_op(dentry, &sdcardfs_ci_dops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (IS_ROOT(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) name = &dentry->d_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /* now start the actual lookup procedure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) lower_dir_dentry = lower_parent_path->dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) lower_dir_mnt = lower_parent_path->mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* Use vfs_path_lookup to check if the dentry exists or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) err = vfs_path_lookup(lower_dir_dentry, lower_dir_mnt, name->name, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) &lower_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* check for other cases */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (err == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) const struct cred *cred = current_cred();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct sdcardfs_name_data buffer = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .ctx.actor = sdcardfs_name_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) .to_find = name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) .name = __getname(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) .found = false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (!buffer.name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) file = dentry_open(lower_parent_path, O_RDONLY, cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (IS_ERR(file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) err = PTR_ERR(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) goto put_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) err = iterate_dir(file, &buffer.ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) fput(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) goto put_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (buffer.found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) err = vfs_path_lookup(lower_dir_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) lower_dir_mnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) buffer.name, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) &lower_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) put_name:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) __putname(buffer.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /* no error: handle positive dentries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (!err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /* check if the dentry is an obb dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * if true, the lower_inode must be replaced with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * the inode of the graft path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (need_graft_path(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /* setup_obb_dentry()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * The lower_path will be stored to the dentry's orig_path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * and the base obbpath will be copyed to the lower_path variable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * if an error returned, there's no change in the lower_path
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * returns: -ERRNO if error (0: no error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) err = setup_obb_dentry(dentry, &lower_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* if the sbi->obbpath is not available, we can optionally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * setup the lower_path with its orig_path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * but, the current implementation just returns an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * because the sdcard daemon also regards this case as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * a lookup fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) pr_info("sdcardfs: base obbpath is not available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) sdcardfs_put_reset_orig_path(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) sdcardfs_set_lower_path(dentry, &lower_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) ret_dentry =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) __sdcardfs_interpose(dentry, dentry->d_sb, &lower_path, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (IS_ERR(ret_dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) err = PTR_ERR(ret_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) /* path_put underlying path on error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) sdcardfs_put_reset_lower_path(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * We don't consider ENOENT an error, and we want to return a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * negative dentry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (err && err != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* get a (very likely) new negative dentry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) lower_dentry = lookup_one_len_unlocked(name->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) lower_dir_dentry, name->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (IS_ERR(lower_dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) err = PTR_ERR(lower_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) lower_path.dentry = lower_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) lower_path.mnt = mntget(lower_dir_mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * Check if someone sneakily filled in the dentry when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * we weren't looking. We'll check again in create.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (unlikely(d_inode_rcu(lower_dentry))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) sdcardfs_set_lower_path(dentry, &lower_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * If the intent is to create a file, then don't return an error, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) * the VFS will continue the process of making this negative dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * into a positive one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (flags & (LOOKUP_CREATE|LOOKUP_RENAME_TARGET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return ret_dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * On success:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * fills dentry object appropriate values and returns NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * On fail (== error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * returns error ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * @dir : Parent inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * @dentry : Target dentry to lookup. we should set each of fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * (dentry->d_name is initialized already)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * @nd : nameidata of parent inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct dentry *sdcardfs_lookup(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct dentry *ret = NULL, *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) struct path lower_parent_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) const struct cred *saved_cred = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) parent = dget_parent(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (!check_caller_access_to_name(d_inode(parent), &dentry->d_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) ret = ERR_PTR(-EACCES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* save current_cred and override it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) saved_cred = override_fsids(SDCARDFS_SB(dir->i_sb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) SDCARDFS_I(dir)->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (!saved_cred) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ret = ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) sdcardfs_get_lower_path(parent, &lower_parent_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* allocate dentry private data. We free it in ->d_release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) err = new_dentry_private_data(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) ret = ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) ret = __sdcardfs_lookup(dentry, flags, &lower_parent_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) SDCARDFS_I(dir)->data->userid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (IS_ERR(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) dentry = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (d_inode(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) fsstack_copy_attr_times(d_inode(dentry),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) sdcardfs_lower_inode(d_inode(dentry)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /* get derived permission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) get_derived_permission(parent, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) fixup_tmp_permissions(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) fixup_lower_ownership(dentry, dentry->d_name.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* update parent directory's atime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) fsstack_copy_attr_atime(d_inode(parent),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) sdcardfs_lower_inode(d_inode(parent)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) sdcardfs_put_lower_path(parent, &lower_parent_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) revert_fsids(saved_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) dput(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }