diff options
author | Michael Halcrow <mhalcrow@us.ibm.com> | 2007-02-16 04:28:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-16 11:14:01 -0500 |
commit | eb95e7ffa50fa2921ef1845a5dcb2fe5b21e83a2 (patch) | |
tree | 665bc814f571b88988b668e34cf45f2981853e57 | |
parent | 29dbb3fc8020f025bc38b262ec494e19fd3eac02 (diff) |
[PATCH] eCryptfs: Reduce stack usage in ecryptfs_generate_key_packet_set()
eCryptfs is gobbling a lot of stack in ecryptfs_generate_key_packet_set()
because it allocates a temporary memory-hungry ecryptfs_key_record struct.
This patch introduces a new kmem_cache for that struct and converts
ecryptfs_generate_key_packet_set() to use it.
Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 1 | ||||
-rw-r--r-- | fs/ecryptfs/keystore.c | 26 | ||||
-rw-r--r-- | fs/ecryptfs/main.c | 5 |
3 files changed, 24 insertions, 8 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index b3609b7cdf11..403e3bad1455 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -467,6 +467,7 @@ extern struct kmem_cache *ecryptfs_header_cache_1; | |||
467 | extern struct kmem_cache *ecryptfs_header_cache_2; | 467 | extern struct kmem_cache *ecryptfs_header_cache_2; |
468 | extern struct kmem_cache *ecryptfs_xattr_cache; | 468 | extern struct kmem_cache *ecryptfs_xattr_cache; |
469 | extern struct kmem_cache *ecryptfs_lower_page_cache; | 469 | extern struct kmem_cache *ecryptfs_lower_page_cache; |
470 | extern struct kmem_cache *ecryptfs_key_record_cache; | ||
470 | 471 | ||
471 | int ecryptfs_interpose(struct dentry *hidden_dentry, | 472 | int ecryptfs_interpose(struct dentry *hidden_dentry, |
472 | struct dentry *this_dentry, struct super_block *sb, | 473 | struct dentry *this_dentry, struct super_block *sb, |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 81156e95ef8e..b550dea8eee6 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -1638,6 +1638,8 @@ out: | |||
1638 | return rc; | 1638 | return rc; |
1639 | } | 1639 | } |
1640 | 1640 | ||
1641 | struct kmem_cache *ecryptfs_key_record_cache; | ||
1642 | |||
1641 | /** | 1643 | /** |
1642 | * ecryptfs_generate_key_packet_set | 1644 | * ecryptfs_generate_key_packet_set |
1643 | * @dest: Virtual address from which to write the key record set | 1645 | * @dest: Virtual address from which to write the key record set |
@@ -1664,50 +1666,55 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1664 | &ecryptfs_superblock_to_private( | 1666 | &ecryptfs_superblock_to_private( |
1665 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | 1667 | ecryptfs_dentry->d_sb)->mount_crypt_stat; |
1666 | size_t written; | 1668 | size_t written; |
1667 | struct ecryptfs_key_record key_rec; | 1669 | struct ecryptfs_key_record *key_rec; |
1668 | int rc = 0; | 1670 | int rc = 0; |
1669 | 1671 | ||
1670 | (*len) = 0; | 1672 | (*len) = 0; |
1673 | key_rec = kmem_cache_alloc(ecryptfs_key_record_cache, GFP_KERNEL); | ||
1674 | if (!key_rec) { | ||
1675 | rc = -ENOMEM; | ||
1676 | goto out; | ||
1677 | } | ||
1671 | if (mount_crypt_stat->global_auth_tok) { | 1678 | if (mount_crypt_stat->global_auth_tok) { |
1672 | auth_tok = mount_crypt_stat->global_auth_tok; | 1679 | auth_tok = mount_crypt_stat->global_auth_tok; |
1673 | if (auth_tok->token_type == ECRYPTFS_PASSWORD) { | 1680 | if (auth_tok->token_type == ECRYPTFS_PASSWORD) { |
1674 | rc = write_tag_3_packet((dest_base + (*len)), | 1681 | rc = write_tag_3_packet((dest_base + (*len)), |
1675 | max, auth_tok, | 1682 | max, auth_tok, |
1676 | crypt_stat, &key_rec, | 1683 | crypt_stat, key_rec, |
1677 | &written); | 1684 | &written); |
1678 | if (rc) { | 1685 | if (rc) { |
1679 | ecryptfs_printk(KERN_WARNING, "Error " | 1686 | ecryptfs_printk(KERN_WARNING, "Error " |
1680 | "writing tag 3 packet\n"); | 1687 | "writing tag 3 packet\n"); |
1681 | goto out; | 1688 | goto out_free; |
1682 | } | 1689 | } |
1683 | (*len) += written; | 1690 | (*len) += written; |
1684 | /* Write auth tok signature packet */ | 1691 | /* Write auth tok signature packet */ |
1685 | rc = write_tag_11_packet( | 1692 | rc = write_tag_11_packet( |
1686 | (dest_base + (*len)), | 1693 | (dest_base + (*len)), |
1687 | (max - (*len)), | 1694 | (max - (*len)), |
1688 | key_rec.sig, ECRYPTFS_SIG_SIZE, &written); | 1695 | key_rec->sig, ECRYPTFS_SIG_SIZE, &written); |
1689 | if (rc) { | 1696 | if (rc) { |
1690 | ecryptfs_printk(KERN_ERR, "Error writing " | 1697 | ecryptfs_printk(KERN_ERR, "Error writing " |
1691 | "auth tok signature packet\n"); | 1698 | "auth tok signature packet\n"); |
1692 | goto out; | 1699 | goto out_free; |
1693 | } | 1700 | } |
1694 | (*len) += written; | 1701 | (*len) += written; |
1695 | } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { | 1702 | } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { |
1696 | rc = write_tag_1_packet(dest_base + (*len), | 1703 | rc = write_tag_1_packet(dest_base + (*len), |
1697 | max, auth_tok, | 1704 | max, auth_tok, |
1698 | crypt_stat,mount_crypt_stat, | 1705 | crypt_stat,mount_crypt_stat, |
1699 | &key_rec, &written); | 1706 | key_rec, &written); |
1700 | if (rc) { | 1707 | if (rc) { |
1701 | ecryptfs_printk(KERN_WARNING, "Error " | 1708 | ecryptfs_printk(KERN_WARNING, "Error " |
1702 | "writing tag 1 packet\n"); | 1709 | "writing tag 1 packet\n"); |
1703 | goto out; | 1710 | goto out_free; |
1704 | } | 1711 | } |
1705 | (*len) += written; | 1712 | (*len) += written; |
1706 | } else { | 1713 | } else { |
1707 | ecryptfs_printk(KERN_WARNING, "Unsupported " | 1714 | ecryptfs_printk(KERN_WARNING, "Unsupported " |
1708 | "authentication token type\n"); | 1715 | "authentication token type\n"); |
1709 | rc = -EINVAL; | 1716 | rc = -EINVAL; |
1710 | goto out; | 1717 | goto out_free; |
1711 | } | 1718 | } |
1712 | } else | 1719 | } else |
1713 | BUG(); | 1720 | BUG(); |
@@ -1717,6 +1724,9 @@ ecryptfs_generate_key_packet_set(char *dest_base, | |||
1717 | ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n"); | 1724 | ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n"); |
1718 | rc = -EIO; | 1725 | rc = -EIO; |
1719 | } | 1726 | } |
1727 | |||
1728 | out_free: | ||
1729 | kmem_cache_free(ecryptfs_key_record_cache, key_rec); | ||
1720 | out: | 1730 | out: |
1721 | if (rc) | 1731 | if (rc) |
1722 | (*len) = 0; | 1732 | (*len) = 0; |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 26fe405a5763..80044d196fe0 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -651,6 +651,11 @@ static struct ecryptfs_cache_info { | |||
651 | .name = "ecryptfs_lower_page_cache", | 651 | .name = "ecryptfs_lower_page_cache", |
652 | .size = PAGE_CACHE_SIZE, | 652 | .size = PAGE_CACHE_SIZE, |
653 | }, | 653 | }, |
654 | { | ||
655 | .cache = &ecryptfs_key_record_cache, | ||
656 | .name = "ecryptfs_key_record_cache", | ||
657 | .size = sizeof(struct ecryptfs_key_record), | ||
658 | }, | ||
654 | }; | 659 | }; |
655 | 660 | ||
656 | static void ecryptfs_free_kmem_caches(void) | 661 | static void ecryptfs_free_kmem_caches(void) |