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 | } |