Check in case folding support
[ext4-patch-queue.git] / support-case-insensitive-file-name-lookups
blob32d81702c447691a04735634e89e1c7aa307f70c
1 ext4: Support case-insensitive file name lookups
3 From: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
5 This patch implements the actual support for case-insensitive file name
6 lookups in ext4, based on the feature bit and the encoding stored in the
7 superblock.
9 A filesystem that has the fname_encoding feature set is able to
10 configure directories with the +F (EXT4_CASEFOLD_FL) attribute, enabling
11 lookups to succeed in that directory in a case-insensitive fashion, i.e:
12 match a directory entry even if the name used by userspace is not a byte
13 per byte match with the disk name, but is an equivalent case-insensitive
14 version of the Unicode string.  This operation is called a
15 case-insensitive file name lookup.
17 The feature is configured as an inode attribute applied to directories
18 and inherited by its children.  This attribute can only be enabled on
19 empty directories for filesystems that support the encoding feature,
20 thus preventing collision of file names that only differ by case.
22 * dcache handling:
24 For a +F directory, Ext4 only stores the first equivalent name dentry
25 used in the dcache. This is done to prevent unintentional duplication of
26 dentries in the dcache, while also allowing the VFS code to quickly find
27 the right entry in the cache despite which equivalent string was used in
28 a previous lookup, without having to resort to ->lookup().
30 d_hash() of casefolded directories is implemented as the hash of the
31 casefolded string, such that we always have a well-known bucket for all
32 the equivalencies of the same string. d_compare() uses the
33 utf8_strncasecmp() infrastructure, which handles the comparison of
34 equivalent, same case, names as well.
36 For now, negative lookups are not inserted in the dcache, since they
37 would need to be invalidated anyway, because we can't trust missing file
38 dentries.  This is bad for performance but requires some leveraging of
39 the vfs layer to fix.  We can live without that for now, and so does
40 everyone else.
42 * on-disk data:
44 Despite using a specific version of the name as the internal
45 representation within the dcache, the name stored and fetched from the
46 disk is a byte-per-byte match with what the user requested, making this
47 implementation 'name-preserving'. i.e. no actual information is lost
48 when writing to storage.
50 DX is supported by modifying the hashes used in +F directories to make
51 them case/encoding-aware.  The new disk hashes are calculated as the
52 hash of the full casefolded string, instead of the string directly.
53 This allows us to efficiently search for file names in the htree without
54 requiring the user to provide an exact name.
56 * Dealing with invalid sequences:
58 By default, when a invalid UTF-8 sequence is identified, ext4 will treat
59 it as an opaque byte sequence, ignoring the encoding and reverting to
60 the old behavior for that unique file.  This means that case-insensitive
61 file name lookup will not work only for that file.  An optional bit can
62 be set in the superblock telling the filesystem code and userspace tools
63 to enforce the encoding.  When that optional bit is set, any attempt to
64 create a file name using an invalid UTF-8 sequence will fail and return
65 an error to userspace.
67 * Normalization algorithm:
69 The UTF-8 algorithms used to compare strings in ext4 is implemented
70 lives in fs/unicode, and is based on a previous version developed by
71 SGI.  It implements the Canonical decomposition (NFD) algorithm
72 described by the Unicode specification 12.1, or higher, combined with
73 the elimination of ignorable code points (NFDi) and full
74 case-folding (CF) as documented in fs/unicode/utf8_norm.c.
76 NFD seems to be the best normalization method for EXT4 because:
78   - It has a lower cost than NFC/NFKC (which requires
79     decomposing to NFD as an intermediary step)
80   - It doesn't eliminate important semantic meaning like
81     compatibility decompositions.
83 Although:
85   - This implementation is not completely linguistic accurate, because
86   different languages have conflicting rules, which would require the
87   specialization of the filesystem to a given locale, which brings all
88   sorts of problems for removable media and for users who use more than
89   one language.
91 Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.co.uk>
92 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
93 ---
94  fs/ext4/dir.c      |  48 +++++++++++++++++++++++++++++++++++
95  fs/ext4/ext4.h     |  21 ++++++++++-----
96  fs/ext4/hash.c     |  34 ++++++++++++++++++++++++-
97  fs/ext4/ialloc.c   |   2 +-
98  fs/ext4/inline.c   |   2 +-
99  fs/ext4/inode.c    |   4 ++-
100  fs/ext4/ioctl.c    |  18 +++++++++++++
101  fs/ext4/namei.c    | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
102  fs/ext4/super.c    |   6 +++++
103  include/linux/fs.h |   2 ++
104  10 files changed, 223 insertions(+), 21 deletions(-)
106 diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
107 index 0ccd51f72048..884a6e776809 100644
108 --- a/fs/ext4/dir.c
109 +++ b/fs/ext4/dir.c
110 @@ -26,6 +26,7 @@
111  #include <linux/buffer_head.h>
112  #include <linux/slab.h>
113  #include <linux/iversion.h>
114 +#include <linux/unicode.h>
115  #include "ext4.h"
116  #include "xattr.h"
118 @@ -660,3 +661,50 @@ const struct file_operations ext4_dir_operations = {
119         .open           = ext4_dir_open,
120         .release        = ext4_release_dir,
121  };
123 +#ifdef CONFIG_UNICODE
124 +static int ext4_d_compare(const struct dentry *dentry, unsigned int len,
125 +                         const char *str, const struct qstr *name)
127 +       struct qstr qstr = {.name = str, .len = len };
129 +       if (!IS_CASEFOLDED(dentry->d_parent->d_inode)) {
130 +               if (len != name->len)
131 +                       return -1;
132 +               return !memcmp(str, name, len);
133 +       }
135 +       return ext4_ci_compare(dentry->d_parent->d_inode, name, &qstr);
138 +static int ext4_d_hash(const struct dentry *dentry, struct qstr *str)
140 +       const struct ext4_sb_info *sbi = EXT4_SB(dentry->d_sb);
141 +       const struct unicode_map *um = sbi->s_encoding;
142 +       unsigned char *norm;
143 +       int len, ret = 0;
145 +       if (!IS_CASEFOLDED(dentry->d_inode))
146 +               return 0;
148 +       norm = kmalloc(PATH_MAX, GFP_ATOMIC);
149 +       if (!norm)
150 +               return -ENOMEM;
152 +       len = utf8_casefold(um, str, norm, PATH_MAX);
153 +       if (len < 0) {
154 +               if (ext4_has_strict_mode(sbi))
155 +                       ret = -EINVAL;
156 +               goto out;
157 +       }
158 +       str->hash = full_name_hash(dentry, norm, len);
159 +out:
160 +       kfree(norm);
161 +       return ret;
164 +const struct dentry_operations ext4_dentry_ops = {
165 +       .d_hash = ext4_d_hash,
166 +       .d_compare = ext4_d_compare,
168 +#endif
169 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
170 index 2219b4f4a593..dc0d4b4a0119 100644
171 --- a/fs/ext4/ext4.h
172 +++ b/fs/ext4/ext4.h
173 @@ -399,10 +399,11 @@ struct flex_groups {
174  #define EXT4_EOFBLOCKS_FL              0x00400000 /* Blocks allocated beyond EOF */
175  #define EXT4_INLINE_DATA_FL            0x10000000 /* Inode has inline data. */
176  #define EXT4_PROJINHERIT_FL            0x20000000 /* Create with parents projid */
177 +#define EXT4_CASEFOLD_FL               0x40000000 /* Casefolded file */
178  #define EXT4_RESERVED_FL               0x80000000 /* reserved for ext4 lib */
180 -#define EXT4_FL_USER_VISIBLE           0x304BDFFF /* User visible flags */
181 -#define EXT4_FL_USER_MODIFIABLE                0x204BC0FF /* User modifiable flags */
182 +#define EXT4_FL_USER_VISIBLE           0x704BDFFF /* User visible flags */
183 +#define EXT4_FL_USER_MODIFIABLE                0x604BC0FF /* User modifiable flags */
185  /* Flags we can manipulate with through EXT4_IOC_FSSETXATTR */
186  #define EXT4_FL_XFLAG_VISIBLE          (EXT4_SYNC_FL | \
187 @@ -417,10 +418,10 @@ struct flex_groups {
188                            EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\
189                            EXT4_NOCOMPR_FL | EXT4_JOURNAL_DATA_FL |\
190                            EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL |\
191 -                          EXT4_PROJINHERIT_FL)
192 +                          EXT4_PROJINHERIT_FL | EXT4_CASEFOLD_FL)
194  /* Flags that are appropriate for regular files (all but dir-specific ones). */
195 -#define EXT4_REG_FLMASK (~(EXT4_DIRSYNC_FL | EXT4_TOPDIR_FL))
196 +#define EXT4_REG_FLMASK (~(EXT4_DIRSYNC_FL | EXT4_TOPDIR_FL | EXT4_CASEFOLD_FL))
198  /* Flags that are appropriate for non-directories/regular files. */
199  #define EXT4_OTHER_FLMASK (EXT4_NODUMP_FL | EXT4_NOATIME_FL)
200 @@ -2393,8 +2394,8 @@ extern int ext4_check_all_de(struct inode *dir, struct buffer_head *bh,
201  extern int ext4_sync_file(struct file *, loff_t, loff_t, int);
203  /* hash.c */
204 -extern int ext4fs_dirhash(const char *name, int len, struct
205 -                         dx_hash_info *hinfo);
206 +extern int ext4fs_dirhash(const struct inode *dir, const char *name, int len,
207 +                         struct dx_hash_info *hinfo);
209  /* ialloc.c */
210  extern struct inode *__ext4_new_inode(handle_t *, struct inode *, umode_t,
211 @@ -2990,6 +2991,10 @@ static inline void ext4_unlock_group(struct super_block *sb,
212  /* dir.c */
213  extern const struct file_operations ext4_dir_operations;
215 +#ifdef CONFIG_UNICODE
216 +extern const struct dentry_operations ext4_dentry_ops;
217 +#endif
219  /* file.c */
220  extern const struct inode_operations ext4_file_inode_operations;
221  extern const struct file_operations ext4_file_operations;
222 @@ -3082,6 +3087,10 @@ extern void initialize_dirent_tail(struct ext4_dir_entry_tail *t,
223  extern int ext4_handle_dirty_dirent_node(handle_t *handle,
224                                          struct inode *inode,
225                                          struct buffer_head *bh);
226 +extern int ext4_ci_compare(const struct inode *parent,
227 +                          const struct qstr *name,
228 +                          const struct qstr *entry);
230  #define S_SHIFT 12
231  static const unsigned char ext4_type_by_mode[(S_IFMT >> S_SHIFT) + 1] = {
232         [S_IFREG >> S_SHIFT]    = EXT4_FT_REG_FILE,
233 diff --git a/fs/ext4/hash.c b/fs/ext4/hash.c
234 index 46b24da33a28..d358bfcb6b3f 100644
235 --- a/fs/ext4/hash.c
236 +++ b/fs/ext4/hash.c
237 @@ -6,6 +6,7 @@
238   */
240  #include <linux/fs.h>
241 +#include <linux/unicode.h>
242  #include <linux/compiler.h>
243  #include <linux/bitops.h>
244  #include "ext4.h"
245 @@ -196,7 +197,8 @@ static void str2hashbuf_unsigned(const char *msg, int len, __u32 *buf, int num)
246   * represented, and whether or not the returned hash is 32 bits or 64
247   * bits.  32 bit hashes will return 0 for the minor hash.
248   */
249 -int ext4fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
250 +static int __ext4fs_dirhash(const char *name, int len,
251 +                           struct dx_hash_info *hinfo)
253         __u32   hash;
254         __u32   minor_hash = 0;
255 @@ -268,3 +270,33 @@ int ext4fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo)
256         hinfo->minor_hash = minor_hash;
257         return 0;
260 +int ext4fs_dirhash(const struct inode *dir, const char *name, int len,
261 +                  struct dx_hash_info *hinfo)
263 +#ifdef CONFIG_UNICODE
264 +       const struct unicode_map *um = EXT4_SB(dir->i_sb)->s_encoding;
265 +       int r, dlen;
266 +       unsigned char *buff;
267 +       struct qstr qstr = {.name = name, .len = len };
269 +       if (len && IS_CASEFOLDED(dir)) {
270 +               buff = kzalloc(sizeof(char) * PATH_MAX, GFP_KERNEL);
271 +               if (!buff)
272 +                       return -ENOMEM;
274 +               dlen = utf8_casefold(um, &qstr, buff, PATH_MAX);
275 +               if (dlen < 0) {
276 +                       kfree(buff);
277 +                       goto opaque_seq;
278 +               }
280 +               r = __ext4fs_dirhash(buff, dlen, hinfo);
282 +               kfree(buff);
283 +               return r;
284 +       }
285 +opaque_seq:
286 +#endif
287 +       return __ext4fs_dirhash(name, len, hinfo);
289 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
290 index f3e17a8c84b4..764ff4c56233 100644
291 --- a/fs/ext4/ialloc.c
292 +++ b/fs/ext4/ialloc.c
293 @@ -455,7 +455,7 @@ static int find_group_orlov(struct super_block *sb, struct inode *parent,
294                 if (qstr) {
295                         hinfo.hash_version = DX_HASH_HALF_MD4;
296                         hinfo.seed = sbi->s_hash_seed;
297 -                       ext4fs_dirhash(qstr->name, qstr->len, &hinfo);
298 +                       ext4fs_dirhash(parent, qstr->name, qstr->len, &hinfo);
299                         grp = hinfo.hash;
300                 } else
301                         grp = prandom_u32();
302 diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
303 index 56f6e1782d5f..f73bc3925282 100644
304 --- a/fs/ext4/inline.c
305 +++ b/fs/ext4/inline.c
306 @@ -1407,7 +1407,7 @@ int htree_inlinedir_to_tree(struct file *dir_file,
307                         }
308                 }
310 -               ext4fs_dirhash(de->name, de->name_len, hinfo);
311 +               ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
312                 if ((hinfo->hash < start_hash) ||
313                     ((hinfo->hash == start_hash) &&
314                      (hinfo->minor_hash < start_minor_hash)))
315 diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
316 index 609c8366d029..82298c63ea6d 100644
317 --- a/fs/ext4/inode.c
318 +++ b/fs/ext4/inode.c
319 @@ -4742,9 +4742,11 @@ void ext4_set_inode_flags(struct inode *inode)
320                 new_fl |= S_DAX;
321         if (flags & EXT4_ENCRYPT_FL)
322                 new_fl |= S_ENCRYPTED;
323 +       if (flags & EXT4_CASEFOLD_FL)
324 +               new_fl |= S_CASEFOLD;
325         inode_set_flags(inode, new_fl,
326                         S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX|
327 -                       S_ENCRYPTED);
328 +                       S_ENCRYPTED|S_CASEFOLD);
331  static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
332 diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
333 index 20faa6a69238..e14e6c5ede9d 100644
334 --- a/fs/ext4/ioctl.c
335 +++ b/fs/ext4/ioctl.c
336 @@ -278,6 +278,7 @@ static int ext4_ioctl_setflags(struct inode *inode,
337         struct ext4_iloc iloc;
338         unsigned int oldflags, mask, i;
339         unsigned int jflag;
340 +       struct super_block *sb = inode->i_sb;
342         /* Is it quota file? Do not allow user to mess with it */
343         if (ext4_is_quota_file(inode))
344 @@ -322,6 +323,23 @@ static int ext4_ioctl_setflags(struct inode *inode,
345                         goto flags_out;
346         }
348 +       if ((flags ^ oldflags) & EXT4_CASEFOLD_FL) {
349 +               if (!ext4_has_feature_fname_encoding(sb)) {
350 +                       err = -EOPNOTSUPP;
351 +                       goto flags_out;
352 +               }
354 +               if (!S_ISDIR(inode->i_mode)) {
355 +                       err = -ENOTDIR;
356 +                       goto flags_out;
357 +               }
359 +               if (!ext4_empty_dir(inode)) {
360 +                       err = -ENOTEMPTY;
361 +                       goto flags_out;
362 +               }
363 +       }
365         handle = ext4_journal_start(inode, EXT4_HT_INODE, 1);
366         if (IS_ERR(handle)) {
367                 err = PTR_ERR(handle);
368 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
369 index 980166a8122a..e917830eae84 100644
370 --- a/fs/ext4/namei.c
371 +++ b/fs/ext4/namei.c
372 @@ -35,6 +35,7 @@
373  #include <linux/buffer_head.h>
374  #include <linux/bio.h>
375  #include <linux/iversion.h>
376 +#include <linux/unicode.h>
377  #include "ext4.h"
378  #include "ext4_jbd2.h"
380 @@ -629,7 +630,7 @@ static struct stats dx_show_leaf(struct inode *dir,
381                                 }
382                                 if (!fscrypt_has_encryption_key(dir)) {
383                                         /* Directory is not encrypted */
384 -                                       ext4fs_dirhash(de->name,
385 +                                       ext4fs_dirhash(dir, de->name,
386                                                 de->name_len, &h);
387                                         printk("%*.s:(U)%x.%u ", len,
388                                                name, h.hash,
389 @@ -662,8 +663,8 @@ static struct stats dx_show_leaf(struct inode *dir,
390                                                 name = fname_crypto_str.name;
391                                                 len = fname_crypto_str.len;
392                                         }
393 -                                       ext4fs_dirhash(de->name, de->name_len,
394 -                                                      &h);
395 +                                       ext4fs_dirhash(dir, de->name,
396 +                                                      de->name_len, &h);
397                                         printk("%*.s:(E)%x.%u ", len, name,
398                                                h.hash, (unsigned) ((char *) de
399                                                                    - base));
400 @@ -673,7 +674,7 @@ static struct stats dx_show_leaf(struct inode *dir,
401  #else
402                                 int len = de->name_len;
403                                 char *name = de->name;
404 -                               ext4fs_dirhash(de->name, de->name_len, &h);
405 +                               ext4fs_dirhash(dir, de->name, de->name_len, &h);
406                                 printk("%*.s:%x.%u ", len, name, h.hash,
407                                        (unsigned) ((char *) de - base));
408  #endif
409 @@ -762,7 +763,7 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,
410                 hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
411         hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
412         if (fname && fname_name(fname))
413 -               ext4fs_dirhash(fname_name(fname), fname_len(fname), hinfo);
414 +               ext4fs_dirhash(dir, fname_name(fname), fname_len(fname), hinfo);
415         hash = hinfo->hash;
417         if (root->info.unused_flags & 1) {
418 @@ -1008,7 +1009,7 @@ static int htree_dirblock_to_tree(struct file *dir_file,
419                         /* silently ignore the rest of the block */
420                         break;
421                 }
422 -               ext4fs_dirhash(de->name, de->name_len, hinfo);
423 +               ext4fs_dirhash(dir, de->name, de->name_len, hinfo);
424                 if ((hinfo->hash < start_hash) ||
425                     ((hinfo->hash == start_hash) &&
426                      (hinfo->minor_hash < start_minor_hash)))
427 @@ -1197,7 +1198,7 @@ static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de,
429         while ((char *) de < base + blocksize) {
430                 if (de->name_len && de->inode) {
431 -                       ext4fs_dirhash(de->name, de->name_len, &h);
432 +                       ext4fs_dirhash(dir, de->name, de->name_len, &h);
433                         map_tail--;
434                         map_tail->hash = h.hash;
435                         map_tail->offs = ((char *) de - base)>>2;
436 @@ -1252,15 +1253,52 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
437         dx_set_count(entries, count + 1);
440 +#ifdef CONFIG_UNICODE
442 + * Test whether a case-insensitive directory entry matches the filename
443 + * being searched for.
444 + *
445 + * Returns: 0 if the directory entry matches, more than 0 if it
446 + * doesn't match or less than zero on error.
447 + */
448 +int ext4_ci_compare(const struct inode *parent, const struct qstr *name,
449 +                   const struct qstr *entry)
451 +       const struct ext4_sb_info *sbi = EXT4_SB(parent->i_sb);
452 +       const struct unicode_map *um = sbi->s_encoding;
453 +       int ret;
455 +       ret = utf8_strncasecmp(um, name, entry);
456 +       if (ret < 0) {
457 +               /* Handle invalid character sequence as either an error
458 +                * or as an opaque byte sequence.
459 +                */
460 +               if (ext4_has_strict_mode(sbi))
461 +                       return -EINVAL;
463 +               if (name->len != entry->len)
464 +                       return 1;
466 +               return !!memcmp(name->name, entry->name, name->len);
467 +       }
469 +       return ret;
471 +#endif
473  /*
474   * Test whether a directory entry matches the filename being searched for.
475   *
476   * Return: %true if the directory entry matches, otherwise %false.
477   */
478 -static inline bool ext4_match(const struct ext4_filename *fname,
479 +static inline bool ext4_match(const struct inode *parent,
480 +                             const struct ext4_filename *fname,
481                               const struct ext4_dir_entry_2 *de)
483         struct fscrypt_name f;
484 +#ifdef CONFIG_UNICODE
485 +       const struct qstr entry = {.name = de->name, .len = de->name_len};
486 +#endif
488         if (!de->inode)
489                 return false;
490 @@ -1270,6 +1308,12 @@ static inline bool ext4_match(const struct ext4_filename *fname,
491  #ifdef CONFIG_FS_ENCRYPTION
492         f.crypto_buf = fname->crypto_buf;
493  #endif
495 +#ifdef CONFIG_UNICODE
496 +       if (EXT4_SB(parent->i_sb)->s_encoding && IS_CASEFOLDED(parent))
497 +               return (ext4_ci_compare(parent, fname->usr_fname, &entry) == 0);
498 +#endif
500         return fscrypt_match_name(&f, de->name, de->name_len);
503 @@ -1290,7 +1334,7 @@ int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size,
504                 /* this code is executed quadratically often */
505                 /* do minimal checking `by hand' */
506                 if ((char *) de + de->name_len <= dlimit &&
507 -                   ext4_match(fname, de)) {
508 +                   ext4_match(dir, fname, de)) {
509                         /* found a match - just to be sure, do
510                          * a full check */
511                         if (ext4_check_dir_entry(dir, NULL, de, bh, bh->b_data,
512 @@ -1588,6 +1632,17 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
513                         return ERR_PTR(-EPERM);
514                 }
515         }
517 +#ifdef CONFIG_UNICODE
518 +       if (!inode && IS_CASEFOLDED(dir)) {
519 +               /* Eventually we want to call d_add_ci(dentry, NULL)
520 +                * for negative dentries in the encoding case as
521 +                * well.  For now, prevent the negative dentry
522 +                * from being cached.
523 +                */
524 +               return NULL;
525 +       }
526 +#endif
527         return d_splice_alias(inode, dentry);
530 @@ -1798,7 +1853,7 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
531                 if (ext4_check_dir_entry(dir, NULL, de, bh,
532                                          buf, buf_size, offset))
533                         return -EFSCORRUPTED;
534 -               if (ext4_match(fname, de))
535 +               if (ext4_match(dir, fname, de))
536                         return -EEXIST;
537                 nlen = EXT4_DIR_REC_LEN(de->name_len);
538                 rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
539 @@ -1983,7 +2038,7 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
540         if (fname->hinfo.hash_version <= DX_HASH_TEA)
541                 fname->hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
542         fname->hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
543 -       ext4fs_dirhash(fname_name(fname), fname_len(fname), &fname->hinfo);
544 +       ext4fs_dirhash(dir, fname_name(fname), fname_len(fname), &fname->hinfo);
546         memset(frames, 0, sizeof(frames));
547         frame = frames;
548 @@ -2036,6 +2091,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
549         struct ext4_dir_entry_2 *de;
550         struct ext4_dir_entry_tail *t;
551         struct super_block *sb;
552 +       struct ext4_sb_info *sbi;
553         struct ext4_filename fname;
554         int     retval;
555         int     dx_fallback=0;
556 @@ -2047,10 +2103,17 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
557                 csum_size = sizeof(struct ext4_dir_entry_tail);
559         sb = dir->i_sb;
560 +       sbi = EXT4_SB(sb);
561         blocksize = sb->s_blocksize;
562         if (!dentry->d_name.len)
563                 return -EINVAL;
565 +#ifdef CONFIG_UNICODE
566 +       if (ext4_has_strict_mode(sbi) && IS_CASEFOLDED(dir) &&
567 +           utf8_validate(sbi->s_encoding, &dentry->d_name))
568 +               return -EINVAL;
569 +#endif
571         retval = ext4_fname_setup_filename(dir, &dentry->d_name, 0, &fname);
572         if (retval)
573                 return retval;
574 @@ -2975,6 +3038,17 @@ static int ext4_rmdir(struct inode *dir, struct dentry *dentry)
575         ext4_update_dx_flag(dir);
576         ext4_mark_inode_dirty(handle, dir);
578 +#ifdef CONFIG_UNICODE
579 +       /* VFS negative dentries are incompatible with Encoding and
580 +        * Case-insensitiveness. Eventually we'll want avoid
581 +        * invalidating the dentries here, alongside with returning the
582 +        * negative dentries at ext4_lookup(), when it is better
583 +        * supported by the VFS for the CI case.
584 +        */
585 +       if (IS_CASEFOLDED(dir))
586 +               d_invalidate(dentry);
587 +#endif
589  end_rmdir:
590         brelse(bh);
591         if (handle)
592 @@ -3044,6 +3118,17 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
593         inode->i_ctime = current_time(inode);
594         ext4_mark_inode_dirty(handle, inode);
596 +#ifdef CONFIG_UNICODE
597 +       /* VFS negative dentries are incompatible with Encoding and
598 +        * Case-insensitiveness. Eventually we'll want avoid
599 +        * invalidating the dentries here, alongside with returning the
600 +        * negative dentries at ext4_lookup(), when it is  better
601 +        * supported by the VFS for the CI case.
602 +        */
603 +       if (IS_CASEFOLDED(dir))
604 +               d_invalidate(dentry);
605 +#endif
607  end_unlink:
608         brelse(bh);
609         if (handle)
610 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
611 index 934814d0a041..c17d300a9f16 100644
612 --- a/fs/ext4/super.c
613 +++ b/fs/ext4/super.c
614 @@ -4484,6 +4484,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
615                 iput(root);
616                 goto failed_mount4;
617         }
619 +#ifdef CONFIG_UNICODE
620 +       if (sbi->s_encoding)
621 +               sb->s_d_op = &ext4_dentry_ops;
622 +#endif
624         sb->s_root = d_make_root(root);
625         if (!sb->s_root) {
626                 ext4_msg(sb, KERN_ERR, "get root dentry failed");
627 diff --git a/include/linux/fs.h b/include/linux/fs.h
628 index 8b42df09b04c..6261090e605b 100644
629 --- a/include/linux/fs.h
630 +++ b/include/linux/fs.h
631 @@ -1953,6 +1953,7 @@ struct super_operations {
632  #define S_DAX          0       /* Make all the DAX code disappear */
633  #endif
634  #define S_ENCRYPTED    16384   /* Encrypted file (using fs/crypto/) */
635 +#define S_CASEFOLD     32768   /* Casefolded file */
637  /*
638   * Note that nosuid etc flags are inode-specific: setting some file-system
639 @@ -1993,6 +1994,7 @@ static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags
640  #define IS_NOSEC(inode)                ((inode)->i_flags & S_NOSEC)
641  #define IS_DAX(inode)          ((inode)->i_flags & S_DAX)
642  #define IS_ENCRYPTED(inode)    ((inode)->i_flags & S_ENCRYPTED)
643 +#define IS_CASEFOLDED(inode)   ((inode)->i_flags & S_CASEFOLD)
645  #define IS_WHITEOUT(inode)     (S_ISCHR(inode->i_mode) && \
646                                  (inode)->i_rdev == WHITEOUT_DEV)