^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/vfat/namei.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written 1992,1993 by Werner Almesberger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Windows95/Windows NT compatible extended MSDOS filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * by Gordon Chaffee Copyright (C) 1995. Send bug reports for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * VFAT filesystem to <chaffee@cs.berkeley.edu>. Specify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * what file operation caused you trouble and if you can duplicate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * the problem, send a script that demonstrates it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Short name translation 1999, 2001 by Wolfram Pienkoss <wp@bszh.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Support Multibyte characters and cleanup by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/iversion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "fat.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static inline unsigned long vfat_d_version(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return (unsigned long) dentry->d_fsdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static inline void vfat_d_version_set(struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned long version)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) dentry->d_fsdata = (void *) version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * If new entry was created in the parent, it could create the 8.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * alias (the shortname of logname). So, the parent may have the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * negative-dentry which matches the created 8.3 alias.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * If it happened, the negative dentry isn't actually negative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * anymore. So, drop it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int vfat_revalidate_shortname(struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) int ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) spin_lock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (!inode_eq_iversion(d_inode(dentry->d_parent), vfat_d_version(dentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) spin_unlock(&dentry->d_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static int vfat_revalidate(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* This is not negative dentry. Always valid. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (d_really_is_positive(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return vfat_revalidate_shortname(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int vfat_revalidate_ci(struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (flags & LOOKUP_RCU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -ECHILD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * This is not negative dentry. Always valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Note, rename() to existing directory entry will have ->d_inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * and will use existing name which isn't specified name by user.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * We may be able to drop this positive dentry here. But dropping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * positive dentry isn't good idea. So it's unsupported like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * rename("filename", "FILENAME") for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (d_really_is_positive(dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * This may be nfsd (or something), anyway, we can't see the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * intent of this. So, since this can be for creation, drop it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * Drop the negative dentry, in order to make sure to use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * case sensitive name which is specified by user if this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * for creation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return vfat_revalidate_shortname(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* returns the length of a struct qstr, ignoring trailing dots */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static unsigned int __vfat_striptail_len(unsigned int len, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) while (len && name[len - 1] == '.')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static unsigned int vfat_striptail_len(const struct qstr *qstr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return __vfat_striptail_len(qstr->len, qstr->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Compute the hash for the vfat name corresponding to the dentry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * Note: if the name is invalid, we leave the hash code unchanged so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) * that the existing dentry can be used. The vfat fs routines will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * return ENOENT or EINVAL as appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static int vfat_hash(const struct dentry *dentry, struct qstr *qstr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) qstr->hash = full_name_hash(dentry, qstr->name, vfat_striptail_len(qstr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Compute the hash for the vfat name corresponding to the dentry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Note: if the name is invalid, we leave the hash code unchanged so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * that the existing dentry can be used. The vfat fs routines will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * return ENOENT or EINVAL as appropriate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int vfat_hashi(const struct dentry *dentry, struct qstr *qstr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) const unsigned char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) unsigned long hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) name = qstr->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) len = vfat_striptail_len(qstr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) hash = init_name_hash(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) while (len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) hash = partial_name_hash(nls_tolower(t, *name++), hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) qstr->hash = end_name_hash(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * Case insensitive compare of two vfat names.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static int vfat_cmpi(const struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned int len, const char *str, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned int alen, blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* A filename cannot end in '.' or we treat it like it has none */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) alen = vfat_striptail_len(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) blen = __vfat_striptail_len(len, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (alen == blen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (nls_strnicmp(t, name->name, str, alen) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * Case sensitive compare of two vfat names.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static int vfat_cmp(const struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) unsigned int len, const char *str, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) unsigned int alen, blen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* A filename cannot end in '.' or we treat it like it has none */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) alen = vfat_striptail_len(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) blen = __vfat_striptail_len(len, str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (alen == blen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (strncmp(name->name, str, alen) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static const struct dentry_operations vfat_ci_dentry_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .d_revalidate = vfat_revalidate_ci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .d_hash = vfat_hashi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) .d_compare = vfat_cmpi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static const struct dentry_operations vfat_dentry_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) .d_revalidate = vfat_revalidate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) .d_hash = vfat_hash,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) .d_compare = vfat_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* Characters that are undesirable in an MS-DOS file name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static inline wchar_t vfat_bad_char(wchar_t w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return (w < 0x0020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) || (w == '*') || (w == '?') || (w == '<') || (w == '>')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) || (w == '|') || (w == '"') || (w == ':') || (w == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) || (w == '\\');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static inline wchar_t vfat_replace_char(wchar_t w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return (w == '[') || (w == ']') || (w == ';') || (w == ',')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) || (w == '+') || (w == '=');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static wchar_t vfat_skip_char(wchar_t w)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) return (w == '.') || (w == ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static inline int vfat_is_used_badchars(const wchar_t *s, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) for (i = 0; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) if (vfat_bad_char(s[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (s[i - 1] == ' ') /* last character cannot be space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int vfat_find_form(struct inode *dir, unsigned char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct fat_slot_info sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) int err = fat_scan(dir, name, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) brelse(sinfo.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return 0;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * 1) Valid characters for the 8.3 format alias are any combination of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * letters, uppercase alphabets, digits, any of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * following special characters:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * $ % ' ` - @ { } ~ ! # ( ) & _ ^
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * In this case Longfilename is not stored in disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * WinNT's Extension:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * File name and extension name is contain uppercase/lowercase
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * only. And it is expressed by CASE_LOWER_BASE and CASE_LOWER_EXT.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * 2) File name is 8.3 format, but it contain the uppercase and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * lowercase char, muliti bytes char, etc. In this case numtail is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * added, but Longfilename is stored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) * 3) When the one except for the above, or the following special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * character are contained:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * . [ ] ; , + =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * numtail is added, and Longfilename must be stored in disk .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct shortname_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) unsigned char lower:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) upper:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) valid:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) #define INIT_SHORTNAME_INFO(x) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) (x)->lower = 1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) (x)->upper = 1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) (x)->valid = 1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static inline int to_shortname_char(struct nls_table *nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) unsigned char *buf, int buf_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) wchar_t *src, struct shortname_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (vfat_skip_char(*src)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) info->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (vfat_replace_char(*src)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) info->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) buf[0] = '_';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) len = nls->uni2char(*src, buf, buf_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) if (len <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) info->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) buf[0] = '_';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) } else if (len == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) unsigned char prev = buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (buf[0] >= 0x7F) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) info->lower = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) info->upper = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) buf[0] = nls_toupper(nls, buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (isalpha(buf[0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if (buf[0] == prev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) info->lower = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) info->upper = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) info->lower = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) info->upper = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * Given a valid longname, create a unique shortname. Make sure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * shortname does not exist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * Returns negative number on error, 0 for a normal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * return, and 1 for valid shortname
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int vfat_create_shortname(struct inode *dir, struct nls_table *nls,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) wchar_t *uname, int ulen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) unsigned char *name_res, unsigned char *lcase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct fat_mount_options *opts = &MSDOS_SB(dir->i_sb)->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) wchar_t *ip, *ext_start, *end, *name_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) unsigned char base[9], ext[4], buf[5], *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) unsigned char charbuf[NLS_MAX_CHARSET_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int chl, chi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) int sz = 0, extlen, baselen, i, numtail_baselen, numtail2_baselen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int is_shortname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct shortname_info base_info, ext_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) is_shortname = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) INIT_SHORTNAME_INFO(&base_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) INIT_SHORTNAME_INFO(&ext_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* Now, we need to create a shortname from the long name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) ext_start = end = &uname[ulen];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) while (--ext_start >= uname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (*ext_start == 0x002E) { /* is `.' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (ext_start == end - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) sz = ulen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ext_start = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (ext_start == uname - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) sz = ulen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ext_start = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) } else if (ext_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * Names which start with a dot could be just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * an extension eg. "...test". In this case Win95
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * uses the extension as the name and sets no extension.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) name_start = &uname[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) while (name_start < ext_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (!vfat_skip_char(*name_start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) name_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (name_start != ext_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) sz = ext_start - uname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ext_start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) sz = ulen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ext_start = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) numtail_baselen = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) numtail2_baselen = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) for (baselen = i = 0, p = base, ip = uname; i < sz; i++, ip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) chl = to_shortname_char(nls, charbuf, sizeof(charbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ip, &base_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (chl == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (baselen < 2 && (baselen + chl) > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) numtail2_baselen = baselen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (baselen < 6 && (baselen + chl) > 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) numtail_baselen = baselen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) for (chi = 0; chi < chl; chi++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) *p++ = charbuf[chi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) baselen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (baselen >= 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (baselen >= 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if ((chi < chl - 1) || (ip + 1) - uname < sz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) is_shortname = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (baselen == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) extlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (ext_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) for (p = ext, ip = ext_start; extlen < 3 && ip < end; ip++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) chl = to_shortname_char(nls, charbuf, sizeof(charbuf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ip, &ext_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (chl == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if ((extlen + chl) > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) is_shortname = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) for (chi = 0; chi < chl; chi++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *p++ = charbuf[chi];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) extlen++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (extlen >= 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (ip + 1 != end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) is_shortname = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ext[extlen] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) base[baselen] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* Yes, it can happen. ".\xe5" would do it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (base[0] == DELETED_FLAG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) base[0] = 0x05;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /* OK, at this point we know that base is not longer than 8 symbols,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * ext is not longer than 3, base is nonempty, both don't contain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) * any bad symbols (lowercase transformed to uppercase).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) memset(name_res, ' ', MSDOS_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) memcpy(name_res, base, baselen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) memcpy(name_res + 8, ext, extlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) *lcase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (is_shortname && base_info.valid && ext_info.valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (vfat_find_form(dir, name_res) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (opts->shortname & VFAT_SFN_CREATE_WIN95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return (base_info.upper && ext_info.upper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) } else if (opts->shortname & VFAT_SFN_CREATE_WINNT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if ((base_info.upper || base_info.lower) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) (ext_info.upper || ext_info.lower)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (!base_info.upper && base_info.lower)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) *lcase |= CASE_LOWER_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (!ext_info.upper && ext_info.lower)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) *lcase |= CASE_LOWER_EXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (opts->numtail == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (vfat_find_form(dir, name_res) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * Try to find a unique extension. This used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * iterate through all possibilities sequentially,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * but that gave extremely bad performance. Windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) * only tries a few cases before using random
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * values for part of the base.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (baselen > 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) baselen = numtail_baselen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) name_res[7] = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) name_res[baselen] = '~';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) for (i = 1; i < 10; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) name_res[baselen + 1] = i + '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (vfat_find_form(dir, name_res) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) i = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) sz = (jiffies >> 16) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (baselen > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) baselen = numtail2_baselen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) name_res[7] = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) name_res[baselen + 4] = '~';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) name_res[baselen + 5] = '1' + sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) snprintf(buf, sizeof(buf), "%04X", i & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) memcpy(&name_res[baselen], buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (vfat_find_form(dir, name_res) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) i -= 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* Translate a string, including coded sequences into Unicode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) int *longlen, int *outlen, int escape, int utf8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct nls_table *nls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) const unsigned char *ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) unsigned char *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int i, fill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) int charlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (utf8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) *outlen = utf8s_to_utf16s(name, len, UTF16_HOST_ENDIAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) (wchar_t *) outname, FAT_LFN_LEN + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (*outlen < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return *outlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) else if (*outlen > FAT_LFN_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) op = &outname[*outlen * sizeof(wchar_t)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) for (i = 0, ip = name, op = outname, *outlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) i < len && *outlen < FAT_LFN_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) *outlen += 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (escape && (*ip == ':')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) u8 uc[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (i > len - 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (hex2bin(uc, ip + 1, 2) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) *(wchar_t *)op = uc[0] << 8 | uc[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) op += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ip += 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) i += 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) charlen = nls->char2uni(ip, len - i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) (wchar_t *)op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (charlen < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ip += charlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) i += charlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) op += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (i < len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) *longlen = *outlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) if (*outlen % 13) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) *op++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) *op++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) *outlen += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (*outlen % 13) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) fill = 13 - (*outlen % 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) for (i = 0; i < fill; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) *op++ = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) *op++ = 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) *outlen += fill;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static int vfat_build_slots(struct inode *dir, const unsigned char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) int len, int is_dir, int cluster,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct timespec64 *ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) struct msdos_dir_slot *slots, int *nr_slots)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct fat_mount_options *opts = &sbi->options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct msdos_dir_slot *ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct msdos_dir_entry *de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) unsigned char cksum, lcase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) unsigned char msdos_name[MSDOS_NAME];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) wchar_t *uname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) __le16 time, date;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) u8 time_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) int err, ulen, usize, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) loff_t offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) *nr_slots = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) uname = __getname();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (!uname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) err = xlate_to_uni(name, len, (unsigned char *)uname, &ulen, &usize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) opts->unicode_xlate, opts->utf8, sbi->nls_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) err = vfat_is_used_badchars(uname, ulen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) err = vfat_create_shortname(dir, sbi->nls_disk, uname, ulen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) msdos_name, &lcase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) else if (err == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) de = (struct msdos_dir_entry *)slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) goto shortname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /* build the entry of long file name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) cksum = fat_checksum(msdos_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) *nr_slots = usize / 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) for (ps = slots, i = *nr_slots; i > 0; i--, ps++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ps->id = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ps->attr = ATTR_EXT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) ps->reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ps->alias_checksum = cksum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) ps->start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) offset = (i - 1) * 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) fatwchar_to16(ps->name0_4, uname + offset, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) fatwchar_to16(ps->name5_10, uname + offset + 5, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) fatwchar_to16(ps->name11_12, uname + offset + 11, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) slots[0].id |= 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) de = (struct msdos_dir_entry *)ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) shortname:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* build the entry of 8.3 alias name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) (*nr_slots)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) memcpy(de->name, msdos_name, MSDOS_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) de->attr = is_dir ? ATTR_DIR : ATTR_ARCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) de->lcase = lcase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) fat_time_unix2fat(sbi, ts, &time, &date, &time_cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) de->time = de->ctime = time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) de->date = de->cdate = de->adate = date;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) de->ctime_cs = time_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) fat_set_start(de, cluster);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) de->size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) __putname(uname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) static int vfat_add_entry(struct inode *dir, const struct qstr *qname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) int is_dir, int cluster, struct timespec64 *ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) struct fat_slot_info *sinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct msdos_dir_slot *slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) int err, nr_slots;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) len = vfat_striptail_len(qname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) slots = kmalloc_array(MSDOS_SLOTS, sizeof(*slots), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (slots == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) err = vfat_build_slots(dir, qname->name, len, is_dir, cluster, ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) slots, &nr_slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) err = fat_add_entries(dir, slots, nr_slots, sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) /* update timestamp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) fat_truncate_time(dir, ts, S_CTIME|S_MTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (IS_DIRSYNC(dir))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) (void)fat_sync_inode(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) mark_inode_dirty(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) kfree(slots);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int vfat_find(struct inode *dir, const struct qstr *qname,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct fat_slot_info *sinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) unsigned int len = vfat_striptail_len(qname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return fat_search_long(dir, qname->name, len, sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static struct dentry *vfat_lookup(struct inode *dir, struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct fat_slot_info sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct dentry *alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) mutex_lock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) err = vfat_find(dir, &dentry->d_name, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (err == -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) brelse(sinfo.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) err = PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) alias = d_find_alias(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) * Checking "alias->d_parent == dentry->d_parent" to make sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) * FS is not corrupted (especially double linked dir).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (alias && alias->d_parent == dentry->d_parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * This inode has non anonymous-DCACHE_DISCONNECTED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * dentry. This means, the user did ->lookup() by an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * another name (longname vs 8.3 alias of it) in past.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * Switch to new one for reason of locality if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (!S_ISDIR(inode->i_mode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) d_move(alias, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) mutex_unlock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dput(alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) mutex_unlock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) vfat_d_version_set(dentry, inode_query_iversion(dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) mutex_unlock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) bool excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) struct fat_slot_info sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct timespec64 ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) mutex_lock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ts = current_time(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) inode_inc_iversion(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) brelse(sinfo.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) err = PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) inode_inc_iversion(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* timestamp is already written, so mark_inode_dirty() is unneeded. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) d_instantiate(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) mutex_unlock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static int vfat_rmdir(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct fat_slot_info sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) mutex_lock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) err = fat_dir_empty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) err = vfat_find(dir, &dentry->d_name, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) err = fat_remove_entries(dir, &sinfo); /* and releases bh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) drop_nlink(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) clear_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) fat_truncate_time(inode, NULL, S_ATIME|S_MTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) fat_detach(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) vfat_d_version_set(dentry, inode_query_iversion(dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) mutex_unlock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) static int vfat_unlink(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct inode *inode = d_inode(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct fat_slot_info sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) mutex_lock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) err = vfat_find(dir, &dentry->d_name, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) err = fat_remove_entries(dir, &sinfo); /* and releases bh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) clear_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) fat_truncate_time(inode, NULL, S_ATIME|S_MTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) fat_detach(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) vfat_d_version_set(dentry, inode_query_iversion(dir));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) mutex_unlock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct fat_slot_info sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct timespec64 ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) int err, cluster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) mutex_lock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) ts = current_time(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) cluster = fat_alloc_new_dir(dir, &ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (cluster < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) err = cluster;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) err = vfat_add_entry(dir, &dentry->d_name, 1, cluster, &ts, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) inode_inc_iversion(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) inc_nlink(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) brelse(sinfo.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (IS_ERR(inode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) err = PTR_ERR(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /* the directory was completed, just return a error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) inode_inc_iversion(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) set_nlink(inode, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* timestamp is already written, so mark_inode_dirty() is unneeded. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) d_instantiate(dentry, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) mutex_unlock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) fat_free_clusters(dir, cluster);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) mutex_unlock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct inode *new_dir, struct dentry *new_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct buffer_head *dotdot_bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) struct msdos_dir_entry *dotdot_de;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct inode *old_inode, *new_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct fat_slot_info old_sinfo, sinfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct timespec64 ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) loff_t new_i_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) int err, is_dir, update_dotdot, corrupt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) struct super_block *sb = old_dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (flags & ~RENAME_NOREPLACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) old_sinfo.bh = sinfo.bh = dotdot_bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) old_inode = d_inode(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) new_inode = d_inode(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) mutex_lock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) err = vfat_find(old_dir, &old_dentry->d_name, &old_sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) is_dir = S_ISDIR(old_inode->i_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) update_dotdot = (is_dir && old_dir != new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (update_dotdot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) ts = current_time(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (new_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (is_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) err = fat_dir_empty(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) new_i_pos = MSDOS_I(new_inode)->i_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) fat_detach(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) err = vfat_add_entry(new_dir, &new_dentry->d_name, is_dir, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) &ts, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) new_i_pos = sinfo.i_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) inode_inc_iversion(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) fat_detach(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) fat_attach(old_inode, new_i_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (IS_DIRSYNC(new_dir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) err = fat_sync_inode(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) goto error_inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) mark_inode_dirty(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (update_dotdot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) fat_set_start(dotdot_de, MSDOS_I(new_dir)->i_logstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) mark_buffer_dirty_inode(dotdot_bh, old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (IS_DIRSYNC(new_dir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) err = sync_dirty_buffer(dotdot_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) goto error_dotdot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) drop_nlink(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (!new_inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) inc_nlink(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) err = fat_remove_entries(old_dir, &old_sinfo); /* and releases bh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) old_sinfo.bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) goto error_dotdot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) inode_inc_iversion(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) fat_truncate_time(old_dir, &ts, S_CTIME|S_MTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) if (IS_DIRSYNC(old_dir))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) (void)fat_sync_inode(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) mark_inode_dirty(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (new_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) drop_nlink(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (is_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) drop_nlink(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) fat_truncate_time(new_inode, &ts, S_CTIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) brelse(sinfo.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) brelse(dotdot_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) brelse(old_sinfo.bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) mutex_unlock(&MSDOS_SB(sb)->s_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) error_dotdot:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* data cluster is shared, serious corruption */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) corrupt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (update_dotdot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) fat_set_start(dotdot_de, MSDOS_I(old_dir)->i_logstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) mark_buffer_dirty_inode(dotdot_bh, old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) corrupt |= sync_dirty_buffer(dotdot_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) error_inode:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) fat_detach(old_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) fat_attach(old_inode, old_sinfo.i_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (new_inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) fat_attach(new_inode, new_i_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (corrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) corrupt |= fat_sync_inode(new_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * If new entry was not sharing the data cluster, it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * shouldn't be serious corruption.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) int err2 = fat_remove_entries(new_dir, &sinfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (corrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) corrupt |= err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) sinfo.bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (corrupt < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) fat_fs_error(new_dir->i_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) "%s: Filesystem corrupted (i_pos %lld)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) __func__, sinfo.i_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) static const struct inode_operations vfat_dir_inode_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) .create = vfat_create,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) .lookup = vfat_lookup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) .unlink = vfat_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) .mkdir = vfat_mkdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) .rmdir = vfat_rmdir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) .rename = vfat_rename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) .setattr = fat_setattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) .getattr = fat_getattr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) .update_time = fat_update_time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static void setup(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) MSDOS_SB(sb)->dir_ops = &vfat_dir_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (MSDOS_SB(sb)->options.name_check != 's')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) sb->s_d_op = &vfat_ci_dentry_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) sb->s_d_op = &vfat_dentry_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) static int vfat_fill_super(struct super_block *sb, void *data, int silent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return fat_fill_super(sb, data, silent, 1, setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) static struct dentry *vfat_mount(struct file_system_type *fs_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) int flags, const char *dev_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) return mount_bdev(fs_type, flags, dev_name, data, vfat_fill_super);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) static struct file_system_type vfat_fs_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) .name = "vfat",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) .mount = vfat_mount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) .kill_sb = kill_block_super,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .fs_flags = FS_REQUIRES_DEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) MODULE_ALIAS_FS("vfat");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) static int __init init_vfat_fs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return register_filesystem(&vfat_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) static void __exit exit_vfat_fs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) unregister_filesystem(&vfat_fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) MODULE_DESCRIPTION("VFAT filesystem support");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) MODULE_AUTHOR("Gordon Chaffee");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) module_init(init_vfat_fs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) module_exit(exit_vfat_fs)