^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/affs/namei.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * (c) 1996 Hans-Joachim Widmaier - Rewritten
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * (C) 1993 Ray Burr - Modified for Amiga FFS filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * (C) 1991 Linus Torvalds - minix filesystem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "affs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/exportfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) typedef int (*toupper_t)(int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) /* Simple toupper() for DOS\1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) affs_toupper(int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) return ch >= 'a' && ch <= 'z' ? ch -= ('a' - 'A') : ch;
^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) /* International toupper() for DOS\3 ("international") */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) affs_intl_toupper(int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return (ch >= 'a' && ch <= 'z') || (ch >= 0xE0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) && ch <= 0xFE && ch != 0xF7) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ch - ('a' - 'A') : ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static inline toupper_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) affs_get_toupper(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return affs_test_opt(AFFS_SB(sb)->s_flags, SF_INTL) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) affs_intl_toupper : affs_toupper;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Note: the dentry argument is the parent dentry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __affs_hash_dentry(const struct dentry *dentry, struct qstr *qstr, toupper_t toupper, bool notruncate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) const u8 *name = qstr->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned long hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) retval = affs_check_name(qstr->name, qstr->len, notruncate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) hash = init_name_hash(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) len = min(qstr->len, AFFSNAMEMAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) for (; len > 0; name++, len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) hash = partial_name_hash(toupper(*name), hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) qstr->hash = end_name_hash(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) affs_hash_dentry(const struct dentry *dentry, struct qstr *qstr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return __affs_hash_dentry(dentry, qstr, affs_toupper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) affs_nofilenametruncate(dentry));
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) affs_intl_hash_dentry(const struct dentry *dentry, struct qstr *qstr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return __affs_hash_dentry(dentry, qstr, affs_intl_toupper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) affs_nofilenametruncate(dentry));
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static inline int __affs_compare_dentry(unsigned int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) const char *str, const struct qstr *name, toupper_t toupper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) bool notruncate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) const u8 *aname = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) const u8 *bname = name->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * 'str' is the name of an already existing dentry, so the name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * must be valid. 'name' must be validated first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (affs_check_name(name->name, name->len, notruncate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * If the names are longer than the allowed 30 chars,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * the excess is ignored, so their length may differ.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (len >= AFFSNAMEMAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (name->len < AFFSNAMEMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) len = AFFSNAMEMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) } else if (len != name->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) for (; len > 0; len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (toupper(*aname++) != toupper(*bname++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) affs_compare_dentry(const struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) unsigned int len, const char *str, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return __affs_compare_dentry(len, str, name, affs_toupper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) affs_nofilenametruncate(dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) affs_intl_compare_dentry(const struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) unsigned int len, const char *str, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return __affs_compare_dentry(len, str, name, affs_intl_toupper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) affs_nofilenametruncate(dentry));
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * NOTE! unlike strncmp, affs_match returns 1 for success, 0 for failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) affs_match(struct dentry *dentry, const u8 *name2, toupper_t toupper)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) const u8 *name = dentry->d_name.name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int len = dentry->d_name.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (len >= AFFSNAMEMAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (*name2 < AFFSNAMEMAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) len = AFFSNAMEMAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) } else if (len != *name2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) for (name2++; len > 0; len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (toupper(*name++) != toupper(*name2++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) affs_hash_name(struct super_block *sb, const u8 *name, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) toupper_t toupper = affs_get_toupper(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u32 hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) hash = len = min(len, AFFSNAMEMAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) for (; len > 0; len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) hash = (hash * 13 + toupper(*name++)) & 0x7ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return hash % AFFS_SB(sb)->s_hashsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static struct buffer_head *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) affs_find_entry(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) toupper_t toupper = affs_get_toupper(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u32 key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) pr_debug("%s(\"%pd\")\n", __func__, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) bh = affs_bread(sb, dir->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) key = be32_to_cpu(AFFS_HEAD(bh)->table[affs_hash_name(sb, dentry->d_name.name, dentry->d_name.len)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) affs_brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (key == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) bh = affs_bread(sb, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (affs_match(dentry, AFFS_TAIL(sb, bh)->name, toupper))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) key = be32_to_cpu(AFFS_TAIL(sb, bh)->hash_chain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^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) struct dentry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) affs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct inode *inode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct dentry *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) pr_debug("%s(\"%pd\")\n", __func__, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) affs_lock_dir(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) bh = affs_find_entry(dir, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (IS_ERR(bh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) affs_unlock_dir(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) return ERR_CAST(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u32 ino = bh->b_blocknr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* store the real header ino in d_fsdata for faster lookups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) dentry->d_fsdata = (void *)(long)ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) switch (be32_to_cpu(AFFS_TAIL(sb, bh)->stype)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) //link to dirs disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) //case ST_LINKDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) case ST_LINKFILE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) ino = be32_to_cpu(AFFS_TAIL(sb, bh)->original);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) affs_brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) inode = affs_iget(sb, ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) res = d_splice_alias(inode, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (!IS_ERR_OR_NULL(res))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) res->d_fsdata = dentry->d_fsdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) affs_unlock_dir(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) affs_unlink(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) pr_debug("%s(dir=%lu, %lu \"%pd\")\n", __func__, dir->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) d_inode(dentry)->i_ino, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return affs_remove_header(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) pr_debug("%s(%lu,\"%pd\",0%ho)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) __func__, dir->i_ino, dentry, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) inode = affs_new_inode(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) inode->i_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) affs_mode_to_prot(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) inode->i_op = &affs_file_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) inode->i_fop = &affs_file_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) inode->i_mapping->a_ops = affs_test_opt(AFFS_SB(sb)->s_flags, SF_OFS) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) &affs_aops_ofs : &affs_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) error = affs_add_entry(dir, inode, dentry, ST_FILE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) clear_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) pr_debug("%s(%lu,\"%pd\",0%ho)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) __func__, dir->i_ino, dentry, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) inode = affs_new_inode(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) inode->i_mode = S_IFDIR | mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) affs_mode_to_prot(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) inode->i_op = &affs_dir_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) inode->i_fop = &affs_dir_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) error = affs_add_entry(dir, inode, dentry, ST_USERDIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) clear_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) affs_rmdir(struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) pr_debug("%s(dir=%lu, %lu \"%pd\")\n", __func__, dir->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) d_inode(dentry)->i_ino, dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return affs_remove_header(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct super_block *sb = dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int i, maxlen, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) char c, lc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) pr_debug("%s(%lu,\"%pd\" -> \"%s\")\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) __func__, dir->i_ino, dentry, symname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) maxlen = AFFS_SB(sb)->s_hashsize * sizeof(u32) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) inode = affs_new_inode(dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (!inode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) inode->i_op = &affs_symlink_inode_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) inode_nohighmem(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) inode->i_data.a_ops = &affs_symlink_aops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) inode->i_mode = S_IFLNK | 0777;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) affs_mode_to_prot(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) error = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) bh = affs_bread(sb, inode->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) p = (char *)AFFS_HEAD(bh)->table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) lc = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (*symname == '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct affs_sb_info *sbi = AFFS_SB(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) while (*symname == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) symname++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) spin_lock(&sbi->symlink_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) while (sbi->s_volume[i]) /* Cannot overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) *p++ = sbi->s_volume[i++];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) spin_unlock(&sbi->symlink_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) while (i < maxlen && (c = *symname++)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (c == '.' && lc == '/' && *symname == '.' && symname[1] == '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) *p++ = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) symname += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) lc = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) } else if (c == '.' && lc == '/' && *symname == '/') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) symname++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) lc = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) *p++ = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) lc = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (lc == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) while (*symname == '/')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) symname++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) *p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) inode->i_size = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) mark_buffer_dirty_inode(bh, inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) affs_brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) error = affs_add_entry(dir, inode, dentry, ST_SOFTLINK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) clear_nlink(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) mark_inode_dirty(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) iput(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct inode *inode = d_inode(old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) pr_debug("%s(%lu, %lu, \"%pd\")\n", __func__, inode->i_ino, dir->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return affs_add_entry(dir, inode, dentry, ST_LINKFILE);
^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) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) affs_rename(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct inode *new_dir, struct dentry *new_dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct super_block *sb = old_dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct buffer_head *bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) retval = affs_check_name(new_dentry->d_name.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) new_dentry->d_name.len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) affs_nofilenametruncate(old_dentry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* Unlink destination if it already exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (d_really_is_positive(new_dentry)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) retval = affs_remove_header(new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) bh = affs_bread(sb, d_inode(old_dentry)->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /* Remove header from its parent directory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) affs_lock_dir(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) retval = affs_remove_hash(old_dir, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) affs_unlock_dir(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* And insert it into the new directory with the new name. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) affs_copy_name(AFFS_TAIL(sb, bh)->name, new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) affs_fix_checksum(sb, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) affs_lock_dir(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) retval = affs_insert_hash(new_dir, bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) affs_unlock_dir(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* TODO: move it back to old_dir, if error? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) mark_buffer_dirty_inode(bh, retval ? old_dir : new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) affs_brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) affs_xrename(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct inode *new_dir, struct dentry *new_dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct super_block *sb = old_dir->i_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct buffer_head *bh_old = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct buffer_head *bh_new = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) bh_old = affs_bread(sb, d_inode(old_dentry)->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (!bh_old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) bh_new = affs_bread(sb, d_inode(new_dentry)->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if (!bh_new) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) affs_brelse(bh_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return -EIO;
^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) /* Remove old header from its parent directory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) affs_lock_dir(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) retval = affs_remove_hash(old_dir, bh_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) affs_unlock_dir(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /* Remove new header from its parent directory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) affs_lock_dir(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) retval = affs_remove_hash(new_dir, bh_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) affs_unlock_dir(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (retval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* Insert old into the new directory with the new name. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) affs_copy_name(AFFS_TAIL(sb, bh_old)->name, new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) affs_fix_checksum(sb, bh_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) affs_lock_dir(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) retval = affs_insert_hash(new_dir, bh_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) affs_unlock_dir(new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /* Insert new into the old directory with the old name. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) affs_copy_name(AFFS_TAIL(sb, bh_new)->name, old_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) affs_fix_checksum(sb, bh_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) affs_lock_dir(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) retval = affs_insert_hash(old_dir, bh_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) affs_unlock_dir(old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) mark_buffer_dirty_inode(bh_old, new_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) mark_buffer_dirty_inode(bh_new, old_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) affs_brelse(bh_old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) affs_brelse(bh_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) int affs_rename2(struct inode *old_dir, struct dentry *old_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct inode *new_dir, struct dentry *new_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) unsigned int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) pr_debug("%s(old=%lu,\"%pd\" to new=%lu,\"%pd\")\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) old_dir->i_ino, old_dentry, new_dir->i_ino, new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (flags & RENAME_EXCHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return affs_xrename(old_dir, old_dentry, new_dir, new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return affs_rename(old_dir, old_dentry, new_dir, new_dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static struct dentry *affs_get_parent(struct dentry *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct inode *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) bh = affs_bread(child->d_sb, d_inode(child)->i_ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (!bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return ERR_PTR(-EIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) parent = affs_iget(child->d_sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) be32_to_cpu(AFFS_TAIL(child->d_sb, bh)->parent));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (IS_ERR(parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return ERR_CAST(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return d_obtain_alias(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) static struct inode *affs_nfs_get_inode(struct super_block *sb, u64 ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) u32 generation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!affs_validblock(sb, ino))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return ERR_PTR(-ESTALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) inode = affs_iget(sb, ino);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (IS_ERR(inode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return ERR_CAST(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) return inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) static struct dentry *affs_fh_to_dentry(struct super_block *sb, struct fid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) int fh_len, int fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) affs_nfs_get_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static struct dentry *affs_fh_to_parent(struct super_block *sb, struct fid *fid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) int fh_len, int fh_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) return generic_fh_to_parent(sb, fid, fh_len, fh_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) affs_nfs_get_inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) const struct export_operations affs_export_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) .fh_to_dentry = affs_fh_to_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) .fh_to_parent = affs_fh_to_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .get_parent = affs_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) const struct dentry_operations affs_dentry_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .d_hash = affs_hash_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .d_compare = affs_compare_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) const struct dentry_operations affs_intl_dentry_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) .d_hash = affs_intl_hash_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .d_compare = affs_intl_compare_dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) };