diff options
| -rw-r--r-- | fs/ecryptfs/crypto.c | 12 | ||||
| -rw-r--r-- | fs/ecryptfs/ecryptfs_kernel.h | 2 | ||||
| -rw-r--r-- | fs/ecryptfs/mmap.c | 28 | ||||
| -rw-r--r-- | fs/ecryptfs/read_write.c | 30 |
4 files changed, 39 insertions, 33 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index e890d596da7e..1ae90ef2c74d 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
| @@ -605,14 +605,14 @@ int ecryptfs_decrypt_page(struct page *page) | |||
| 605 | printk(KERN_ERR "%s: Error attempting to copy " | 605 | printk(KERN_ERR "%s: Error attempting to copy " |
| 606 | "page at index [%ld]\n", __FUNCTION__, | 606 | "page at index [%ld]\n", __FUNCTION__, |
| 607 | page->index); | 607 | page->index); |
| 608 | goto out_clear_uptodate; | 608 | goto out; |
| 609 | } | 609 | } |
| 610 | enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER); | 610 | enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER); |
| 611 | if (!enc_extent_virt) { | 611 | if (!enc_extent_virt) { |
| 612 | rc = -ENOMEM; | 612 | rc = -ENOMEM; |
| 613 | ecryptfs_printk(KERN_ERR, "Error allocating memory for " | 613 | ecryptfs_printk(KERN_ERR, "Error allocating memory for " |
| 614 | "encrypted extent\n"); | 614 | "encrypted extent\n"); |
| 615 | goto out_clear_uptodate; | 615 | goto out; |
| 616 | } | 616 | } |
| 617 | enc_extent_page = virt_to_page(enc_extent_virt); | 617 | enc_extent_page = virt_to_page(enc_extent_virt); |
| 618 | for (extent_offset = 0; | 618 | for (extent_offset = 0; |
| @@ -631,21 +631,17 @@ int ecryptfs_decrypt_page(struct page *page) | |||
| 631 | ecryptfs_printk(KERN_ERR, "Error attempting " | 631 | ecryptfs_printk(KERN_ERR, "Error attempting " |
| 632 | "to read lower page; rc = [%d]" | 632 | "to read lower page; rc = [%d]" |
| 633 | "\n", rc); | 633 | "\n", rc); |
| 634 | goto out_clear_uptodate; | 634 | goto out; |
| 635 | } | 635 | } |
| 636 | rc = ecryptfs_decrypt_extent(page, crypt_stat, enc_extent_page, | 636 | rc = ecryptfs_decrypt_extent(page, crypt_stat, enc_extent_page, |
| 637 | extent_offset); | 637 | extent_offset); |
| 638 | if (rc) { | 638 | if (rc) { |
| 639 | printk(KERN_ERR "%s: Error encrypting extent; " | 639 | printk(KERN_ERR "%s: Error encrypting extent; " |
| 640 | "rc = [%d]\n", __FUNCTION__, rc); | 640 | "rc = [%d]\n", __FUNCTION__, rc); |
| 641 | goto out_clear_uptodate; | 641 | goto out; |
| 642 | } | 642 | } |
| 643 | extent_offset++; | 643 | extent_offset++; |
| 644 | } | 644 | } |
| 645 | SetPageUptodate(page); | ||
| 646 | goto out; | ||
| 647 | out_clear_uptodate: | ||
| 648 | ClearPageUptodate(page); | ||
| 649 | out: | 645 | out: |
| 650 | kfree(enc_extent_virt); | 646 | kfree(enc_extent_virt); |
| 651 | return rc; | 647 | return rc; |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index bb92b74d66e9..ce7a5d4aec36 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
| @@ -648,6 +648,6 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
| 648 | struct inode *ecryptfs_inode); | 648 | struct inode *ecryptfs_inode); |
| 649 | int ecryptfs_read(char *data, loff_t offset, size_t size, | 649 | int ecryptfs_read(char *data, loff_t offset, size_t size, |
| 650 | struct file *ecryptfs_file); | 650 | struct file *ecryptfs_file); |
| 651 | struct page *ecryptfs_get1page(struct file *file, loff_t index); | 651 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index); |
| 652 | 652 | ||
| 653 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 653 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 4eb09c1753c6..16a7a555f392 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
| @@ -37,23 +37,27 @@ | |||
| 37 | struct kmem_cache *ecryptfs_lower_page_cache; | 37 | struct kmem_cache *ecryptfs_lower_page_cache; |
| 38 | 38 | ||
| 39 | /** | 39 | /** |
| 40 | * ecryptfs_get1page | 40 | * ecryptfs_get_locked_page |
| 41 | * | 41 | * |
| 42 | * Get one page from cache or lower f/s, return error otherwise. | 42 | * Get one page from cache or lower f/s, return error otherwise. |
| 43 | * | 43 | * |
| 44 | * Returns unlocked and up-to-date page (if ok), with increased | 44 | * Returns locked and up-to-date page (if ok), with increased |
| 45 | * refcnt. | 45 | * refcnt. |
| 46 | */ | 46 | */ |
| 47 | struct page *ecryptfs_get1page(struct file *file, loff_t index) | 47 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index) |
| 48 | { | 48 | { |
| 49 | struct dentry *dentry; | 49 | struct dentry *dentry; |
| 50 | struct inode *inode; | 50 | struct inode *inode; |
| 51 | struct address_space *mapping; | 51 | struct address_space *mapping; |
| 52 | struct page *page; | ||
| 52 | 53 | ||
| 53 | dentry = file->f_path.dentry; | 54 | dentry = file->f_path.dentry; |
| 54 | inode = dentry->d_inode; | 55 | inode = dentry->d_inode; |
| 55 | mapping = inode->i_mapping; | 56 | mapping = inode->i_mapping; |
| 56 | return read_mapping_page(mapping, index, (void *)file); | 57 | page = read_mapping_page(mapping, index, (void *)file); |
| 58 | if (!IS_ERR(page)) | ||
| 59 | lock_page(page); | ||
| 60 | return page; | ||
| 57 | } | 61 | } |
| 58 | 62 | ||
| 59 | /** | 63 | /** |
| @@ -146,12 +150,10 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
| 146 | kunmap_atomic(page_virt, KM_USER0); | 150 | kunmap_atomic(page_virt, KM_USER0); |
| 147 | flush_dcache_page(page); | 151 | flush_dcache_page(page); |
| 148 | if (rc) { | 152 | if (rc) { |
| 149 | ClearPageUptodate(page); | ||
| 150 | printk(KERN_ERR "%s: Error reading xattr " | 153 | printk(KERN_ERR "%s: Error reading xattr " |
| 151 | "region; rc = [%d]\n", __FUNCTION__, rc); | 154 | "region; rc = [%d]\n", __FUNCTION__, rc); |
| 152 | goto out; | 155 | goto out; |
| 153 | } | 156 | } |
| 154 | SetPageUptodate(page); | ||
| 155 | } else { | 157 | } else { |
| 156 | /* This is an encrypted data extent */ | 158 | /* This is an encrypted data extent */ |
| 157 | loff_t lower_offset = | 159 | loff_t lower_offset = |
| @@ -232,6 +234,10 @@ static int ecryptfs_readpage(struct file *file, struct page *page) | |||
| 232 | } | 234 | } |
| 233 | } | 235 | } |
| 234 | out: | 236 | out: |
| 237 | if (rc) | ||
| 238 | ClearPageUptodate(page); | ||
| 239 | else | ||
| 240 | SetPageUptodate(page); | ||
| 235 | ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n", | 241 | ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n", |
| 236 | page->index); | 242 | page->index); |
| 237 | unlock_page(page); | 243 | unlock_page(page); |
| @@ -265,10 +271,18 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page, | |||
| 265 | if (from == 0 && to == PAGE_CACHE_SIZE) | 271 | if (from == 0 && to == PAGE_CACHE_SIZE) |
| 266 | goto out; /* If we are writing a full page, it will be | 272 | goto out; /* If we are writing a full page, it will be |
| 267 | up to date. */ | 273 | up to date. */ |
| 268 | if (!PageUptodate(page)) | 274 | if (!PageUptodate(page)) { |
| 269 | rc = ecryptfs_read_lower_page_segment(page, page->index, 0, | 275 | rc = ecryptfs_read_lower_page_segment(page, page->index, 0, |
| 270 | PAGE_CACHE_SIZE, | 276 | PAGE_CACHE_SIZE, |
| 271 | page->mapping->host); | 277 | page->mapping->host); |
| 278 | if (rc) { | ||
| 279 | printk(KERN_ERR "%s: Error attemping to read lower " | ||
| 280 | "page segment; rc = [%d]\n", __FUNCTION__, rc); | ||
| 281 | ClearPageUptodate(page); | ||
| 282 | goto out; | ||
| 283 | } else | ||
| 284 | SetPageUptodate(page); | ||
| 285 | } | ||
| 272 | if (page->index != 0) { | 286 | if (page->index != 0) { |
| 273 | loff_t end_of_prev_pg_pos = | 287 | loff_t end_of_prev_pg_pos = |
| 274 | (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1); | 288 | (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1); |
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 272eaeb9a738..2150edf9a58e 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c | |||
| @@ -142,8 +142,8 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
| 142 | if (num_bytes > total_remaining_zeros) | 142 | if (num_bytes > total_remaining_zeros) |
| 143 | num_bytes = total_remaining_zeros; | 143 | num_bytes = total_remaining_zeros; |
| 144 | } | 144 | } |
| 145 | ecryptfs_page = ecryptfs_get1page(ecryptfs_file, | 145 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file, |
| 146 | ecryptfs_page_idx); | 146 | ecryptfs_page_idx); |
| 147 | if (IS_ERR(ecryptfs_page)) { | 147 | if (IS_ERR(ecryptfs_page)) { |
| 148 | rc = PTR_ERR(ecryptfs_page); | 148 | rc = PTR_ERR(ecryptfs_page); |
| 149 | printk(KERN_ERR "%s: Error getting page at " | 149 | printk(KERN_ERR "%s: Error getting page at " |
| @@ -161,6 +161,7 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
| 161 | printk(KERN_ERR "%s: Error decrypting " | 161 | printk(KERN_ERR "%s: Error decrypting " |
| 162 | "page; rc = [%d]\n", | 162 | "page; rc = [%d]\n", |
| 163 | __FUNCTION__, rc); | 163 | __FUNCTION__, rc); |
| 164 | ClearPageUptodate(ecryptfs_page); | ||
| 164 | page_cache_release(ecryptfs_page); | 165 | page_cache_release(ecryptfs_page); |
| 165 | goto out; | 166 | goto out; |
| 166 | } | 167 | } |
| @@ -180,14 +181,15 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, | |||
| 180 | } | 181 | } |
| 181 | kunmap_atomic(ecryptfs_page_virt, KM_USER0); | 182 | kunmap_atomic(ecryptfs_page_virt, KM_USER0); |
| 182 | flush_dcache_page(ecryptfs_page); | 183 | flush_dcache_page(ecryptfs_page); |
| 184 | SetPageUptodate(ecryptfs_page); | ||
| 185 | unlock_page(ecryptfs_page); | ||
| 183 | rc = ecryptfs_encrypt_page(ecryptfs_page); | 186 | rc = ecryptfs_encrypt_page(ecryptfs_page); |
| 187 | page_cache_release(ecryptfs_page); | ||
| 184 | if (rc) { | 188 | if (rc) { |
| 185 | printk(KERN_ERR "%s: Error encrypting " | 189 | printk(KERN_ERR "%s: Error encrypting " |
| 186 | "page; rc = [%d]\n", __FUNCTION__, rc); | 190 | "page; rc = [%d]\n", __FUNCTION__, rc); |
| 187 | page_cache_release(ecryptfs_page); | ||
| 188 | goto out; | 191 | goto out; |
| 189 | } | 192 | } |
| 190 | page_cache_release(ecryptfs_page); | ||
| 191 | pos += num_bytes; | 193 | pos += num_bytes; |
| 192 | } | 194 | } |
| 193 | if ((offset + size) > ecryptfs_file_size) { | 195 | if ((offset + size) > ecryptfs_file_size) { |
| @@ -225,7 +227,6 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size, | |||
| 225 | ecryptfs_inode_to_private(ecryptfs_inode); | 227 | ecryptfs_inode_to_private(ecryptfs_inode); |
| 226 | ssize_t octets_read; | 228 | ssize_t octets_read; |
| 227 | mm_segment_t fs_save; | 229 | mm_segment_t fs_save; |
| 228 | size_t i; | ||
| 229 | int rc = 0; | 230 | int rc = 0; |
| 230 | 231 | ||
| 231 | mutex_lock(&inode_info->lower_file_mutex); | 232 | mutex_lock(&inode_info->lower_file_mutex); |
| @@ -242,16 +243,6 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size, | |||
| 242 | rc = -EINVAL; | 243 | rc = -EINVAL; |
| 243 | } | 244 | } |
| 244 | mutex_unlock(&inode_info->lower_file_mutex); | 245 | mutex_unlock(&inode_info->lower_file_mutex); |
| 245 | for (i = 0; i < size; i += PAGE_CACHE_SIZE) { | ||
| 246 | struct page *data_page; | ||
| 247 | |||
| 248 | data_page = virt_to_page(data + i); | ||
| 249 | flush_dcache_page(data_page); | ||
| 250 | if (rc) | ||
| 251 | ClearPageUptodate(data_page); | ||
| 252 | else | ||
| 253 | SetPageUptodate(data_page); | ||
| 254 | } | ||
| 255 | return rc; | 246 | return rc; |
| 256 | } | 247 | } |
| 257 | 248 | ||
| @@ -283,6 +274,7 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
| 283 | virt = kmap(page_for_ecryptfs); | 274 | virt = kmap(page_for_ecryptfs); |
| 284 | rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode); | 275 | rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode); |
| 285 | kunmap(page_for_ecryptfs); | 276 | kunmap(page_for_ecryptfs); |
| 277 | flush_dcache_page(page_for_ecryptfs); | ||
| 286 | return rc; | 278 | return rc; |
| 287 | } | 279 | } |
| 288 | 280 | ||
| @@ -331,8 +323,8 @@ int ecryptfs_read(char *data, loff_t offset, size_t size, | |||
| 331 | 323 | ||
| 332 | if (num_bytes > total_remaining_bytes) | 324 | if (num_bytes > total_remaining_bytes) |
| 333 | num_bytes = total_remaining_bytes; | 325 | num_bytes = total_remaining_bytes; |
| 334 | ecryptfs_page = ecryptfs_get1page(ecryptfs_file, | 326 | ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file, |
| 335 | ecryptfs_page_idx); | 327 | ecryptfs_page_idx); |
| 336 | if (IS_ERR(ecryptfs_page)) { | 328 | if (IS_ERR(ecryptfs_page)) { |
| 337 | rc = PTR_ERR(ecryptfs_page); | 329 | rc = PTR_ERR(ecryptfs_page); |
| 338 | printk(KERN_ERR "%s: Error getting page at " | 330 | printk(KERN_ERR "%s: Error getting page at " |
| @@ -345,6 +337,7 @@ int ecryptfs_read(char *data, loff_t offset, size_t size, | |||
| 345 | if (rc) { | 337 | if (rc) { |
| 346 | printk(KERN_ERR "%s: Error decrypting " | 338 | printk(KERN_ERR "%s: Error decrypting " |
| 347 | "page; rc = [%d]\n", __FUNCTION__, rc); | 339 | "page; rc = [%d]\n", __FUNCTION__, rc); |
| 340 | ClearPageUptodate(ecryptfs_page); | ||
| 348 | page_cache_release(ecryptfs_page); | 341 | page_cache_release(ecryptfs_page); |
| 349 | goto out; | 342 | goto out; |
| 350 | } | 343 | } |
| @@ -353,6 +346,9 @@ int ecryptfs_read(char *data, loff_t offset, size_t size, | |||
| 353 | ((char *)ecryptfs_page_virt + start_offset_in_page), | 346 | ((char *)ecryptfs_page_virt + start_offset_in_page), |
| 354 | num_bytes); | 347 | num_bytes); |
| 355 | kunmap_atomic(ecryptfs_page_virt, KM_USER0); | 348 | kunmap_atomic(ecryptfs_page_virt, KM_USER0); |
| 349 | flush_dcache_page(ecryptfs_page); | ||
| 350 | SetPageUptodate(ecryptfs_page); | ||
| 351 | unlock_page(ecryptfs_page); | ||
| 356 | page_cache_release(ecryptfs_page); | 352 | page_cache_release(ecryptfs_page); |
| 357 | pos += num_bytes; | 353 | pos += num_bytes; |
| 358 | data_offset += num_bytes; | 354 | data_offset += num_bytes; |
