aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-02-16 04:28:40 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-16 11:14:01 -0500
commiteb95e7ffa50fa2921ef1845a5dcb2fe5b21e83a2 (patch)
tree665bc814f571b88988b668e34cf45f2981853e57
parent29dbb3fc8020f025bc38b262ec494e19fd3eac02 (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.h1
-rw-r--r--fs/ecryptfs/keystore.c26
-rw-r--r--fs/ecryptfs/main.c5
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;
467extern struct kmem_cache *ecryptfs_header_cache_2; 467extern struct kmem_cache *ecryptfs_header_cache_2;
468extern struct kmem_cache *ecryptfs_xattr_cache; 468extern struct kmem_cache *ecryptfs_xattr_cache;
469extern struct kmem_cache *ecryptfs_lower_page_cache; 469extern struct kmem_cache *ecryptfs_lower_page_cache;
470extern struct kmem_cache *ecryptfs_key_record_cache;
470 471
471int ecryptfs_interpose(struct dentry *hidden_dentry, 472int 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
1641struct 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
1728out_free:
1729 kmem_cache_free(ecryptfs_key_record_cache, key_rec);
1720out: 1730out:
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
656static void ecryptfs_free_kmem_caches(void) 661static void ecryptfs_free_kmem_caches(void)