15 static int affs_toupper(
int ch);
16 static int affs_hash_dentry(
const struct dentry *,
18 static int affs_compare_dentry(
const struct dentry *parent,
19 const struct inode *pinode,
21 unsigned int len,
const char *
str,
const struct qstr *
name);
22 static int affs_intl_toupper(
int ch);
23 static int affs_intl_hash_dentry(
const struct dentry *,
25 static int affs_intl_compare_dentry(
const struct dentry *parent,
26 const struct inode *pinode,
28 unsigned int len,
const char *
str,
const struct qstr *
name);
31 .d_hash = affs_hash_dentry,
32 .d_compare = affs_compare_dentry,
36 .d_hash = affs_intl_hash_dentry,
37 .d_compare = affs_intl_compare_dentry,
46 return ch >=
'a' && ch <=
'z' ? ch -= (
'a' -
'A') : ch;
52 affs_intl_toupper(
int ch)
54 return (ch >=
'a' && ch <=
'z') || (ch >= 0xE0
55 && ch <= 0xFE && ch != 0xF7) ?
56 ch - (
'a' -
'A') : ch;
62 return AFFS_SB(sb)->s_flags &
SF_INTL ? affs_intl_toupper : affs_toupper;
80 i =
min(qstr->len, 30
u);
81 for (; i > 0; name++, i--)
82 hash = partial_name_hash(
toupper(*name), hash);
83 qstr->hash = end_name_hash(hash);
92 return __affs_hash_dentry(qstr, affs_toupper);
98 return __affs_hash_dentry(qstr, affs_intl_toupper);
101 static inline int __affs_compare_dentry(
unsigned int len,
102 const char *
str,
const struct qstr *name,
toupper_t toupper)
104 const u8 *aname =
str;
123 }
else if (len != name->len)
126 for (; len > 0; len--)
134 affs_compare_dentry(
const struct dentry *parent,
const struct inode *pinode,
136 unsigned int len,
const char *str,
const struct qstr *name)
138 return __affs_compare_dentry(len, str, name, affs_toupper);
141 affs_intl_compare_dentry(
const struct dentry *parent,
const struct inode *pinode,
143 unsigned int len,
const char *str,
const struct qstr *name)
145 return __affs_compare_dentry(len, str, name, affs_intl_toupper);
155 const u8 *name = dentry->
d_name.name;
156 int len = dentry->
d_name.len;
162 }
else if (len != *name2)
165 for (name2++; len > 0; len--)
174 toupper_t toupper = affs_get_toupper(sb);
177 hash = len =
min(len, 30
u);
178 for (; len > 0; len--)
179 hash = (hash * 13 +
toupper(*name++)) & 0x7ff;
181 return hash % AFFS_SB(sb)->s_hashsize;
184 static struct buffer_head *
185 affs_find_entry(
struct inode *dir,
struct dentry *dentry)
188 struct buffer_head *bh;
189 toupper_t toupper = affs_get_toupper(sb);
194 bh = affs_bread(sb, dir->
i_ino);
196 return ERR_PTR(-
EIO);
204 bh = affs_bread(sb, key);
206 return ERR_PTR(-
EIO);
207 if (affs_match(dentry,
AFFS_TAIL(sb, bh)->name, toupper))
217 struct buffer_head *bh;
223 bh = affs_find_entry(dir, dentry);
224 affs_unlock_dir(dir);
241 return ERR_CAST(inode);
243 d_add(dentry, inode);
265 dentry->
d_name.name,mode);
273 mark_inode_dirty(inode);
309 mark_inode_dirty(inode);
330 struct buffer_head *bh;
336 pr_debug(
"AFFS: symlink(%lu,\"%.*s\" -> \"%s\")\n",dir->
i_ino,
339 maxlen = AFFS_SB(sb)->s_hashsize *
sizeof(
u32) - 1;
350 bh = affs_bread(sb, inode->
i_ino);
356 if (*symname ==
'/') {
358 while (*symname ==
'/')
365 while (i < maxlen && (c = *symname++)) {
366 if (c ==
'.' && lc ==
'/' && *symname ==
'.' && symname[1] ==
'/') {
371 }
else if (c ==
'.' && lc ==
'/' && *symname ==
'/') {
380 while (*symname ==
'/')
386 mark_inode_dirty(inode);
396 mark_inode_dirty(inode);
414 struct inode *new_dir,
struct dentry *new_dentry)
417 struct buffer_head *bh =
NULL;
420 pr_debug(
"AFFS: rename(old=%u,\"%*s\" to new=%u,\"%*s\")\n",
435 bh = affs_bread(sb, old_dentry->
d_inode->i_ino);
440 affs_lock_dir(old_dir);
442 affs_unlock_dir(old_dir);
449 affs_lock_dir(new_dir);
451 affs_unlock_dir(new_dir);