add patch improve-warning-directory-handling-messages
[ext4-patch-queue.git] / optimize-ext4-encryption
blob8485b3f37a441e2fc99f2d719ac6355e00d0f82c
1 ext4 crypto: optimize filename encryption
3 Encrypt the filename as soon it is passed in by the user.  This avoids
4 our needing to encrypt the filename 2 or 3 times while in the process
5 of creating a filename.
7 Similarly, when looking up a directory entry, encrypt the filename
8 early, or if the encryption key is not available, base-64 decode the
9 file syystem so that the hash value and the last 16 bytes of the
10 encrypted filename is available in the new struct ext4_filename data
11 structure.
13 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
14 ---
15  fs/ext4/crypto_fname.c | 155 ++++++++++++++++----------------------
16  fs/ext4/ext4.h         |  63 ++++++++++------
17  fs/ext4/inline.c       |  31 ++++----
18  fs/ext4/namei.c        | 294 +++++++++++++++++++++++++++---------------------------------------------
19  4 files changed, 230 insertions(+), 313 deletions(-)
21 diff --git a/fs/ext4/crypto_fname.c b/fs/ext4/crypto_fname.c
22 index fded02f..ad5e328 100644
23 --- a/fs/ext4/crypto_fname.c
24 +++ b/fs/ext4/crypto_fname.c
25 @@ -611,109 +611,82 @@ int ext4_fname_usr_to_disk(struct ext4_fname_crypto_ctx *ctx,
26         return -EACCES;
27  }
29 -/*
30 - * Calculate the htree hash from a filename from user space
31 - */
32 -int ext4_fname_usr_to_hash(struct ext4_fname_crypto_ctx *ctx,
33 -                           const struct qstr *iname,
34 -                           struct dx_hash_info *hinfo)
35 +int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
36 +                             int lookup, struct ext4_filename *fname)
37  {
38 -       struct ext4_str tmp;
39 -       int ret = 0;
40 -       char buf[EXT4_FNAME_CRYPTO_DIGEST_SIZE+1];
41 +       struct ext4_fname_crypto_ctx *ctx;
42 +       int ret = 0, bigname = 0;
44 +       memset(fname, 0, sizeof(struct ext4_filename));
45 +       fname->usr_fname = iname;
47 -       if (!ctx ||
48 +       ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
49 +       if (IS_ERR(ctx))
50 +               return PTR_ERR(ctx);
51 +       if ((ctx == NULL) ||
52             ((iname->name[0] == '.') &&
53              ((iname->len == 1) ||
54               ((iname->name[1] == '.') && (iname->len == 2))))) {
55 -               ext4fs_dirhash(iname->name, iname->len, hinfo);
56 -               return 0;
57 +               fname->disk_name.name = (unsigned char *) iname->name;
58 +               fname->disk_name.len = iname->len;
59 +               goto out;
60         }
62 -       if (!ctx->has_valid_key && iname->name[0] == '_') {
63 -               if (iname->len != 33)
64 -                       return -ENOENT;
65 -               ret = digest_decode(iname->name+1, iname->len, buf);
66 -               if (ret != 24)
67 -                       return -ENOENT;
68 -               memcpy(&hinfo->hash, buf, 4);
69 -               memcpy(&hinfo->minor_hash, buf + 4, 4);
70 -               return 0;
71 +       if (ctx->has_valid_key) {
72 +               ret = ext4_fname_crypto_alloc_buffer(ctx, iname->len,
73 +                                                    &fname->crypto_buf);
74 +               if (ret < 0)
75 +                       goto out;
76 +               ret = ext4_fname_encrypt(ctx, iname, &fname->crypto_buf);
77 +               if (ret < 0)
78 +                       goto out;
79 +               fname->disk_name.name = fname->crypto_buf.name;
80 +               fname->disk_name.len = fname->crypto_buf.len;
81 +               ret = 0;
82 +               goto out;
83         }
85 -       if (!ctx->has_valid_key && iname->name[0] != '_') {
86 -               if (iname->len > 43)
87 -                       return -ENOENT;
88 -               ret = digest_decode(iname->name, iname->len, buf);
89 -               ext4fs_dirhash(buf, ret, hinfo);
90 -               return 0;
91 +       if (!lookup) {
92 +               ret = -EACCES;
93 +               goto out;
94         }
96 -       /* First encrypt the plaintext name */
97 -       ret = ext4_fname_crypto_alloc_buffer(ctx, iname->len, &tmp);
98 -       if (ret < 0)
99 -               return ret;
101 -       ret = ext4_fname_encrypt(ctx, iname, &tmp);
102 -       if (ret >= 0) {
103 -               ext4fs_dirhash(tmp.name, tmp.len, hinfo);
104 -               ret = 0;
105 +       /* We don't have the key and we are doing a lookup; decode the
106 +        * user-supplied name
107 +        */
108 +       if (iname->name[0] == '_')
109 +               bigname = 1;
110 +       if ((bigname && (iname->len != 33)) ||
111 +           (!bigname && (iname->len > 43))) {
112 +               ret = -ENOENT;
113         }
115 -       ext4_fname_crypto_free_buffer(&tmp);
116 +       fname->crypto_buf.name = kmalloc(32, GFP_KERNEL);
117 +       if (fname->crypto_buf.name == NULL) {
118 +               ret = -ENOMEM;
119 +               goto out;
120 +       }
121 +       ret = digest_decode(iname->name + bigname, iname->len - bigname,
122 +                           fname->crypto_buf.name);
123 +       if (ret < 0) {
124 +               ret = -ENOENT;
125 +               goto out;
126 +       }
127 +       fname->crypto_buf.len = ret;
128 +       if (bigname) {
129 +               memcpy(&fname->hinfo.hash, fname->crypto_buf.name, 4);
130 +               memcpy(&fname->hinfo.minor_hash, fname->crypto_buf.name + 4, 4);
131 +       } else {
132 +               fname->disk_name.name = fname->crypto_buf.name;
133 +               fname->disk_name.len = fname->crypto_buf.len;
134 +       }
135 +       ret = 0;
136 +out:
137 +       ext4_put_fname_crypto_ctx(&ctx);
138         return ret;
141 -int ext4_fname_match(struct ext4_fname_crypto_ctx *ctx, struct ext4_str *cstr,
142 -                    int len, const char * const name,
143 -                    struct ext4_dir_entry_2 *de)
144 +void ext4_fname_free_filename(struct ext4_filename *fname)
146 -       int ret = -ENOENT;
147 -       int bigname = (*name == '_');
149 -       if (ctx->has_valid_key) {
150 -               if (cstr->name == NULL) {
151 -                       struct qstr istr;
153 -                       ret = ext4_fname_crypto_alloc_buffer(ctx, len, cstr);
154 -                       if (ret < 0)
155 -                               goto errout;
156 -                       istr.name = name;
157 -                       istr.len = len;
158 -                       ret = ext4_fname_encrypt(ctx, &istr, cstr);
159 -                       if (ret < 0)
160 -                               goto errout;
161 -               }
162 -       } else {
163 -               if (cstr->name == NULL) {
164 -                       cstr->name = kmalloc(32, GFP_KERNEL);
165 -                       if (cstr->name == NULL)
166 -                               return -ENOMEM;
167 -                       if ((bigname && (len != 33)) ||
168 -                           (!bigname && (len > 43)))
169 -                               goto errout;
170 -                       ret = digest_decode(name+bigname, len-bigname,
171 -                                           cstr->name);
172 -                       if (ret < 0) {
173 -                               ret = -ENOENT;
174 -                               goto errout;
175 -                       }
176 -                       cstr->len = ret;
177 -               }
178 -               if (bigname) {
179 -                       if (de->name_len < 16)
180 -                               return 0;
181 -                       ret = memcmp(de->name + de->name_len - 16,
182 -                                    cstr->name + 8, 16);
183 -                       return (ret == 0) ? 1 : 0;
184 -               }
185 -       }
186 -       if (de->name_len != cstr->len)
187 -               return 0;
188 -       ret = memcmp(de->name, cstr->name, cstr->len);
189 -       return (ret == 0) ? 1 : 0;
190 -errout:
191 -       kfree(cstr->name);
192 -       cstr->name = NULL;
193 -       return ret;
194 +       kfree(fname->crypto_buf.name);
195 +       fname->crypto_buf.name = NULL;
196 +       fname->usr_fname = NULL;
197 +       fname->disk_name.name = NULL;
199 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
200 index 009a059..6bdd69e 100644
201 --- a/fs/ext4/ext4.h
202 +++ b/fs/ext4/ext4.h
203 @@ -1838,6 +1838,17 @@ struct dx_hash_info
204   */
205  #define HASH_NB_ALWAYS         1
207 +struct ext4_filename {
208 +       const struct qstr *usr_fname;
209 +       struct ext4_str disk_name;
210 +       struct dx_hash_info hinfo;
211 +#ifdef CONFIG_EXT4_FS_ENCRYPTION
212 +       struct ext4_str crypto_buf;
213 +#endif
216 +#define fname_name(p) ((p)->disk_name.name)
217 +#define fname_len(p)  ((p)->disk_name.len)
219  /*
220   * Describe an inode's exact location on disk and in memory
221 @@ -2098,21 +2109,16 @@ int ext4_fname_disk_to_usr(struct ext4_fname_crypto_ctx *ctx,
222  int ext4_fname_usr_to_disk(struct ext4_fname_crypto_ctx *ctx,
223                            const struct qstr *iname,
224                            struct ext4_str *oname);
225 -int ext4_fname_usr_to_hash(struct ext4_fname_crypto_ctx *ctx,
226 -                          const struct qstr *iname,
227 -                          struct dx_hash_info *hinfo);
228  int ext4_fname_crypto_namelen_on_disk(struct ext4_fname_crypto_ctx *ctx,
229                                       u32 namelen);
230 -int ext4_fname_match(struct ext4_fname_crypto_ctx *ctx, struct ext4_str *cstr,
231 -                    int len, const char * const name,
232 -                    struct ext4_dir_entry_2 *de);
235  #ifdef CONFIG_EXT4_FS_ENCRYPTION
236  void ext4_put_fname_crypto_ctx(struct ext4_fname_crypto_ctx **ctx);
237  struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx(struct inode *inode,
238                                                         u32 max_len);
239  void ext4_fname_crypto_free_buffer(struct ext4_str *crypto_str);
240 +int ext4_fname_setup_filename(struct inode *dir, const struct qstr *iname,
241 +                             int lookup, struct ext4_filename *fname);
242 +void ext4_fname_free_filename(struct ext4_filename *fname);
243  #else
244  static inline
245  void ext4_put_fname_crypto_ctx(struct ext4_fname_crypto_ctx **ctx) { }
246 @@ -2123,6 +2129,16 @@ struct ext4_fname_crypto_ctx *ext4_get_fname_crypto_ctx(struct inode *inode,
247         return NULL;
249  static inline void ext4_fname_crypto_free_buffer(struct ext4_str *p) { }
250 +static inline int ext4_fname_setup_filename(struct inode *dir,
251 +                                    const struct qstr *iname,
252 +                                    int lookup, struct ext4_filename *fname)
254 +       fname->usr_fname = iname;
255 +       fname->disk_name.name = (unsigned char *) iname->name;
256 +       fname->disk_name.len = iname->len;
257 +       return 0;
259 +static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
260  #endif
263 @@ -2156,14 +2172,13 @@ extern void ext4_htree_free_dir_info(struct dir_private_info *p);
264  extern int ext4_find_dest_de(struct inode *dir, struct inode *inode,
265                              struct buffer_head *bh,
266                              void *buf, int buf_size,
267 -                            const char *name, int namelen,
268 +                            struct ext4_filename *fname,
269                              struct ext4_dir_entry_2 **dest_de);
270  int ext4_insert_dentry(struct inode *dir,
271 -                       struct inode *inode,
272 -                       struct ext4_dir_entry_2 *de,
273 -                       int buf_size,
274 -                      const struct qstr *iname,
275 -                       const char *name, int namelen);
276 +                      struct inode *inode,
277 +                      struct ext4_dir_entry_2 *de,
278 +                      int buf_size,
279 +                      struct ext4_filename *fname);
280  static inline void ext4_update_dx_flag(struct inode *inode)
282         if (!EXT4_HAS_COMPAT_FEATURE(inode->i_sb,
283 @@ -2317,13 +2332,14 @@ extern int ext4_orphan_add(handle_t *, struct inode *);
284  extern int ext4_orphan_del(handle_t *, struct inode *);
285  extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
286                                 __u32 start_minor_hash, __u32 *next_hash);
287 -extern int search_dir(struct buffer_head *bh,
288 -                     char *search_buf,
289 -                     int buf_size,
290 -                     struct inode *dir,
291 -                     const struct qstr *d_name,
292 -                     unsigned int offset,
293 -                     struct ext4_dir_entry_2 **res_dir);
294 +extern int ext4_search_dir(struct buffer_head *bh,
295 +                          char *search_buf,
296 +                          int buf_size,
297 +                          struct inode *dir,
298 +                          struct ext4_filename *fname,
299 +                          const struct qstr *d_name,
300 +                          unsigned int offset,
301 +                          struct ext4_dir_entry_2 **res_dir);
302  extern int ext4_generic_delete_entry(handle_t *handle,
303                                      struct inode *dir,
304                                      struct ext4_dir_entry_2 *de_del,
305 @@ -2768,7 +2784,9 @@ extern int ext4_da_write_inline_data_begin(struct address_space *mapping,
306  extern int ext4_da_write_inline_data_end(struct inode *inode, loff_t pos,
307                                          unsigned len, unsigned copied,
308                                          struct page *page);
309 -extern int ext4_try_add_inline_entry(handle_t *handle, struct dentry *dentry,
310 +extern int ext4_try_add_inline_entry(handle_t *handle,
311 +                                    struct ext4_filename *fname,
312 +                                    struct dentry *dentry,
313                                      struct inode *inode);
314  extern int ext4_try_create_inline_dir(handle_t *handle,
315                                       struct inode *parent,
316 @@ -2782,6 +2800,7 @@ extern int htree_inlinedir_to_tree(struct file *dir_file,
317                                    __u32 start_hash, __u32 start_minor_hash,
318                                    int *has_inline_data);
319  extern struct buffer_head *ext4_find_inline_entry(struct inode *dir,
320 +                                       struct ext4_filename *fname,
321                                         const struct qstr *d_name,
322                                         struct ext4_dir_entry_2 **res_dir,
323                                         int *has_inline_data);
324 diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
325 index 095c7a2..cd944a7 100644
326 --- a/fs/ext4/inline.c
327 +++ b/fs/ext4/inline.c
328 @@ -995,20 +995,18 @@ void ext4_show_inline_dir(struct inode *dir, struct buffer_head *bh,
329   * and -EEXIST if directory entry already exists.
330   */
331  static int ext4_add_dirent_to_inline(handle_t *handle,
332 +                                    struct ext4_filename *fname,
333                                      struct dentry *dentry,
334                                      struct inode *inode,
335                                      struct ext4_iloc *iloc,
336                                      void *inline_start, int inline_size)
338         struct inode    *dir = d_inode(dentry->d_parent);
339 -       const char      *name = dentry->d_name.name;
340 -       int             namelen = dentry->d_name.len;
341         int             err;
342         struct ext4_dir_entry_2 *de;
344 -       err = ext4_find_dest_de(dir, inode, iloc->bh,
345 -                               inline_start, inline_size,
346 -                               name, namelen, &de);
347 +       err = ext4_find_dest_de(dir, inode, iloc->bh, inline_start,
348 +                               inline_size, fname, &de);
349         if (err)
350                 return err;
352 @@ -1016,8 +1014,7 @@ static int ext4_add_dirent_to_inline(handle_t *handle,
353         err = ext4_journal_get_write_access(handle, iloc->bh);
354         if (err)
355                 return err;
356 -       ext4_insert_dentry(dir, inode, de, inline_size, &dentry->d_name,
357 -                          name, namelen);
358 +       ext4_insert_dentry(dir, inode, de, inline_size, fname);
360         ext4_show_inline_dir(dir, iloc->bh, inline_start, inline_size);
362 @@ -1248,8 +1245,8 @@ out:
363   * If succeeds, return 0. If not, extended the inline dir and copied data to
364   * the new created block.
365   */
366 -int ext4_try_add_inline_entry(handle_t *handle, struct dentry *dentry,
367 -                             struct inode *inode)
368 +int ext4_try_add_inline_entry(handle_t *handle, struct ext4_filename *fname,
369 +                             struct dentry *dentry, struct inode *inode)
371         int ret, inline_size;
372         void *inline_start;
373 @@ -1268,7 +1265,7 @@ int ext4_try_add_inline_entry(handle_t *handle, struct dentry *dentry,
374                                                  EXT4_INLINE_DOTDOT_SIZE;
375         inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE;
377 -       ret = ext4_add_dirent_to_inline(handle, dentry, inode, &iloc,
378 +       ret = ext4_add_dirent_to_inline(handle, fname, dentry, inode, &iloc,
379                                         inline_start, inline_size);
380         if (ret != -ENOSPC)
381                 goto out;
382 @@ -1289,8 +1286,9 @@ int ext4_try_add_inline_entry(handle_t *handle, struct dentry *dentry,
383         if (inline_size) {
384                 inline_start = ext4_get_inline_xattr_pos(dir, &iloc);
386 -               ret = ext4_add_dirent_to_inline(handle, dentry, inode, &iloc,
387 -                                               inline_start, inline_size);
388 +               ret = ext4_add_dirent_to_inline(handle, fname, dentry,
389 +                                               inode, &iloc, inline_start,
390 +                                               inline_size);
392                 if (ret != -ENOSPC)
393                         goto out;
394 @@ -1611,6 +1609,7 @@ out:
397  struct buffer_head *ext4_find_inline_entry(struct inode *dir,
398 +                                       struct ext4_filename *fname,
399                                         const struct qstr *d_name,
400                                         struct ext4_dir_entry_2 **res_dir,
401                                         int *has_inline_data)
402 @@ -1632,8 +1631,8 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir,
403         inline_start = (void *)ext4_raw_inode(&iloc)->i_block +
404                                                 EXT4_INLINE_DOTDOT_SIZE;
405         inline_size = EXT4_MIN_INLINE_DATA_SIZE - EXT4_INLINE_DOTDOT_SIZE;
406 -       ret = search_dir(iloc.bh, inline_start, inline_size,
407 -                        dir, d_name, 0, res_dir);
408 +       ret = ext4_search_dir(iloc.bh, inline_start, inline_size,
409 +                             dir, fname, d_name, 0, res_dir);
410         if (ret == 1)
411                 goto out_find;
412         if (ret < 0)
413 @@ -1645,8 +1644,8 @@ struct buffer_head *ext4_find_inline_entry(struct inode *dir,
414         inline_start = ext4_get_inline_xattr_pos(dir, &iloc);
415         inline_size = ext4_get_inline_size(dir) - EXT4_MIN_INLINE_DATA_SIZE;
417 -       ret = search_dir(iloc.bh, inline_start, inline_size,
418 -                        dir, d_name, 0, res_dir);
419 +       ret = ext4_search_dir(iloc.bh, inline_start, inline_size,
420 +                             dir, fname, d_name, 0, res_dir);
421         if (ret == 1)
422                 goto out_find;
424 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
425 index 814f3be..56c60cb 100644
426 --- a/fs/ext4/namei.c
427 +++ b/fs/ext4/namei.c
428 @@ -248,7 +248,7 @@ static void dx_set_count(struct dx_entry *entries, unsigned value);
429  static void dx_set_limit(struct dx_entry *entries, unsigned value);
430  static unsigned dx_root_limit(struct inode *dir, unsigned infosize);
431  static unsigned dx_node_limit(struct inode *dir);
432 -static struct dx_frame *dx_probe(const struct qstr *d_name,
433 +static struct dx_frame *dx_probe(struct ext4_filename *fname,
434                                  struct inode *dir,
435                                  struct dx_hash_info *hinfo,
436                                  struct dx_frame *frame);
437 @@ -267,10 +267,10 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash,
438                                  struct dx_frame *frames,
439                                  __u32 *start_hash);
440  static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
441 -               const struct qstr *d_name,
442 +               struct ext4_filename *fname,
443                 struct ext4_dir_entry_2 **res_dir);
444 -static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
445 -                            struct inode *inode);
446 +static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
447 +                            struct dentry *dentry, struct inode *inode);
449  /* checksumming functions */
450  void initialize_dirent_tail(struct ext4_dir_entry_tail *t,
451 @@ -724,7 +724,7 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
452   * back to userspace.
453   */
454  static struct dx_frame *
455 -dx_probe(const struct qstr *d_name, struct inode *dir,
456 +dx_probe(struct ext4_filename *fname, struct inode *dir,
457          struct dx_hash_info *hinfo, struct dx_frame *frame_in)
459         unsigned count, indirect;
460 @@ -746,32 +746,14 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
461                              root->info.hash_version);
462                 goto fail;
463         }
464 +       if (fname)
465 +               hinfo = &fname->hinfo;
466         hinfo->hash_version = root->info.hash_version;
467         if (hinfo->hash_version <= DX_HASH_TEA)
468                 hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
469         hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
470 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
471 -       if (d_name) {
472 -               struct ext4_fname_crypto_ctx *ctx = NULL;
473 -               int res;
475 -               /* Check if the directory is encrypted */
476 -               ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
477 -               if (IS_ERR(ctx)) {
478 -                       ret_err = ERR_PTR(PTR_ERR(ctx));
479 -                       goto fail;
480 -               }
481 -               res = ext4_fname_usr_to_hash(ctx, d_name, hinfo);
482 -               if (res < 0) {
483 -                       ret_err = ERR_PTR(res);
484 -                       goto fail;
485 -               }
486 -               ext4_put_fname_crypto_ctx(&ctx);
487 -       }
488 -#else
489 -       if (d_name)
490 -               ext4fs_dirhash(d_name->name, d_name->len, hinfo);
491 -#endif
492 +       if (fname && fname_name(fname))
493 +               ext4fs_dirhash(fname_name(fname), fname_len(fname), hinfo);
494         hash = hinfo->hash;
496         if (root->info.unused_flags & 1) {
497 @@ -1155,12 +1137,13 @@ errout:
499  static inline int search_dirblock(struct buffer_head *bh,
500                                   struct inode *dir,
501 +                                 struct ext4_filename *fname,
502                                   const struct qstr *d_name,
503                                   unsigned int offset,
504                                   struct ext4_dir_entry_2 **res_dir)
506 -       return search_dir(bh, bh->b_data, dir->i_sb->s_blocksize, dir,
507 -                         d_name, offset, res_dir);
508 +       return ext4_search_dir(bh, bh->b_data, dir->i_sb->s_blocksize, dir,
509 +                              fname, d_name, offset, res_dir);
512  /*
513 @@ -1242,54 +1225,54 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, ext4_lblk_t block)
514   * `len <= EXT4_NAME_LEN' is guaranteed by caller.
515   * `de != NULL' is guaranteed by caller.
516   */
517 -static inline int ext4_match(struct ext4_fname_crypto_ctx *ctx,
518 -                            struct ext4_str *fname_crypto_str,
519 -                            int len, const char * const name,
520 +static inline int ext4_match(struct ext4_filename *fname,
521                              struct ext4_dir_entry_2 *de)
523 -       int res;
524 +       const void *name = fname_name(fname);
525 +       u32 len = fname_len(fname);
527         if (!de->inode)
528                 return 0;
530  #ifdef CONFIG_EXT4_FS_ENCRYPTION
531 -       if (ctx)
532 -               return ext4_fname_match(ctx, fname_crypto_str, len, name, de);
533 +       if (unlikely(!name)) {
534 +               if (fname->usr_fname->name[0] == '_') {
535 +                       int ret;
536 +                       if (de->name_len < 16)
537 +                               return 0;
538 +                       ret = memcmp(de->name + de->name_len - 16,
539 +                                    fname->crypto_buf.name + 8, 16);
540 +                       return (ret == 0) ? 1 : 0;
541 +               }
542 +               name = fname->crypto_buf.name;
543 +               len = fname->crypto_buf.len;
544 +       }
545  #endif
546 -       if (len != de->name_len)
547 +       if (de->name_len != len)
548                 return 0;
549 -       res = memcmp(name, de->name, len);
550 -       return (res == 0) ? 1 : 0;
551 +       return (memcmp(de->name, name, len) == 0) ? 1 : 0;
554  /*
555   * Returns 0 if not found, -1 on failure, and 1 on success
556   */
557 -int search_dir(struct buffer_head *bh, char *search_buf, int buf_size,
558 -              struct inode *dir, const struct qstr *d_name,
559 -              unsigned int offset, struct ext4_dir_entry_2 **res_dir)
560 +int ext4_search_dir(struct buffer_head *bh, char *search_buf, int buf_size,
561 +                   struct inode *dir, struct ext4_filename *fname,
562 +                   const struct qstr *d_name,
563 +                   unsigned int offset, struct ext4_dir_entry_2 **res_dir)
565         struct ext4_dir_entry_2 * de;
566         char * dlimit;
567         int de_len;
568 -       const char *name = d_name->name;
569 -       int namelen = d_name->len;
570 -       struct ext4_fname_crypto_ctx *ctx = NULL;
571 -       struct ext4_str fname_crypto_str = {.name = NULL, .len = 0};
572         int res;
574 -       ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
575 -       if (IS_ERR(ctx))
576 -               return -1;
578         de = (struct ext4_dir_entry_2 *)search_buf;
579         dlimit = search_buf + buf_size;
580         while ((char *) de < dlimit) {
581                 /* this code is executed quadratically often */
582                 /* do minimal checking `by hand' */
583                 if ((char *) de + de->name_len <= dlimit) {
584 -                       res = ext4_match(ctx, &fname_crypto_str, namelen,
585 -                                        name, de);
586 +                       res = ext4_match(fname, de);
587                         if (res < 0) {
588                                 res = -1;
589                                 goto return_result;
590 @@ -1322,8 +1305,6 @@ int search_dir(struct buffer_head *bh, char *search_buf, int buf_size,
592         res = 0;
593  return_result:
594 -       ext4_put_fname_crypto_ctx(&ctx);
595 -       ext4_fname_crypto_free_buffer(&fname_crypto_str);
596         return res;
599 @@ -1370,7 +1351,8 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
600                                    buffer */
601         int num = 0;
602         ext4_lblk_t  nblocks;
603 -       int i, namelen;
604 +       int i, namelen, retval;
605 +       struct ext4_filename fname;
607         *res_dir = NULL;
608         sb = dir->i_sb;
609 @@ -1378,14 +1360,18 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
610         if (namelen > EXT4_NAME_LEN)
611                 return NULL;
613 +       retval = ext4_fname_setup_filename(dir, d_name, 1, &fname);
614 +       if (retval)
615 +               return ERR_PTR(retval);
617         if (ext4_has_inline_data(dir)) {
618                 int has_inline_data = 1;
619 -               ret = ext4_find_inline_entry(dir, d_name, res_dir,
620 +               ret = ext4_find_inline_entry(dir, &fname, d_name, res_dir,
621                                              &has_inline_data);
622                 if (has_inline_data) {
623                         if (inlined)
624                                 *inlined = 1;
625 -                       return ret;
626 +                       goto cleanup_and_exit;
627                 }
628         }
630 @@ -1400,14 +1386,14 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
631                 goto restart;
632         }
633         if (is_dx(dir)) {
634 -               bh = ext4_dx_find_entry(dir, d_name, res_dir);
635 +               ret = ext4_dx_find_entry(dir, &fname, res_dir);
636                 /*
637                  * On success, or if the error was file not found,
638                  * return.  Otherwise, fall back to doing a search the
639                  * old fashioned way.
640                  */
641 -               if (!IS_ERR(bh) || PTR_ERR(bh) != ERR_BAD_DX_DIR)
642 -                       return bh;
643 +               if (!IS_ERR(ret) || PTR_ERR(ret) != ERR_BAD_DX_DIR)
644 +                       goto cleanup_and_exit;
645                 dxtrace(printk(KERN_DEBUG "ext4_find_entry: dx failed, "
646                                "falling back\n"));
647         }
648 @@ -1438,8 +1424,10 @@ restart:
649                                 num++;
650                                 bh = ext4_getblk(NULL, dir, b++, 0);
651                                 if (unlikely(IS_ERR(bh))) {
652 -                                       if (ra_max == 0)
653 -                                               return bh;
654 +                                       if (ra_max == 0) {
655 +                                               ret = bh;
656 +                                               goto cleanup_and_exit;
657 +                                       }
658                                         break;
659                                 }
660                                 bh_use[ra_max] = bh;
661 @@ -1469,7 +1457,7 @@ restart:
662                         goto next;
663                 }
664                 set_buffer_verified(bh);
665 -               i = search_dirblock(bh, dir, d_name,
666 +               i = search_dirblock(bh, dir, &fname, d_name,
667                             block << EXT4_BLOCK_SIZE_BITS(sb), res_dir);
668                 if (i == 1) {
669                         EXT4_I(dir)->i_dir_start_lookup = block;
670 @@ -1500,15 +1488,17 @@ cleanup_and_exit:
671         /* Clean up the read-ahead blocks */
672         for (; ra_ptr < ra_max; ra_ptr++)
673                 brelse(bh_use[ra_ptr]);
674 +       ext4_fname_free_filename(&fname);
675         return ret;
678 -static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct qstr *d_name,
679 -                      struct ext4_dir_entry_2 **res_dir)
680 +static struct buffer_head * ext4_dx_find_entry(struct inode *dir,
681 +                       struct ext4_filename *fname,
682 +                       struct ext4_dir_entry_2 **res_dir)
684         struct super_block * sb = dir->i_sb;
685 -       struct dx_hash_info     hinfo;
686         struct dx_frame frames[2], *frame;
687 +       const struct qstr *d_name = fname->usr_fname;
688         struct buffer_head *bh;
689         ext4_lblk_t block;
690         int retval;
691 @@ -1516,7 +1506,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
692  #ifdef CONFIG_EXT4_FS_ENCRYPTION
693         *res_dir = NULL;
694  #endif
695 -       frame = dx_probe(d_name, dir, &hinfo, frames);
696 +       frame = dx_probe(fname, dir, NULL, frames);
697         if (IS_ERR(frame))
698                 return (struct buffer_head *) frame;
699         do {
700 @@ -1525,7 +1515,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
701                 if (IS_ERR(bh))
702                         goto errout;
704 -               retval = search_dirblock(bh, dir, d_name,
705 +               retval = search_dirblock(bh, dir, fname, d_name,
706                                          block << EXT4_BLOCK_SIZE_BITS(sb),
707                                          res_dir);
708                 if (retval == 1)
709 @@ -1537,7 +1527,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
710                 }
712                 /* Check to see if we should continue to search */
713 -               retval = ext4_htree_next_block(dir, hinfo.hash, frame,
714 +               retval = ext4_htree_next_block(dir, fname->hinfo.hash, frame,
715                                                frames, NULL);
716                 if (retval < 0) {
717                         ext4_warning(sb,
718 @@ -1796,32 +1786,16 @@ journal_error:
719  int ext4_find_dest_de(struct inode *dir, struct inode *inode,
720                       struct buffer_head *bh,
721                       void *buf, int buf_size,
722 -                     const char *name, int namelen,
723 +                     struct ext4_filename *fname,
724                       struct ext4_dir_entry_2 **dest_de)
726         struct ext4_dir_entry_2 *de;
727 -       unsigned short reclen = EXT4_DIR_REC_LEN(namelen);
728 +       unsigned short reclen = EXT4_DIR_REC_LEN(fname_len(fname));
729         int nlen, rlen;
730         unsigned int offset = 0;
731         char *top;
732 -       struct ext4_fname_crypto_ctx *ctx = NULL;
733 -       struct ext4_str fname_crypto_str = {.name = NULL, .len = 0};
734         int res;
736 -       ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
737 -       if (IS_ERR(ctx))
738 -               return -1;
740 -       if (ctx != NULL) {
741 -               /* Calculate record length needed to store the entry */
742 -               res = ext4_fname_crypto_namelen_on_disk(ctx, namelen);
743 -               if (res < 0) {
744 -                       ext4_put_fname_crypto_ctx(&ctx);
745 -                       return res;
746 -               }
747 -               reclen = EXT4_DIR_REC_LEN(res);
748 -       }
750         de = (struct ext4_dir_entry_2 *)buf;
751         top = buf + buf_size - reclen;
752         while ((char *) de <= top) {
753 @@ -1831,7 +1805,7 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
754                         goto return_result;
755                 }
756                 /* Provide crypto context and crypto buffer to ext4 match */
757 -               res = ext4_match(ctx, &fname_crypto_str, namelen, name, de);
758 +               res = ext4_match(fname, de);
759                 if (res < 0)
760                         goto return_result;
761                 if (res > 0) {
762 @@ -1853,8 +1827,6 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
763                 res = 0;
764         }
765  return_result:
766 -       ext4_put_fname_crypto_ctx(&ctx);
767 -       ext4_fname_crypto_free_buffer(&fname_crypto_str);
768         return res;
771 @@ -1862,39 +1834,10 @@ int ext4_insert_dentry(struct inode *dir,
772                        struct inode *inode,
773                        struct ext4_dir_entry_2 *de,
774                        int buf_size,
775 -                      const struct qstr *iname,
776 -                      const char *name, int namelen)
777 +                      struct ext4_filename *fname)
780         int nlen, rlen;
781 -       struct ext4_fname_crypto_ctx *ctx = NULL;
782 -       struct ext4_str fname_crypto_str = {.name = NULL, .len = 0};
783 -       struct ext4_str tmp_str;
784 -       int res;
786 -       ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
787 -       if (IS_ERR(ctx))
788 -               return -EIO;
789 -       /* By default, the input name would be written to the disk */
790 -       tmp_str.name = (unsigned char *)name;
791 -       tmp_str.len = namelen;
792 -       if (ctx != NULL) {
793 -               /* Directory is encrypted */
794 -               res = ext4_fname_crypto_alloc_buffer(ctx, EXT4_NAME_LEN,
795 -                                                    &fname_crypto_str);
796 -               if (res < 0) {
797 -                       ext4_put_fname_crypto_ctx(&ctx);
798 -                       return -ENOMEM;
799 -               }
800 -               res = ext4_fname_usr_to_disk(ctx, iname, &fname_crypto_str);
801 -               if (res < 0) {
802 -                       ext4_put_fname_crypto_ctx(&ctx);
803 -                       ext4_fname_crypto_free_buffer(&fname_crypto_str);
804 -                       return res;
805 -               }
806 -               tmp_str.name = fname_crypto_str.name;
807 -               tmp_str.len = fname_crypto_str.len;
808 -       }
810         nlen = EXT4_DIR_REC_LEN(de->name_len);
811         rlen = ext4_rec_len_from_disk(de->rec_len, buf_size);
812 @@ -1908,11 +1851,8 @@ int ext4_insert_dentry(struct inode *dir,
813         de->file_type = EXT4_FT_UNKNOWN;
814         de->inode = cpu_to_le32(inode->i_ino);
815         ext4_set_de_type(inode->i_sb, de, inode->i_mode);
816 -       de->name_len = tmp_str.len;
818 -       memcpy(de->name, tmp_str.name, tmp_str.len);
819 -       ext4_put_fname_crypto_ctx(&ctx);
820 -       ext4_fname_crypto_free_buffer(&fname_crypto_str);
821 +       de->name_len = fname_len(fname);
822 +       memcpy(de->name, fname_name(fname), fname_len(fname));
823         return 0;
826 @@ -1924,13 +1864,11 @@ int ext4_insert_dentry(struct inode *dir,
827   * space.  It will return -ENOSPC if no space is available, and -EIO
828   * and -EEXIST if directory entry already exists.
829   */
830 -static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
831 +static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname,
832 +                            struct inode *dir,
833                              struct inode *inode, struct ext4_dir_entry_2 *de,
834                              struct buffer_head *bh)
836 -       struct inode    *dir = d_inode(dentry->d_parent);
837 -       const char      *name = dentry->d_name.name;
838 -       int             namelen = dentry->d_name.len;
839         unsigned int    blocksize = dir->i_sb->s_blocksize;
840         int             csum_size = 0;
841         int             err;
842 @@ -1939,9 +1877,8 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
843                 csum_size = sizeof(struct ext4_dir_entry_tail);
845         if (!de) {
846 -               err = ext4_find_dest_de(dir, inode,
847 -                                       bh, bh->b_data, blocksize - csum_size,
848 -                                       name, namelen, &de);
849 +               err = ext4_find_dest_de(dir, inode, bh, bh->b_data,
850 +                                       blocksize - csum_size, fname, &de);
851                 if (err)
852                         return err;
853         }
854 @@ -1954,8 +1891,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
856         /* By now the buffer is marked for journaling. Due to crypto operations,
857          * the following function call may fail */
858 -       err = ext4_insert_dentry(dir, inode, de, blocksize, &dentry->d_name,
859 -                                name, namelen);
860 +       err = ext4_insert_dentry(dir, inode, de, blocksize, fname);
861         if (err < 0)
862                 return err;
864 @@ -1985,17 +1921,11 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry,
865   * This converts a one block unindexed directory to a 3 block indexed
866   * directory, and adds the dentry to the indexed directory.
867   */
868 -static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
869 +static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
870 +                           struct dentry *dentry,
871                             struct inode *inode, struct buffer_head *bh)
873         struct inode    *dir = d_inode(dentry->d_parent);
874 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
875 -       struct ext4_fname_crypto_ctx *ctx = NULL;
876 -       int res;
877 -#else
878 -       const char      *name = dentry->d_name.name;
879 -       int             namelen = dentry->d_name.len;
880 -#endif
881         struct buffer_head *bh2;
882         struct dx_root  *root;
883         struct dx_frame frames[2], *frame;
884 @@ -2006,17 +1936,10 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
885         unsigned        len;
886         int             retval;
887         unsigned        blocksize;
888 -       struct dx_hash_info hinfo;
889         ext4_lblk_t  block;
890         struct fake_dirent *fde;
891         int csum_size = 0;
893 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
894 -       ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
895 -       if (IS_ERR(ctx))
896 -               return PTR_ERR(ctx);
897 -#endif
899         if (ext4_has_metadata_csum(inode->i_sb))
900                 csum_size = sizeof(struct ext4_dir_entry_tail);
902 @@ -2078,22 +2001,12 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
903         dx_set_limit(entries, dx_root_limit(dir, sizeof(root->info)));
905         /* Initialize as for dx_probe */
906 -       hinfo.hash_version = root->info.hash_version;
907 -       if (hinfo.hash_version <= DX_HASH_TEA)
908 -               hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
909 -       hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
910 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
911 -       res = ext4_fname_usr_to_hash(ctx, &dentry->d_name, &hinfo);
912 -       if (res < 0) {
913 -               ext4_put_fname_crypto_ctx(&ctx);
914 -               ext4_mark_inode_dirty(handle, dir);
915 -               brelse(bh);
916 -               return res;
917 -       }
918 -       ext4_put_fname_crypto_ctx(&ctx);
919 -#else
920 -       ext4fs_dirhash(name, namelen, &hinfo);
921 -#endif
922 +       fname->hinfo.hash_version = root->info.hash_version;
923 +       if (fname->hinfo.hash_version <= DX_HASH_TEA)
924 +               fname->hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
925 +       fname->hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;
926 +       ext4fs_dirhash(fname_name(fname), fname_len(fname), &fname->hinfo);
928         memset(frames, 0, sizeof(frames));
929         frame = frames;
930         frame->entries = entries;
931 @@ -2108,14 +2021,14 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
932         if (retval)
933                 goto out_frames;        
935 -       de = do_split(handle,dir, &bh, frame, &hinfo);
936 +       de = do_split(handle,dir, &bh, frame, &fname->hinfo);
937         if (IS_ERR(de)) {
938                 retval = PTR_ERR(de);
939                 goto out_frames;
940         }
941         dx_release(frames);
943 -       retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
944 +       retval = add_dirent_to_buf(handle, fname, dir, inode, de, bh);
945         brelse(bh);
946         return retval;
947  out_frames:
948 @@ -2147,6 +2060,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
949         struct ext4_dir_entry_2 *de;
950         struct ext4_dir_entry_tail *t;
951         struct super_block *sb;
952 +       struct ext4_filename fname;
953         int     retval;
954         int     dx_fallback=0;
955         unsigned blocksize;
956 @@ -2161,10 +2075,15 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
957         if (!dentry->d_name.len)
958                 return -EINVAL;
960 +       retval = ext4_fname_setup_filename(dir, &dentry->d_name, 0, &fname);
961 +       if (retval)
962 +               return retval;
964         if (ext4_has_inline_data(dir)) {
965 -               retval = ext4_try_add_inline_entry(handle, dentry, inode);
966 +               retval = ext4_try_add_inline_entry(handle, &fname,
967 +                                                  dentry, inode);
968                 if (retval < 0)
969 -                       return retval;
970 +                       goto out;
971                 if (retval == 1) {
972                         retval = 0;
973                         goto out;
974 @@ -2172,7 +2091,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
975         }
977         if (is_dx(dir)) {
978 -               retval = ext4_dx_add_entry(handle, dentry, inode);
979 +               retval = ext4_dx_add_entry(handle, &fname, dentry, inode);
980                 if (!retval || (retval != ERR_BAD_DX_DIR))
981                         goto out;
982                 ext4_clear_inode_flag(dir, EXT4_INODE_INDEX);
983 @@ -2182,24 +2101,31 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
984         blocks = dir->i_size >> sb->s_blocksize_bits;
985         for (block = 0; block < blocks; block++) {
986                 bh = ext4_read_dirblock(dir, block, DIRENT);
987 -               if (IS_ERR(bh))
988 -                       return PTR_ERR(bh);
990 -               retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
991 +               if (IS_ERR(bh)) {
992 +                       retval = PTR_ERR(bh);
993 +                       bh = NULL;
994 +                       goto out;
995 +               }
996 +               retval = add_dirent_to_buf(handle, &fname, dir, inode,
997 +                                          NULL, bh);
998                 if (retval != -ENOSPC)
999                         goto out;
1001                 if (blocks == 1 && !dx_fallback &&
1002                     EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) {
1003 -                       retval = make_indexed_dir(handle, dentry, inode, bh);
1004 +                       retval = make_indexed_dir(handle, &fname, dentry,
1005 +                                                 inode, bh);
1006                         bh = NULL; /* make_indexed_dir releases bh */
1007                         goto out;
1008                 }
1009                 brelse(bh);
1010         }
1011         bh = ext4_append(handle, dir, &block);
1012 -       if (IS_ERR(bh))
1013 -               return PTR_ERR(bh);
1014 +       if (IS_ERR(bh)) {
1015 +               retval = PTR_ERR(bh);
1016 +               bh = NULL;
1017 +               goto out;
1018 +       }
1019         de = (struct ext4_dir_entry_2 *) bh->b_data;
1020         de->inode = 0;
1021         de->rec_len = ext4_rec_len_to_disk(blocksize - csum_size, blocksize);
1022 @@ -2209,8 +2135,9 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
1023                 initialize_dirent_tail(t, blocksize);
1024         }
1026 -       retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
1027 +       retval = add_dirent_to_buf(handle, &fname, dir, inode, de, bh);
1028  out:
1029 +       ext4_fname_free_filename(&fname);
1030         brelse(bh);
1031         if (retval == 0)
1032                 ext4_set_inode_state(inode, EXT4_STATE_NEWENTRY);
1033 @@ -2220,19 +2147,18 @@ out:
1034  /*
1035   * Returns 0 for success, or a negative error value
1036   */
1037 -static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1038 -                            struct inode *inode)
1039 +static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,
1040 +                            struct dentry *dentry, struct inode *inode)
1042         struct dx_frame frames[2], *frame;
1043         struct dx_entry *entries, *at;
1044 -       struct dx_hash_info hinfo;
1045         struct buffer_head *bh;
1046         struct inode *dir = d_inode(dentry->d_parent);
1047         struct super_block *sb = dir->i_sb;
1048         struct ext4_dir_entry_2 *de;
1049         int err;
1051 -       frame = dx_probe(&dentry->d_name, dir, &hinfo, frames);
1052 +       frame = dx_probe(fname, dir, NULL, frames);
1053         if (IS_ERR(frame))
1054                 return PTR_ERR(frame);
1055         entries = frame->entries;
1056 @@ -2249,7 +2175,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1057         if (err)
1058                 goto journal_error;
1060 -       err = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
1061 +       err = add_dirent_to_buf(handle, fname, dir, inode, NULL, bh);
1062         if (err != -ENOSPC)
1063                 goto cleanup;
1065 @@ -2345,12 +2271,12 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1066                         goto cleanup;
1067                 }
1068         }
1069 -       de = do_split(handle, dir, &bh, frame, &hinfo);
1070 +       de = do_split(handle, dir, &bh, frame, &fname->hinfo);
1071         if (IS_ERR(de)) {
1072                 err = PTR_ERR(de);
1073                 goto cleanup;
1074         }
1075 -       err = add_dirent_to_buf(handle, dentry, inode, de, bh);
1076 +       err = add_dirent_to_buf(handle, fname, dir, inode, de, bh);
1077         goto cleanup;
1079  journal_error: