diff options
Diffstat (limited to 'fs/ecryptfs/mmap.c')
-rw-r--r-- | fs/ecryptfs/mmap.c | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index cc64fca89f8d..6a44148c5fb9 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -62,6 +62,18 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) | |||
62 | { | 62 | { |
63 | int rc; | 63 | int rc; |
64 | 64 | ||
65 | /* | ||
66 | * Refuse to write the page out if we are called from reclaim context | ||
67 | * since our writepage() path may potentially allocate memory when | ||
68 | * calling into the lower fs vfs_write() which may in turn invoke | ||
69 | * us again. | ||
70 | */ | ||
71 | if (current->flags & PF_MEMALLOC) { | ||
72 | redirty_page_for_writepage(wbc, page); | ||
73 | rc = 0; | ||
74 | goto out; | ||
75 | } | ||
76 | |||
65 | rc = ecryptfs_encrypt_page(page); | 77 | rc = ecryptfs_encrypt_page(page); |
66 | if (rc) { | 78 | if (rc) { |
67 | ecryptfs_printk(KERN_WARNING, "Error encrypting " | 79 | ecryptfs_printk(KERN_WARNING, "Error encrypting " |
@@ -70,8 +82,8 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) | |||
70 | goto out; | 82 | goto out; |
71 | } | 83 | } |
72 | SetPageUptodate(page); | 84 | SetPageUptodate(page); |
73 | unlock_page(page); | ||
74 | out: | 85 | out: |
86 | unlock_page(page); | ||
75 | return rc; | 87 | return rc; |
76 | } | 88 | } |
77 | 89 | ||
@@ -193,11 +205,7 @@ static int ecryptfs_readpage(struct file *file, struct page *page) | |||
193 | &ecryptfs_inode_to_private(page->mapping->host)->crypt_stat; | 205 | &ecryptfs_inode_to_private(page->mapping->host)->crypt_stat; |
194 | int rc = 0; | 206 | int rc = 0; |
195 | 207 | ||
196 | if (!crypt_stat | 208 | if (!crypt_stat || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
197 | || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED) | ||
198 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { | ||
199 | ecryptfs_printk(KERN_DEBUG, | ||
200 | "Passing through unencrypted page\n"); | ||
201 | rc = ecryptfs_read_lower_page_segment(page, page->index, 0, | 209 | rc = ecryptfs_read_lower_page_segment(page, page->index, 0, |
202 | PAGE_CACHE_SIZE, | 210 | PAGE_CACHE_SIZE, |
203 | page->mapping->host); | 211 | page->mapping->host); |
@@ -295,8 +303,7 @@ static int ecryptfs_write_begin(struct file *file, | |||
295 | struct ecryptfs_crypt_stat *crypt_stat = | 303 | struct ecryptfs_crypt_stat *crypt_stat = |
296 | &ecryptfs_inode_to_private(mapping->host)->crypt_stat; | 304 | &ecryptfs_inode_to_private(mapping->host)->crypt_stat; |
297 | 305 | ||
298 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED) | 306 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
299 | || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { | ||
300 | rc = ecryptfs_read_lower_page_segment( | 307 | rc = ecryptfs_read_lower_page_segment( |
301 | page, index, 0, PAGE_CACHE_SIZE, mapping->host); | 308 | page, index, 0, PAGE_CACHE_SIZE, mapping->host); |
302 | if (rc) { | 309 | if (rc) { |
@@ -374,6 +381,11 @@ static int ecryptfs_write_begin(struct file *file, | |||
374 | && (pos != 0)) | 381 | && (pos != 0)) |
375 | zero_user(page, 0, PAGE_CACHE_SIZE); | 382 | zero_user(page, 0, PAGE_CACHE_SIZE); |
376 | out: | 383 | out: |
384 | if (unlikely(rc)) { | ||
385 | unlock_page(page); | ||
386 | page_cache_release(page); | ||
387 | *pagep = NULL; | ||
388 | } | ||
377 | return rc; | 389 | return rc; |
378 | } | 390 | } |
379 | 391 | ||
@@ -486,13 +498,8 @@ static int ecryptfs_write_end(struct file *file, | |||
486 | struct ecryptfs_crypt_stat *crypt_stat = | 498 | struct ecryptfs_crypt_stat *crypt_stat = |
487 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 499 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
488 | int rc; | 500 | int rc; |
501 | int need_unlock_page = 1; | ||
489 | 502 | ||
490 | if (crypt_stat->flags & ECRYPTFS_NEW_FILE) { | ||
491 | ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " | ||
492 | "crypt_stat at memory location [%p]\n", crypt_stat); | ||
493 | crypt_stat->flags &= ~(ECRYPTFS_NEW_FILE); | ||
494 | } else | ||
495 | ecryptfs_printk(KERN_DEBUG, "Not a new file\n"); | ||
496 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" | 503 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" |
497 | "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); | 504 | "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); |
498 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { | 505 | if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { |
@@ -512,26 +519,26 @@ static int ecryptfs_write_end(struct file *file, | |||
512 | "zeros in page with index = [0x%.16lx]\n", index); | 519 | "zeros in page with index = [0x%.16lx]\n", index); |
513 | goto out; | 520 | goto out; |
514 | } | 521 | } |
515 | rc = ecryptfs_encrypt_page(page); | 522 | set_page_dirty(page); |
516 | if (rc) { | 523 | unlock_page(page); |
517 | ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " | 524 | need_unlock_page = 0; |
518 | "index [0x%.16lx])\n", index); | ||
519 | goto out; | ||
520 | } | ||
521 | if (pos + copied > i_size_read(ecryptfs_inode)) { | 525 | if (pos + copied > i_size_read(ecryptfs_inode)) { |
522 | i_size_write(ecryptfs_inode, pos + copied); | 526 | i_size_write(ecryptfs_inode, pos + copied); |
523 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " | 527 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " |
524 | "[0x%.16llx]\n", | 528 | "[0x%.16llx]\n", |
525 | (unsigned long long)i_size_read(ecryptfs_inode)); | 529 | (unsigned long long)i_size_read(ecryptfs_inode)); |
530 | balance_dirty_pages_ratelimited(mapping); | ||
531 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | ||
532 | if (rc) { | ||
533 | printk(KERN_ERR "Error writing inode size to metadata; " | ||
534 | "rc = [%d]\n", rc); | ||
535 | goto out; | ||
536 | } | ||
526 | } | 537 | } |
527 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | 538 | rc = copied; |
528 | if (rc) | ||
529 | printk(KERN_ERR "Error writing inode size to metadata; " | ||
530 | "rc = [%d]\n", rc); | ||
531 | else | ||
532 | rc = copied; | ||
533 | out: | 539 | out: |
534 | unlock_page(page); | 540 | if (need_unlock_page) |
541 | unlock_page(page); | ||
535 | page_cache_release(page); | 542 | page_cache_release(page); |
536 | return rc; | 543 | return rc; |
537 | } | 544 | } |