diff options
Diffstat (limited to 'fs/ecryptfs/inode.c')
-rw-r--r-- | fs/ecryptfs/inode.c | 84 |
1 files changed, 32 insertions, 52 deletions
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index b592938a84bc..4d4cc6a90cd5 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -143,26 +143,6 @@ out: | |||
143 | } | 143 | } |
144 | 144 | ||
145 | /** | 145 | /** |
146 | * grow_file | ||
147 | * @ecryptfs_dentry: the eCryptfs dentry | ||
148 | * | ||
149 | * This is the code which will grow the file to its correct size. | ||
150 | */ | ||
151 | static int grow_file(struct dentry *ecryptfs_dentry) | ||
152 | { | ||
153 | struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode; | ||
154 | char zero_virt[] = { 0x00 }; | ||
155 | int rc = 0; | ||
156 | |||
157 | rc = ecryptfs_write(ecryptfs_inode, zero_virt, 0, 1); | ||
158 | i_size_write(ecryptfs_inode, 0); | ||
159 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | ||
160 | ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |= | ||
161 | ECRYPTFS_NEW_FILE; | ||
162 | return rc; | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * ecryptfs_initialize_file | 146 | * ecryptfs_initialize_file |
167 | * | 147 | * |
168 | * Cause the file to be changed from a basic empty file to an ecryptfs | 148 | * Cause the file to be changed from a basic empty file to an ecryptfs |
@@ -181,7 +161,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
181 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | 161 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); |
182 | goto out; | 162 | goto out; |
183 | } | 163 | } |
184 | crypt_stat->flags |= ECRYPTFS_NEW_FILE; | ||
185 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); | 164 | ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); |
186 | rc = ecryptfs_new_file_context(ecryptfs_dentry); | 165 | rc = ecryptfs_new_file_context(ecryptfs_dentry); |
187 | if (rc) { | 166 | if (rc) { |
@@ -189,22 +168,18 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) | |||
189 | "context; rc = [%d]\n", rc); | 168 | "context; rc = [%d]\n", rc); |
190 | goto out; | 169 | goto out; |
191 | } | 170 | } |
192 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | 171 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); |
193 | if (rc) { | 172 | if (rc) { |
194 | printk(KERN_ERR "%s: Error attempting to initialize " | 173 | printk(KERN_ERR "%s: Error attempting to initialize " |
195 | "the persistent file for the dentry with name " | 174 | "the lower file for the dentry with name " |
196 | "[%s]; rc = [%d]\n", __func__, | 175 | "[%s]; rc = [%d]\n", __func__, |
197 | ecryptfs_dentry->d_name.name, rc); | 176 | ecryptfs_dentry->d_name.name, rc); |
198 | goto out; | 177 | goto out; |
199 | } | 178 | } |
200 | rc = ecryptfs_write_metadata(ecryptfs_dentry); | 179 | rc = ecryptfs_write_metadata(ecryptfs_dentry); |
201 | if (rc) { | ||
202 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); | ||
203 | goto out; | ||
204 | } | ||
205 | rc = grow_file(ecryptfs_dentry); | ||
206 | if (rc) | 180 | if (rc) |
207 | printk(KERN_ERR "Error growing file; rc = [%d]\n", rc); | 181 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); |
182 | ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); | ||
208 | out: | 183 | out: |
209 | return rc; | 184 | return rc; |
210 | } | 185 | } |
@@ -250,11 +225,9 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
250 | struct dentry *lower_dir_dentry; | 225 | struct dentry *lower_dir_dentry; |
251 | struct vfsmount *lower_mnt; | 226 | struct vfsmount *lower_mnt; |
252 | struct inode *lower_inode; | 227 | struct inode *lower_inode; |
253 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
254 | struct ecryptfs_crypt_stat *crypt_stat; | 228 | struct ecryptfs_crypt_stat *crypt_stat; |
255 | char *page_virt = NULL; | 229 | char *page_virt = NULL; |
256 | u64 file_size; | 230 | int put_lower = 0, rc = 0; |
257 | int rc = 0; | ||
258 | 231 | ||
259 | lower_dir_dentry = lower_dentry->d_parent; | 232 | lower_dir_dentry = lower_dentry->d_parent; |
260 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( | 233 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( |
@@ -301,14 +274,15 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
301 | rc = -ENOMEM; | 274 | rc = -ENOMEM; |
302 | goto out; | 275 | goto out; |
303 | } | 276 | } |
304 | rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | 277 | rc = ecryptfs_get_lower_file(ecryptfs_dentry); |
305 | if (rc) { | 278 | if (rc) { |
306 | printk(KERN_ERR "%s: Error attempting to initialize " | 279 | printk(KERN_ERR "%s: Error attempting to initialize " |
307 | "the persistent file for the dentry with name " | 280 | "the lower file for the dentry with name " |
308 | "[%s]; rc = [%d]\n", __func__, | 281 | "[%s]; rc = [%d]\n", __func__, |
309 | ecryptfs_dentry->d_name.name, rc); | 282 | ecryptfs_dentry->d_name.name, rc); |
310 | goto out_free_kmem; | 283 | goto out_free_kmem; |
311 | } | 284 | } |
285 | put_lower = 1; | ||
312 | crypt_stat = &ecryptfs_inode_to_private( | 286 | crypt_stat = &ecryptfs_inode_to_private( |
313 | ecryptfs_dentry->d_inode)->crypt_stat; | 287 | ecryptfs_dentry->d_inode)->crypt_stat; |
314 | /* TODO: lock for crypt_stat comparison */ | 288 | /* TODO: lock for crypt_stat comparison */ |
@@ -326,18 +300,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, | |||
326 | } | 300 | } |
327 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; | 301 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; |
328 | } | 302 | } |
329 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 303 | ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); |
330 | ecryptfs_dentry->d_sb)->mount_crypt_stat; | ||
331 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | ||
332 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | ||
333 | file_size = (crypt_stat->metadata_size | ||
334 | + i_size_read(lower_dentry->d_inode)); | ||
335 | else | ||
336 | file_size = i_size_read(lower_dentry->d_inode); | ||
337 | } else { | ||
338 | file_size = get_unaligned_be64(page_virt); | ||
339 | } | ||
340 | i_size_write(ecryptfs_dentry->d_inode, (loff_t)file_size); | ||
341 | out_free_kmem: | 304 | out_free_kmem: |
342 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); | 305 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
343 | goto out; | 306 | goto out; |
@@ -346,6 +309,8 @@ out_put: | |||
346 | mntput(lower_mnt); | 309 | mntput(lower_mnt); |
347 | d_drop(ecryptfs_dentry); | 310 | d_drop(ecryptfs_dentry); |
348 | out: | 311 | out: |
312 | if (put_lower) | ||
313 | ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); | ||
349 | return rc; | 314 | return rc; |
350 | } | 315 | } |
351 | 316 | ||
@@ -562,8 +527,6 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
562 | dget(lower_dentry); | 527 | dget(lower_dentry); |
563 | rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); | 528 | rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); |
564 | dput(lower_dentry); | 529 | dput(lower_dentry); |
565 | if (!rc) | ||
566 | d_delete(lower_dentry); | ||
567 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); | 530 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
568 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; | 531 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; |
569 | unlock_dir(lower_dir_dentry); | 532 | unlock_dir(lower_dir_dentry); |
@@ -634,8 +597,8 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
634 | fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); | 597 | fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); |
635 | out_lock: | 598 | out_lock: |
636 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); | 599 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
637 | dput(lower_new_dentry->d_parent); | 600 | dput(lower_new_dir_dentry); |
638 | dput(lower_old_dentry->d_parent); | 601 | dput(lower_old_dir_dentry); |
639 | dput(lower_new_dentry); | 602 | dput(lower_new_dentry); |
640 | dput(lower_old_dentry); | 603 | dput(lower_old_dentry); |
641 | return rc; | 604 | return rc; |
@@ -783,8 +746,11 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
783 | 746 | ||
784 | if (unlikely((ia->ia_size == i_size))) { | 747 | if (unlikely((ia->ia_size == i_size))) { |
785 | lower_ia->ia_valid &= ~ATTR_SIZE; | 748 | lower_ia->ia_valid &= ~ATTR_SIZE; |
786 | goto out; | 749 | return 0; |
787 | } | 750 | } |
751 | rc = ecryptfs_get_lower_file(dentry); | ||
752 | if (rc) | ||
753 | return rc; | ||
788 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; | 754 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
789 | /* Switch on growing or shrinking file */ | 755 | /* Switch on growing or shrinking file */ |
790 | if (ia->ia_size > i_size) { | 756 | if (ia->ia_size > i_size) { |
@@ -862,6 +828,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, | |||
862 | lower_ia->ia_valid &= ~ATTR_SIZE; | 828 | lower_ia->ia_valid &= ~ATTR_SIZE; |
863 | } | 829 | } |
864 | out: | 830 | out: |
831 | ecryptfs_put_lower_file(inode); | ||
865 | return rc; | 832 | return rc; |
866 | } | 833 | } |
867 | 834 | ||
@@ -937,7 +904,13 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
937 | 904 | ||
938 | mount_crypt_stat = &ecryptfs_superblock_to_private( | 905 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
939 | dentry->d_sb)->mount_crypt_stat; | 906 | dentry->d_sb)->mount_crypt_stat; |
907 | rc = ecryptfs_get_lower_file(dentry); | ||
908 | if (rc) { | ||
909 | mutex_unlock(&crypt_stat->cs_mutex); | ||
910 | goto out; | ||
911 | } | ||
940 | rc = ecryptfs_read_metadata(dentry); | 912 | rc = ecryptfs_read_metadata(dentry); |
913 | ecryptfs_put_lower_file(inode); | ||
941 | if (rc) { | 914 | if (rc) { |
942 | if (!(mount_crypt_stat->flags | 915 | if (!(mount_crypt_stat->flags |
943 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | 916 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { |
@@ -951,10 +924,17 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
951 | goto out; | 924 | goto out; |
952 | } | 925 | } |
953 | rc = 0; | 926 | rc = 0; |
954 | crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | 927 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED |
928 | | ECRYPTFS_ENCRYPTED); | ||
955 | } | 929 | } |
956 | } | 930 | } |
957 | mutex_unlock(&crypt_stat->cs_mutex); | 931 | mutex_unlock(&crypt_stat->cs_mutex); |
932 | if (S_ISREG(inode->i_mode)) { | ||
933 | rc = filemap_write_and_wait(inode->i_mapping); | ||
934 | if (rc) | ||
935 | goto out; | ||
936 | fsstack_copy_attr_all(inode, lower_inode); | ||
937 | } | ||
958 | memcpy(&lower_ia, ia, sizeof(lower_ia)); | 938 | memcpy(&lower_ia, ia, sizeof(lower_ia)); |
959 | if (ia->ia_valid & ATTR_FILE) | 939 | if (ia->ia_valid & ATTR_FILE) |
960 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); | 940 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); |