diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2010-05-21 11:09:58 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-05-21 18:31:28 -0400 |
| commit | 48c1e44aceca577aa35be509714bd9ec4b4c3837 (patch) | |
| tree | 5fe7c1f352e21bf1d58763cb2f4158d94e080923 /fs/ecryptfs/inode.c | |
| parent | 02bd97997a07a89cb9311c7f00864cfc785c37f9 (diff) | |
switch ecryptfs_write() to struct inode *, kill on-stack fake files
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ecryptfs/inode.c')
| -rw-r--r-- | fs/ecryptfs/inode.c | 48 |
1 files changed, 8 insertions, 40 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index e2d4418affac..65dee2f336ae 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -142,19 +142,10 @@ out: | |||
| 142 | static int grow_file(struct dentry *ecryptfs_dentry) | 142 | static int grow_file(struct dentry *ecryptfs_dentry) |
| 143 | { | 143 | { |
| 144 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; | 144 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; |
| 145 | struct file fake_file; | ||
| 146 | struct ecryptfs_file_info tmp_file_info; | ||
| 147 | char zero_virt[] = { 0x00 }; | 145 | char zero_virt[] = { 0x00 }; |
| 148 | int rc = 0; | 146 | int rc = 0; |
| 149 | 147 | ||
| 150 | memset(&fake_file, 0, sizeof(fake_file)); | 148 | rc = ecryptfs_write(ecryptfs_inode, zero_virt, 0, 1); |
| 151 | fake_file.f_path.dentry = ecryptfs_dentry; | ||
| 152 | memset(&tmp_file_info, 0, sizeof(tmp_file_info)); | ||
| 153 | ecryptfs_set_file_private(&fake_file, &tmp_file_info); | ||
| 154 | ecryptfs_set_file_lower( | ||
| 155 | &fake_file, | ||
| 156 | ecryptfs_inode_to_private(ecryptfs_inode)->lower_file); | ||
| 157 | rc = ecryptfs_write(&fake_file, zero_virt, 0, 1); | ||
| 158 | i_size_write(ecryptfs_inode, 0); | 149 | i_size_write(ecryptfs_inode, 0); |
| 159 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | 150 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); |
| 160 | ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= | 151 | ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= |
| @@ -784,8 +775,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 784 | { | 775 | { |
| 785 | int rc = 0; | 776 | int rc = 0; |
| 786 | struct inode *inode = dentry->d_inode; | 777 | struct inode *inode = dentry->d_inode; |
| 787 | struct dentry *lower_dentry; | ||
| 788 | struct file fake_ecryptfs_file; | ||
| 789 | struct ecryptfs_crypt_stat *crypt_stat; | 778 | struct ecryptfs_crypt_stat *crypt_stat; |
| 790 | loff_t i_size = i_size_read(inode); | 779 | loff_t i_size = i_size_read(inode); |
| 791 | loff_t lower_size_before_truncate; | 780 | loff_t lower_size_before_truncate; |
| @@ -796,23 +785,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 796 | goto out; | 785 | goto out; |
| 797 | } | 786 | } |
| 798 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 787 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
| 799 | /* Set up a fake ecryptfs file, this is used to interface with | ||
| 800 | * the file in the underlying filesystem so that the | ||
| 801 | * truncation has an effect there as well. */ | ||
| 802 | memset(&fake_ecryptfs_file, 0, sizeof(fake_ecryptfs_file)); | ||
| 803 | fake_ecryptfs_file.f_path.dentry = dentry; | ||
| 804 | /* Released at out_free: label */ | ||
| 805 | ecryptfs_set_file_private(&fake_ecryptfs_file, | ||
| 806 | kmem_cache_alloc(ecryptfs_file_info_cache, | ||
| 807 | GFP_KERNEL)); | ||
| 808 | if (unlikely(!ecryptfs_file_to_private(&fake_ecryptfs_file))) { | ||
| 809 | rc = -ENOMEM; | ||
| 810 | goto out; | ||
| 811 | } | ||
| 812 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
| 813 | ecryptfs_set_file_lower( | ||
| 814 | &fake_ecryptfs_file, | ||
| 815 | ecryptfs_inode_to_private(dentry->d_inode)->lower_file); | ||
| 816 | /* Switch on growing or shrinking file */ | 788 | /* Switch on growing or shrinking file */ |
| 817 | if (ia->ia_size > i_size) { | 789 | if (ia->ia_size > i_size) { |
| 818 | char zero[] = { 0x00 }; | 790 | char zero[] = { 0x00 }; |
| @@ -822,7 +794,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 822 | * this triggers code that will fill in 0's throughout | 794 | * this triggers code that will fill in 0's throughout |
| 823 | * the intermediate portion of the previous end of the | 795 | * the intermediate portion of the previous end of the |
| 824 | * file and the new and of the file */ | 796 | * file and the new and of the file */ |
| 825 | rc = ecryptfs_write(&fake_ecryptfs_file, zero, | 797 | rc = ecryptfs_write(inode, zero, |
| 826 | (ia->ia_size - 1), 1); | 798 | (ia->ia_size - 1), 1); |
| 827 | } else { /* ia->ia_size < i_size_read(inode) */ | 799 | } else { /* ia->ia_size < i_size_read(inode) */ |
| 828 | /* We're chopping off all the pages down to the page | 800 | /* We're chopping off all the pages down to the page |
| @@ -835,10 +807,10 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 835 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 807 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
| 836 | rc = vmtruncate(inode, ia->ia_size); | 808 | rc = vmtruncate(inode, ia->ia_size); |
| 837 | if (rc) | 809 | if (rc) |
| 838 | goto out_free; | 810 | goto out; |
| 839 | lower_ia->ia_size = ia->ia_size; | 811 | lower_ia->ia_size = ia->ia_size; |
| 840 | lower_ia->ia_valid |= ATTR_SIZE; | 812 | lower_ia->ia_valid |= ATTR_SIZE; |
| 841 | goto out_free; | 813 | goto out; |
| 842 | } | 814 | } |
| 843 | if (num_zeros) { | 815 | if (num_zeros) { |
| 844 | char *zeros_virt; | 816 | char *zeros_virt; |
| @@ -846,16 +818,16 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 846 | zeros_virt = kzalloc(num_zeros, GFP_KERNEL); | 818 | zeros_virt = kzalloc(num_zeros, GFP_KERNEL); |
| 847 | if (!zeros_virt) { | 819 | if (!zeros_virt) { |
| 848 | rc = -ENOMEM; | 820 | rc = -ENOMEM; |
| 849 | goto out_free; | 821 | goto out; |
| 850 | } | 822 | } |
| 851 | rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt, | 823 | rc = ecryptfs_write(inode, zeros_virt, |
| 852 | ia->ia_size, num_zeros); | 824 | ia->ia_size, num_zeros); |
| 853 | kfree(zeros_virt); | 825 | kfree(zeros_virt); |
| 854 | if (rc) { | 826 | if (rc) { |
| 855 | printk(KERN_ERR "Error attempting to zero out " | 827 | printk(KERN_ERR "Error attempting to zero out " |
| 856 | "the remainder of the end page on " | 828 | "the remainder of the end page on " |
| 857 | "reducing truncate; rc = [%d]\n", rc); | 829 | "reducing truncate; rc = [%d]\n", rc); |
| 858 | goto out_free; | 830 | goto out; |
| 859 | } | 831 | } |
| 860 | } | 832 | } |
| 861 | vmtruncate(inode, ia->ia_size); | 833 | vmtruncate(inode, ia->ia_size); |
| @@ -864,7 +836,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 864 | printk(KERN_ERR "Problem with " | 836 | printk(KERN_ERR "Problem with " |
| 865 | "ecryptfs_write_inode_size_to_metadata; " | 837 | "ecryptfs_write_inode_size_to_metadata; " |
| 866 | "rc = [%d]\n", rc); | 838 | "rc = [%d]\n", rc); |
| 867 | goto out_free; | 839 | goto out; |
| 868 | } | 840 | } |
| 869 | /* We are reducing the size of the ecryptfs file, and need to | 841 | /* We are reducing the size of the ecryptfs file, and need to |
| 870 | * know if we need to reduce the size of the lower file. */ | 842 | * know if we need to reduce the size of the lower file. */ |
| @@ -878,10 +850,6 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
| 878 | } else | 850 | } else |
| 879 | lower_ia->ia_valid &= ~ATTR_SIZE; | 851 | lower_ia->ia_valid &= ~ATTR_SIZE; |
| 880 | } | 852 | } |
| 881 | out_free: | ||
| 882 | if (ecryptfs_file_to_private(&fake_ecryptfs_file)) | ||
| 883 | kmem_cache_free(ecryptfs_file_info_cache, | ||
| 884 | ecryptfs_file_to_private(&fake_ecryptfs_file)); | ||
| 885 | out: | 853 | out: |
| 886 | return rc; | 854 | return rc; |
| 887 | } | 855 | } |
