^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * fs/sdcardfs/dentry.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/ctype.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * returns: -ERRNO if error (returned to user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * 0: tell VFS to invalidate dentry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * 1: dentry is valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static int sdcardfs_d_revalidate(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int err = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct path parent_lower_path, lower_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct dentry *parent_dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct dentry *parent_lower_dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct dentry *lower_cur_parent_dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct dentry *lower_dentry = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct sdcardfs_inode_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (IS_ROOT(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* check uninitialized obb_dentry and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * whether the base obbpath has been changed or not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (is_obbpath_invalid(dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) parent_dentry = dget_parent(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) sdcardfs_get_lower_path(parent_dentry, &parent_lower_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) sdcardfs_get_real_lower(dentry, &lower_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) parent_lower_dentry = parent_lower_path.dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) lower_dentry = lower_path.dentry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) lower_cur_parent_dentry = dget_parent(lower_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) if ((lower_dentry->d_flags & DCACHE_OP_REVALIDATE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) err = lower_dentry->d_op->d_revalidate(lower_dentry, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (err == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) spin_lock(&lower_dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (d_unhashed(lower_dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) spin_unlock(&lower_dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) spin_unlock(&lower_dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (parent_lower_dentry != lower_cur_parent_dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (dentry < lower_dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) spin_lock_nested(&lower_dentry->d_lock, DENTRY_D_LOCK_NESTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) spin_lock(&lower_dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!qstr_case_eq(&dentry->d_name, &lower_dentry->d_name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (dentry < lower_dentry) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) spin_unlock(&lower_dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) spin_unlock(&lower_dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* If our top's inode is gone, we may be out of date */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) inode = igrab(d_inode(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) data = top_data_get(SDCARDFS_I(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (!data || data->abandoned) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) data_put(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) iput(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) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dput(parent_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) dput(lower_cur_parent_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) sdcardfs_put_lower_path(parent_dentry, &parent_lower_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) sdcardfs_put_real_lower(dentry, &lower_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* 1 = delete, 0 = cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int sdcardfs_d_delete(const struct dentry *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return SDCARDFS_SB(d->d_sb)->options.nocache ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static void sdcardfs_d_release(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (!dentry || !dentry->d_fsdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* release and reset the lower paths */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (has_graft_path(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) sdcardfs_put_reset_orig_path(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) sdcardfs_put_reset_lower_path(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) free_dentry_private_data(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static int sdcardfs_hash_ci(const struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct qstr *qstr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * This function is copy of vfat_hashi.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * FIXME Should we support national language?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * Refer to vfat_hashi()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) const unsigned char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) unsigned long hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) name = qstr->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) len = qstr->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) hash = init_name_hash(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) while (len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) hash = partial_name_hash(tolower(*name++), hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) qstr->hash = end_name_hash(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * Case insensitive compare of two vfat names.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int sdcardfs_cmp_ci(const struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) unsigned int len, const char *str, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /* FIXME Should we support national language? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (name->len == len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (str_n_case_eq(name->name, str, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static void sdcardfs_canonical_path(const struct path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct path *actual_path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) sdcardfs_get_real_lower(path->dentry, actual_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) const struct dentry_operations sdcardfs_ci_dops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .d_revalidate = sdcardfs_d_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .d_delete = sdcardfs_d_delete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .d_release = sdcardfs_d_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .d_hash = sdcardfs_hash_ci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .d_compare = sdcardfs_cmp_ci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .d_canonical_path = sdcardfs_canonical_path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)