diff options
author | Thieu Le <thieule@chromium.org> | 2011-03-08 19:26:03 -0500 |
---|---|---|
committer | Tyler Hicks <tyhicks@linux.vnet.ibm.com> | 2011-03-28 02:47:45 -0400 |
commit | 57db4e8d73ef2b5e94a3f412108dff2576670a8a (patch) | |
tree | ab6eae8e879cfa41cdb3309d8e6a52de14746ca4 /fs/ecryptfs/mmap.c | |
parent | fed8859b3ab94274c986cbdf7d27130e0545f02c (diff) |
ecryptfs: modify write path to encrypt page in writepage
Change the write path to encrypt the data only when the page is written to
disk in ecryptfs_writepage. Previously, ecryptfs encrypts the page in
ecryptfs_write_end which means that if there are multiple write requests to
the same page, ecryptfs ends up re-encrypting that page over and over again.
This patch minimizes the number of encryptions needed.
Signed-off-by: Thieu Le <thieule@chromium.org>
[tyhicks: Changed NULL .drop_inode sop pointer to generic_drop_inode]
Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
Diffstat (limited to 'fs/ecryptfs/mmap.c')
-rw-r--r-- | fs/ecryptfs/mmap.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 519af27db059..5e150131eb9d 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 | ||
@@ -481,6 +493,7 @@ static int ecryptfs_write_end(struct file *file, | |||
481 | struct ecryptfs_crypt_stat *crypt_stat = | 493 | struct ecryptfs_crypt_stat *crypt_stat = |
482 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 494 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
483 | int rc; | 495 | int rc; |
496 | int need_unlock_page = 1; | ||
484 | 497 | ||
485 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" | 498 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" |
486 | "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); | 499 | "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); |
@@ -501,26 +514,26 @@ static int ecryptfs_write_end(struct file *file, | |||
501 | "zeros in page with index = [0x%.16lx]\n", index); | 514 | "zeros in page with index = [0x%.16lx]\n", index); |
502 | goto out; | 515 | goto out; |
503 | } | 516 | } |
504 | rc = ecryptfs_encrypt_page(page); | 517 | set_page_dirty(page); |
505 | if (rc) { | 518 | unlock_page(page); |
506 | ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " | 519 | need_unlock_page = 0; |
507 | "index [0x%.16lx])\n", index); | ||
508 | goto out; | ||
509 | } | ||
510 | if (pos + copied > i_size_read(ecryptfs_inode)) { | 520 | if (pos + copied > i_size_read(ecryptfs_inode)) { |
511 | i_size_write(ecryptfs_inode, pos + copied); | 521 | i_size_write(ecryptfs_inode, pos + copied); |
512 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " | 522 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " |
513 | "[0x%.16llx]\n", | 523 | "[0x%.16llx]\n", |
514 | (unsigned long long)i_size_read(ecryptfs_inode)); | 524 | (unsigned long long)i_size_read(ecryptfs_inode)); |
525 | balance_dirty_pages_ratelimited(mapping); | ||
526 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | ||
527 | if (rc) { | ||
528 | printk(KERN_ERR "Error writing inode size to metadata; " | ||
529 | "rc = [%d]\n", rc); | ||
530 | goto out; | ||
531 | } | ||
515 | } | 532 | } |
516 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | 533 | rc = copied; |
517 | if (rc) | ||
518 | printk(KERN_ERR "Error writing inode size to metadata; " | ||
519 | "rc = [%d]\n", rc); | ||
520 | else | ||
521 | rc = copied; | ||
522 | out: | 534 | out: |
523 | unlock_page(page); | 535 | if (need_unlock_page) |
536 | unlock_page(page); | ||
524 | page_cache_release(page); | 537 | page_cache_release(page); |
525 | return rc; | 538 | return rc; |
526 | } | 539 | } |