aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@canonical.com>2012-07-03 19:50:57 -0400
committerTyler Hicks <tyhicks@canonical.com>2012-07-13 19:46:06 -0400
commit821f7494a77627fb1ab539591c57b22cdca702d6 (patch)
tree561ee1768e62c120766c40c0b8fc8aa30b4f4a95
parente3ccaa9761200952cc269b1f4b7d7bb77a5e071b (diff)
eCryptfs: Revert to a writethrough cache model
A change was made about a year ago to get eCryptfs to better utilize its page cache during writes. The idea was to do the page encryption operations during page writeback, rather than doing them when initially writing into the page cache, to reduce the number of page encryption operations during sequential writes. This meant that the encrypted page would only be written to the lower filesystem during page writeback, which was a change from how eCryptfs had previously wrote to the lower filesystem in ecryptfs_write_end(). The change caused a few eCryptfs-internal bugs that were shook out. Unfortunately, more grave side effects have been identified that will force changes outside of eCryptfs. Because the lower filesystem isn't consulted until page writeback, eCryptfs has no way to pass lower write errors (ENOSPC, mainly) back to userspace. Additionaly, it was reported that quotas could be bypassed because of the way eCryptfs may sometimes open the lower filesystem using a privileged kthread. It would be nice to resolve the latest issues, but it is best if the eCryptfs commits be reverted to the old behavior in the meantime. This reverts: 32001d6f "eCryptfs: Flush file in vma close" 5be79de2 "eCryptfs: Flush dirty pages in setattr" 57db4e8d "ecryptfs: modify write path to encrypt page in writepage" Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Tested-by: Colin King <colin.king@canonical.com> Cc: Colin King <colin.king@canonical.com> Cc: Thieu Le <thieule@google.com>
-rw-r--r--fs/ecryptfs/file.c33
-rw-r--r--fs/ecryptfs/inode.c6
-rw-r--r--fs/ecryptfs/mmap.c39
3 files changed, 15 insertions, 63 deletions
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index baf8b0550391..44ce5c6a541d 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -138,27 +138,6 @@ out:
138 return rc; 138 return rc;
139} 139}
140 140
141static void ecryptfs_vma_close(struct vm_area_struct *vma)
142{
143 filemap_write_and_wait(vma->vm_file->f_mapping);
144}
145
146static const struct vm_operations_struct ecryptfs_file_vm_ops = {
147 .close = ecryptfs_vma_close,
148 .fault = filemap_fault,
149};
150
151static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma)
152{
153 int rc;
154
155 rc = generic_file_mmap(file, vma);
156 if (!rc)
157 vma->vm_ops = &ecryptfs_file_vm_ops;
158
159 return rc;
160}
161
162struct kmem_cache *ecryptfs_file_info_cache; 141struct kmem_cache *ecryptfs_file_info_cache;
163 142
164static int read_or_initialize_metadata(struct dentry *dentry) 143static int read_or_initialize_metadata(struct dentry *dentry)
@@ -311,15 +290,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
311static int 290static int
312ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) 291ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
313{ 292{
314 int rc = 0; 293 return vfs_fsync(ecryptfs_file_to_lower(file), datasync);
315
316 rc = generic_file_fsync(file, start, end, datasync);
317 if (rc)
318 goto out;
319 rc = vfs_fsync_range(ecryptfs_file_to_lower(file), start, end,
320 datasync);
321out:
322 return rc;
323} 294}
324 295
325static int ecryptfs_fasync(int fd, struct file *file, int flag) 296static int ecryptfs_fasync(int fd, struct file *file, int flag)
@@ -388,7 +359,7 @@ const struct file_operations ecryptfs_main_fops = {
388#ifdef CONFIG_COMPAT 359#ifdef CONFIG_COMPAT
389 .compat_ioctl = ecryptfs_compat_ioctl, 360 .compat_ioctl = ecryptfs_compat_ioctl,
390#endif 361#endif
391 .mmap = ecryptfs_file_mmap, 362 .mmap = generic_file_mmap,
392 .open = ecryptfs_open, 363 .open = ecryptfs_open,
393 .flush = ecryptfs_flush, 364 .flush = ecryptfs_flush,
394 .release = ecryptfs_release, 365 .release = ecryptfs_release,
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 2d4143f8f5c9..769fb8524aeb 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -981,12 +981,6 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
981 goto out; 981 goto out;
982 } 982 }
983 983
984 if (S_ISREG(inode->i_mode)) {
985 rc = filemap_write_and_wait(inode->i_mapping);
986 if (rc)
987 goto out;
988 fsstack_copy_attr_all(inode, lower_inode);
989 }
990 memcpy(&lower_ia, ia, sizeof(lower_ia)); 984 memcpy(&lower_ia, ia, sizeof(lower_ia));
991 if (ia->ia_valid & ATTR_FILE) 985 if (ia->ia_valid & ATTR_FILE)
992 lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); 986 lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file);
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index a46b3a8fee1e..bd1d57f98f74 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -66,18 +66,6 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
66{ 66{
67 int rc; 67 int rc;
68 68
69 /*
70 * Refuse to write the page out if we are called from reclaim context
71 * since our writepage() path may potentially allocate memory when
72 * calling into the lower fs vfs_write() which may in turn invoke
73 * us again.
74 */
75 if (current->flags & PF_MEMALLOC) {
76 redirty_page_for_writepage(wbc, page);
77 rc = 0;
78 goto out;
79 }
80
81 rc = ecryptfs_encrypt_page(page); 69 rc = ecryptfs_encrypt_page(page);
82 if (rc) { 70 if (rc) {
83 ecryptfs_printk(KERN_WARNING, "Error encrypting " 71 ecryptfs_printk(KERN_WARNING, "Error encrypting "
@@ -498,7 +486,6 @@ static int ecryptfs_write_end(struct file *file,
498 struct ecryptfs_crypt_stat *crypt_stat = 486 struct ecryptfs_crypt_stat *crypt_stat =
499 &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; 487 &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
500 int rc; 488 int rc;
501 int need_unlock_page = 1;
502 489
503 ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" 490 ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
504 "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); 491 "(page w/ index = [0x%.16lx], to = [%d])\n", index, to);
@@ -519,26 +506,26 @@ static int ecryptfs_write_end(struct file *file,
519 "zeros in page with index = [0x%.16lx]\n", index); 506 "zeros in page with index = [0x%.16lx]\n", index);
520 goto out; 507 goto out;
521 } 508 }
522 set_page_dirty(page); 509 rc = ecryptfs_encrypt_page(page);
523 unlock_page(page); 510 if (rc) {
524 need_unlock_page = 0; 511 ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
512 "index [0x%.16lx])\n", index);
513 goto out;
514 }
525 if (pos + copied > i_size_read(ecryptfs_inode)) { 515 if (pos + copied > i_size_read(ecryptfs_inode)) {
526 i_size_write(ecryptfs_inode, pos + copied); 516 i_size_write(ecryptfs_inode, pos + copied);
527 ecryptfs_printk(KERN_DEBUG, "Expanded file size to " 517 ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
528 "[0x%.16llx]\n", 518 "[0x%.16llx]\n",
529 (unsigned long long)i_size_read(ecryptfs_inode)); 519 (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 }
537 } 520 }
538 rc = copied; 521 rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
522 if (rc)
523 printk(KERN_ERR "Error writing inode size to metadata; "
524 "rc = [%d]\n", rc);
525 else
526 rc = copied;
539out: 527out:
540 if (need_unlock_page) 528 unlock_page(page);
541 unlock_page(page);
542 page_cache_release(page); 529 page_cache_release(page);
543 return rc; 530 return rc;
544} 531}