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
13 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
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,
30 - * Calculate the htree hash from a filename from user space
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)
38 - struct ext4_str tmp;
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;
48 + ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
50 + return PTR_ERR(ctx);
51 + if ((ctx == NULL) ||
52 ((iname->name[0] == '.') &&
54 ((iname->name[1] == '.') && (iname->len == 2))))) {
55 - ext4fs_dirhash(iname->name, iname->len, hinfo);
57 + fname->disk_name.name = (unsigned char *) iname->name;
58 + fname->disk_name.len = iname->len;
62 - if (!ctx->has_valid_key && iname->name[0] == '_') {
63 - if (iname->len != 33)
65 - ret = digest_decode(iname->name+1, iname->len, buf);
68 - memcpy(&hinfo->hash, buf, 4);
69 - memcpy(&hinfo->minor_hash, buf + 4, 4);
71 + if (ctx->has_valid_key) {
72 + ret = ext4_fname_crypto_alloc_buffer(ctx, iname->len,
73 + &fname->crypto_buf);
76 + ret = ext4_fname_encrypt(ctx, iname, &fname->crypto_buf);
79 + fname->disk_name.name = fname->crypto_buf.name;
80 + fname->disk_name.len = fname->crypto_buf.len;
85 - if (!ctx->has_valid_key && iname->name[0] != '_') {
86 - if (iname->len > 43)
88 - ret = digest_decode(iname->name, iname->len, buf);
89 - ext4fs_dirhash(buf, ret, hinfo);
96 - /* First encrypt the plaintext name */
97 - ret = ext4_fname_crypto_alloc_buffer(ctx, iname->len, &tmp);
101 - ret = ext4_fname_encrypt(ctx, iname, &tmp);
103 - ext4fs_dirhash(tmp.name, tmp.len, hinfo);
105 + /* We don't have the key and we are doing a lookup; decode the
106 + * user-supplied name
108 + if (iname->name[0] == '_')
110 + if ((bigname && (iname->len != 33)) ||
111 + (!bigname && (iname->len > 43))) {
115 - ext4_fname_crypto_free_buffer(&tmp);
116 + fname->crypto_buf.name = kmalloc(32, GFP_KERNEL);
117 + if (fname->crypto_buf.name == NULL) {
121 + ret = digest_decode(iname->name + bigname, iname->len - bigname,
122 + fname->crypto_buf.name);
127 + fname->crypto_buf.len = ret;
129 + memcpy(&fname->hinfo.hash, fname->crypto_buf.name, 4);
130 + memcpy(&fname->hinfo.minor_hash, fname->crypto_buf.name + 4, 4);
132 + fname->disk_name.name = fname->crypto_buf.name;
133 + fname->disk_name.len = fname->crypto_buf.len;
137 + ext4_put_fname_crypto_ctx(&ctx);
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)
147 - int bigname = (*name == '_');
149 - if (ctx->has_valid_key) {
150 - if (cstr->name == NULL) {
153 - ret = ext4_fname_crypto_alloc_buffer(ctx, len, cstr);
158 - ret = ext4_fname_encrypt(ctx, &istr, cstr);
163 - if (cstr->name == NULL) {
164 - cstr->name = kmalloc(32, GFP_KERNEL);
165 - if (cstr->name == NULL)
167 - if ((bigname && (len != 33)) ||
168 - (!bigname && (len > 43)))
170 - ret = digest_decode(name+bigname, len-bigname,
179 - if (de->name_len < 16)
181 - ret = memcmp(de->name + de->name_len - 16,
182 - cstr->name + 8, 16);
183 - return (ret == 0) ? 1 : 0;
186 - if (de->name_len != cstr->len)
188 - ret = memcmp(de->name, cstr->name, cstr->len);
189 - return (ret == 0) ? 1 : 0;
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
203 @@ -1838,6 +1838,17 @@ struct dx_hash_info
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;
216 +#define fname_name(p) ((p)->disk_name.name)
217 +#define fname_len(p) ((p)->disk_name.len)
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,
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,
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);
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,
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;
259 +static inline void ext4_fname_free_filename(struct ext4_filename *fname) { }
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,
274 - const struct qstr *iname,
275 - const char *name, int namelen);
276 + struct inode *inode,
277 + struct ext4_dir_entry_2 *de,
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,
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,
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,
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,
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.
331 static int ext4_add_dirent_to_inline(handle_t *handle,
332 + struct ext4_filename *fname,
333 struct dentry *dentry,
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;
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);
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);
356 - ext4_insert_dentry(dir, inode, de, inline_size, &dentry->d_name,
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.
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;
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);
382 @@ -1289,8 +1286,9 @@ int ext4_try_add_inline_entry(handle_t *handle, struct dentry *dentry,
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,
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);
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);
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,
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,
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,
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);
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
472 - struct ext4_fname_crypto_ctx *ctx = NULL;
475 - /* Check if the directory is encrypted */
476 - ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
478 - ret_err = ERR_PTR(PTR_ERR(ctx));
481 - res = ext4_fname_usr_to_hash(ctx, d_name, hinfo);
483 - ret_err = ERR_PTR(res);
486 - ext4_put_fname_crypto_ctx(&ctx);
490 - ext4fs_dirhash(d_name->name, d_name->len, hinfo);
492 + if (fname && fname_name(fname))
493 + ext4fs_dirhash(fname_name(fname), fname_len(fname), hinfo);
496 if (root->info.unused_flags & 1) {
497 @@ -1155,12 +1137,13 @@ errout:
499 static inline int search_dirblock(struct buffer_head *bh,
501 + struct ext4_filename *fname,
502 const struct qstr *d_name,
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);
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.
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)
524 + const void *name = fname_name(fname);
525 + u32 len = fname_len(fname);
530 #ifdef CONFIG_EXT4_FS_ENCRYPTION
532 - return ext4_fname_match(ctx, fname_crypto_str, len, name, de);
533 + if (unlikely(!name)) {
534 + if (fname->usr_fname->name[0] == '_') {
536 + if (de->name_len < 16)
538 + ret = memcmp(de->name + de->name_len - 16,
539 + fname->crypto_buf.name + 8, 16);
540 + return (ret == 0) ? 1 : 0;
542 + name = fname->crypto_buf.name;
543 + len = fname->crypto_buf.len;
546 - if (len != de->name_len)
547 + if (de->name_len != len)
549 - res = memcmp(name, de->name, len);
550 - return (res == 0) ? 1 : 0;
551 + return (memcmp(de->name, name, len) == 0) ? 1 : 0;
555 * Returns 0 if not found, -1 on failure, and 1 on success
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;
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};
574 - ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
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,
586 + res = ext4_match(fname, de);
590 @@ -1322,8 +1305,6 @@ int search_dir(struct buffer_head *bh, char *search_buf, int buf_size,
594 - ext4_put_fname_crypto_ctx(&ctx);
595 - ext4_fname_crypto_free_buffer(&fname_crypto_str);
599 @@ -1370,7 +1351,8 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
604 + int i, namelen, retval;
605 + struct ext4_filename fname;
609 @@ -1378,14 +1360,18 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
610 if (namelen > EXT4_NAME_LEN)
613 + retval = ext4_fname_setup_filename(dir, d_name, 1, &fname);
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,
622 if (has_inline_data) {
626 + goto cleanup_and_exit;
630 @@ -1400,14 +1386,14 @@ static struct buffer_head * ext4_find_entry (struct inode *dir,
634 - bh = ext4_dx_find_entry(dir, d_name, res_dir);
635 + ret = ext4_dx_find_entry(dir, &fname, res_dir);
637 * On success, or if the error was file not found,
638 * return. Otherwise, fall back to doing a search the
641 - if (!IS_ERR(bh) || PTR_ERR(bh) != ERR_BAD_DX_DIR)
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, "
648 @@ -1438,8 +1424,10 @@ restart:
650 bh = ext4_getblk(NULL, dir, b++, 0);
651 if (unlikely(IS_ERR(bh))) {
656 + goto cleanup_and_exit;
661 @@ -1469,7 +1457,7 @@ restart:
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);
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);
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;
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
695 - frame = dx_probe(d_name, dir, &hinfo, frames);
696 + frame = dx_probe(fname, dir, NULL, frames);
698 return (struct buffer_head *) frame;
700 @@ -1525,7 +1515,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
704 - retval = search_dirblock(bh, dir, d_name,
705 + retval = search_dirblock(bh, dir, fname, d_name,
706 block << EXT4_BLOCK_SIZE_BITS(sb),
709 @@ -1537,7 +1527,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
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,
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));
730 unsigned int offset = 0;
732 - struct ext4_fname_crypto_ctx *ctx = NULL;
733 - struct ext4_str fname_crypto_str = {.name = NULL, .len = 0};
736 - ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
741 - /* Calculate record length needed to store the entry */
742 - res = ext4_fname_crypto_namelen_on_disk(ctx, namelen);
744 - ext4_put_fname_crypto_ctx(&ctx);
747 - reclen = EXT4_DIR_REC_LEN(res);
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,
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);
762 @@ -1853,8 +1827,6 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode,
766 - ext4_put_fname_crypto_ctx(&ctx);
767 - ext4_fname_crypto_free_buffer(&fname_crypto_str);
771 @@ -1862,39 +1834,10 @@ int ext4_insert_dentry(struct inode *dir,
773 struct ext4_dir_entry_2 *de,
775 - const struct qstr *iname,
776 - const char *name, int namelen)
777 + struct ext4_filename *fname)
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;
786 - ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
789 - /* By default, the input name would be written to the disk */
790 - tmp_str.name = (unsigned char *)name;
791 - tmp_str.len = namelen;
793 - /* Directory is encrypted */
794 - res = ext4_fname_crypto_alloc_buffer(ctx, EXT4_NAME_LEN,
795 - &fname_crypto_str);
797 - ext4_put_fname_crypto_ctx(&ctx);
800 - res = ext4_fname_usr_to_disk(ctx, iname, &fname_crypto_str);
802 - ext4_put_fname_crypto_ctx(&ctx);
803 - ext4_fname_crypto_free_buffer(&fname_crypto_str);
806 - tmp_str.name = fname_crypto_str.name;
807 - tmp_str.len = fname_crypto_str.len;
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));
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.
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,
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;
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);
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);
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,
860 + err = ext4_insert_dentry(dir, inode, de, blocksize, fname);
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.
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;
878 - const char *name = dentry->d_name.name;
879 - int namelen = dentry->d_name.len;
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,
888 - struct dx_hash_info hinfo;
890 struct fake_dirent *fde;
893 -#ifdef CONFIG_EXT4_FS_ENCRYPTION
894 - ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
896 - return PTR_ERR(ctx);
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);
913 - ext4_put_fname_crypto_ctx(&ctx);
914 - ext4_mark_inode_dirty(handle, dir);
918 - ext4_put_fname_crypto_ctx(&ctx);
920 - ext4fs_dirhash(name, namelen, &hinfo);
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));
930 frame->entries = entries;
931 @@ -2108,14 +2021,14 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry,
935 - de = do_split(handle,dir, &bh, frame, &hinfo);
936 + de = do_split(handle,dir, &bh, frame, &fname->hinfo);
938 retval = PTR_ERR(de);
943 - retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
944 + retval = add_dirent_to_buf(handle, fname, dir, inode, de, bh);
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;
956 @@ -2161,10 +2075,15 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
957 if (!dentry->d_name.len)
960 + retval = ext4_fname_setup_filename(dir, &dentry->d_name, 0, &fname);
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,
974 @@ -2172,7 +2091,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
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))
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);
988 - return PTR_ERR(bh);
990 - retval = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
992 + retval = PTR_ERR(bh);
996 + retval = add_dirent_to_buf(handle, &fname, dir, inode,
998 if (retval != -ENOSPC)
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,
1006 bh = NULL; /* make_indexed_dir releases bh */
1011 bh = ext4_append(handle, dir, &block);
1013 - return PTR_ERR(bh);
1015 + retval = PTR_ERR(bh);
1019 de = (struct ext4_dir_entry_2 *) bh->b_data;
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);
1026 - retval = add_dirent_to_buf(handle, dentry, inode, de, bh);
1027 + retval = add_dirent_to_buf(handle, &fname, dir, inode, de, bh);
1029 + ext4_fname_free_filename(&fname);
1032 ext4_set_inode_state(inode, EXT4_STATE_NEWENTRY);
1033 @@ -2220,19 +2147,18 @@ out:
1035 * Returns 0 for success, or a negative error value
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;
1051 - frame = dx_probe(&dentry->d_name, dir, &hinfo, frames);
1052 + frame = dx_probe(fname, dir, NULL, frames);
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,
1060 - err = add_dirent_to_buf(handle, dentry, inode, NULL, bh);
1061 + err = add_dirent_to_buf(handle, fname, dir, inode, NULL, bh);
1065 @@ -2345,12 +2271,12 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1069 - de = do_split(handle, dir, &bh, frame, &hinfo);
1070 + de = do_split(handle, dir, &bh, frame, &fname->hinfo);
1075 - err = add_dirent_to_buf(handle, dentry, inode, de, bh);
1076 + err = add_dirent_to_buf(handle, fname, dir, inode, de, bh);