aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@google.com>2015-04-12 01:07:01 -0400
committerTheodore Ts'o <tytso@mit.edu>2015-04-12 01:07:01 -0400
commitb30984864406ad01b72eee486add103e9cb3526f (patch)
tree0c0e6cefa0691c6747504e2e4336a2eb488cab67 /fs
parent4bdfc873ba34e425d6532581b4127b960274272a (diff)
ext4 crypto: partial update to namei.c for fname crypto
Modifies dx_show_leaf and dx_probe to support fname encryption. Filename encryption not yet enabled. Signed-off-by: Uday Savagaonkar <savagaon@google.com> Signed-off-by: Ildar Muslukhov <ildarm@google.com> Signed-off-by: Michael Halcrow <mhalcrow@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/namei.c109
1 files changed, 101 insertions, 8 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index eb11a1b8a3d5..85add9a9e1cd 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -585,8 +585,10 @@ struct stats
585 unsigned bcount; 585 unsigned bcount;
586}; 586};
587 587
588static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext4_dir_entry_2 *de, 588static struct stats dx_show_leaf(struct inode *dir,
589 int size, int show_names) 589 struct dx_hash_info *hinfo,
590 struct ext4_dir_entry_2 *de,
591 int size, int show_names)
590{ 592{
591 unsigned names = 0, space = 0; 593 unsigned names = 0, space = 0;
592 char *base = (char *) de; 594 char *base = (char *) de;
@@ -599,12 +601,80 @@ static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext4_dir_ent
599 { 601 {
600 if (show_names) 602 if (show_names)
601 { 603 {
604#ifdef CONFIG_EXT4_FS_ENCRYPTION
605 int len;
606 char *name;
607 struct ext4_str fname_crypto_str
608 = {.name = NULL, .len = 0};
609 struct ext4_fname_crypto_ctx *ctx = NULL;
610 int res;
611
612 name = de->name;
613 len = de->name_len;
614 ctx = ext4_get_fname_crypto_ctx(dir,
615 EXT4_NAME_LEN);
616 if (IS_ERR(ctx)) {
617 printk(KERN_WARNING "Error acquiring"
618 " crypto ctxt--skipping crypto\n");
619 ctx = NULL;
620 }
621 if (ctx == NULL) {
622 /* Directory is not encrypted */
623 ext4fs_dirhash(de->name,
624 de->name_len, &h);
625 printk("%*.s:(U)%x.%u ", len,
626 name, h.hash,
627 (unsigned) ((char *) de
628 - base));
629 } else {
630 /* Directory is encrypted */
631 res = ext4_fname_crypto_alloc_buffer(
632 ctx, de->name_len,
633 &fname_crypto_str);
634 if (res < 0) {
635 printk(KERN_WARNING "Error "
636 "allocating crypto "
637 "buffer--skipping "
638 "crypto\n");
639 ext4_put_fname_crypto_ctx(&ctx);
640 ctx = NULL;
641 }
642 res = ext4_fname_disk_to_usr(ctx, de,
643 &fname_crypto_str);
644 if (res < 0) {
645 printk(KERN_WARNING "Error "
646 "converting filename "
647 "from disk to usr"
648 "\n");
649 name = "??";
650 len = 2;
651 } else {
652 name = fname_crypto_str.name;
653 len = fname_crypto_str.len;
654 }
655 res = ext4_fname_disk_to_hash(ctx, de,
656 &h);
657 if (res < 0) {
658 printk(KERN_WARNING "Error "
659 "converting filename "
660 "from disk to htree"
661 "\n");
662 h.hash = 0xDEADBEEF;
663 }
664 printk("%*.s:(E)%x.%u ", len, name,
665 h.hash, (unsigned) ((char *) de
666 - base));
667 ext4_put_fname_crypto_ctx(&ctx);
668 ext4_fname_crypto_free_buffer(
669 &fname_crypto_str);
670 }
671#else
602 int len = de->name_len; 672 int len = de->name_len;
603 char *name = de->name; 673 char *name = de->name;
604 while (len--) printk("%c", *name++);
605 ext4fs_dirhash(de->name, de->name_len, &h); 674 ext4fs_dirhash(de->name, de->name_len, &h);
606 printk(":%x.%u ", h.hash, 675 printk("%*.s:%x.%u ", len, name, h.hash,
607 (unsigned) ((char *) de - base)); 676 (unsigned) ((char *) de - base));
677#endif
608 } 678 }
609 space += EXT4_DIR_REC_LEN(de->name_len); 679 space += EXT4_DIR_REC_LEN(de->name_len);
610 names++; 680 names++;
@@ -622,7 +692,6 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
622 unsigned count = dx_get_count(entries), names = 0, space = 0, i; 692 unsigned count = dx_get_count(entries), names = 0, space = 0, i;
623 unsigned bcount = 0; 693 unsigned bcount = 0;
624 struct buffer_head *bh; 694 struct buffer_head *bh;
625 int err;
626 printk("%i indexed blocks...\n", count); 695 printk("%i indexed blocks...\n", count);
627 for (i = 0; i < count; i++, entries++) 696 for (i = 0; i < count; i++, entries++)
628 { 697 {
@@ -636,7 +705,8 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
636 continue; 705 continue;
637 stats = levels? 706 stats = levels?
638 dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1): 707 dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1):
639 dx_show_leaf(hinfo, (struct ext4_dir_entry_2 *) bh->b_data, blocksize, 0); 708 dx_show_leaf(dir, hinfo, (struct ext4_dir_entry_2 *)
709 bh->b_data, blocksize, 0);
640 names += stats.names; 710 names += stats.names;
641 space += stats.space; 711 space += stats.space;
642 bcount += stats.bcount; 712 bcount += stats.bcount;
@@ -686,8 +756,28 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
686 if (hinfo->hash_version <= DX_HASH_TEA) 756 if (hinfo->hash_version <= DX_HASH_TEA)
687 hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned; 757 hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;
688 hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed; 758 hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;
759#ifdef CONFIG_EXT4_FS_ENCRYPTION
760 if (d_name) {
761 struct ext4_fname_crypto_ctx *ctx = NULL;
762 int res;
763
764 /* Check if the directory is encrypted */
765 ctx = ext4_get_fname_crypto_ctx(dir, EXT4_NAME_LEN);
766 if (IS_ERR(ctx)) {
767 ret_err = ERR_PTR(PTR_ERR(ctx));
768 goto fail;
769 }
770 res = ext4_fname_usr_to_hash(ctx, d_name, hinfo);
771 if (res < 0) {
772 ret_err = ERR_PTR(res);
773 goto fail;
774 }
775 ext4_put_fname_crypto_ctx(&ctx);
776 }
777#else
689 if (d_name) 778 if (d_name)
690 ext4fs_dirhash(d_name->name, d_name->len, hinfo); 779 ext4fs_dirhash(d_name->name, d_name->len, hinfo);
780#endif
691 hash = hinfo->hash; 781 hash = hinfo->hash;
692 782
693 if (root->info.unused_flags & 1) { 783 if (root->info.unused_flags & 1) {
@@ -772,6 +862,7 @@ fail:
772 brelse(frame->bh); 862 brelse(frame->bh);
773 frame--; 863 frame--;
774 } 864 }
865
775 if (ret_err == ERR_PTR(ERR_BAD_DX_DIR)) 866 if (ret_err == ERR_PTR(ERR_BAD_DX_DIR))
776 ext4_warning(dir->i_sb, 867 ext4_warning(dir->i_sb,
777 "Corrupt dir inode %lu, running e2fsck is " 868 "Corrupt dir inode %lu, running e2fsck is "
@@ -1604,8 +1695,10 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir,
1604 initialize_dirent_tail(t, blocksize); 1695 initialize_dirent_tail(t, blocksize);
1605 } 1696 }
1606 1697
1607 dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data1, blocksize, 1)); 1698 dxtrace(dx_show_leaf(dir, hinfo, (struct ext4_dir_entry_2 *) data1,
1608 dxtrace(dx_show_leaf (hinfo, (struct ext4_dir_entry_2 *) data2, blocksize, 1)); 1699 blocksize, 1));
1700 dxtrace(dx_show_leaf(dir, hinfo, (struct ext4_dir_entry_2 *) data2,
1701 blocksize, 1));
1609 1702
1610 /* Which block gets the new entry? */ 1703 /* Which block gets the new entry? */
1611 if (hinfo->hash >= hash2) { 1704 if (hinfo->hash >= hash2) {