aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThieu Le <thieule@chromium.org>2011-03-08 19:26:03 -0500
committerTyler Hicks <tyhicks@linux.vnet.ibm.com>2011-03-28 02:47:45 -0400
commit57db4e8d73ef2b5e94a3f412108dff2576670a8a (patch)
treeab6eae8e879cfa41cdb3309d8e6a52de14746ca4
parentfed8859b3ab94274c986cbdf7d27130e0545f02c (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>
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h1
-rw-r--r--fs/ecryptfs/file.c9
-rw-r--r--fs/ecryptfs/main.c2
-rw-r--r--fs/ecryptfs/mmap.c41
-rw-r--r--fs/ecryptfs/read_write.c12
-rw-r--r--fs/ecryptfs/super.c3
6 files changed, 38 insertions, 30 deletions
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 427478e29760..3ef5b0030231 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -296,7 +296,6 @@ struct ecryptfs_inode_info {
296 struct inode vfs_inode; 296 struct inode vfs_inode;
297 struct inode *wii_inode; 297 struct inode *wii_inode;
298 struct file *lower_file; 298 struct file *lower_file;
299 struct mutex lower_file_mutex;
300 struct ecryptfs_crypt_stat crypt_stat; 299 struct ecryptfs_crypt_stat crypt_stat;
301}; 300};
302 301
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 7d1050e254f9..cedc913d11ba 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -273,7 +273,14 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
273static int 273static int
274ecryptfs_fsync(struct file *file, int datasync) 274ecryptfs_fsync(struct file *file, int datasync)
275{ 275{
276 return vfs_fsync(ecryptfs_file_to_lower(file), datasync); 276 int rc = 0;
277
278 rc = generic_file_fsync(file, datasync);
279 if (rc)
280 goto out;
281 rc = vfs_fsync(ecryptfs_file_to_lower(file), datasync);
282out:
283 return rc;
277} 284}
278 285
279static int ecryptfs_fasync(int fd, struct file *file, int flag) 286static int ecryptfs_fasync(int fd, struct file *file, int flag)
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 758323a0f09a..63e412cf0fa1 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -122,7 +122,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
122 ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); 122 ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
123 int rc = 0; 123 int rc = 0;
124 124
125 mutex_lock(&inode_info->lower_file_mutex);
126 if (!inode_info->lower_file) { 125 if (!inode_info->lower_file) {
127 struct dentry *lower_dentry; 126 struct dentry *lower_dentry;
128 struct vfsmount *lower_mnt = 127 struct vfsmount *lower_mnt =
@@ -138,7 +137,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
138 inode_info->lower_file = NULL; 137 inode_info->lower_file = NULL;
139 } 138 }
140 } 139 }
141 mutex_unlock(&inode_info->lower_file_mutex);
142 return rc; 140 return rc;
143} 141}
144 142
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);
74out: 85out:
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;
522out: 534out:
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}
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
index db184ef15d3d..85d430963116 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -44,15 +44,11 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
44 ssize_t rc; 44 ssize_t rc;
45 45
46 inode_info = ecryptfs_inode_to_private(ecryptfs_inode); 46 inode_info = ecryptfs_inode_to_private(ecryptfs_inode);
47 mutex_lock(&inode_info->lower_file_mutex);
48 BUG_ON(!inode_info->lower_file); 47 BUG_ON(!inode_info->lower_file);
49 inode_info->lower_file->f_pos = offset;
50 fs_save = get_fs(); 48 fs_save = get_fs();
51 set_fs(get_ds()); 49 set_fs(get_ds());
52 rc = vfs_write(inode_info->lower_file, data, size, 50 rc = vfs_write(inode_info->lower_file, data, size, &offset);
53 &inode_info->lower_file->f_pos);
54 set_fs(fs_save); 51 set_fs(fs_save);
55 mutex_unlock(&inode_info->lower_file_mutex);
56 mark_inode_dirty_sync(ecryptfs_inode); 52 mark_inode_dirty_sync(ecryptfs_inode);
57 return rc; 53 return rc;
58} 54}
@@ -234,15 +230,11 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
234 mm_segment_t fs_save; 230 mm_segment_t fs_save;
235 ssize_t rc; 231 ssize_t rc;
236 232
237 mutex_lock(&inode_info->lower_file_mutex);
238 BUG_ON(!inode_info->lower_file); 233 BUG_ON(!inode_info->lower_file);
239 inode_info->lower_file->f_pos = offset;
240 fs_save = get_fs(); 234 fs_save = get_fs();
241 set_fs(get_ds()); 235 set_fs(get_ds());
242 rc = vfs_read(inode_info->lower_file, data, size, 236 rc = vfs_read(inode_info->lower_file, data, size, &offset);
243 &inode_info->lower_file->f_pos);
244 set_fs(fs_save); 237 set_fs(fs_save);
245 mutex_unlock(&inode_info->lower_file_mutex);
246 return rc; 238 return rc;
247} 239}
248 240
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 3042fe123a34..bacc882e1ae4 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -55,7 +55,6 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb)
55 if (unlikely(!inode_info)) 55 if (unlikely(!inode_info))
56 goto out; 56 goto out;
57 ecryptfs_init_crypt_stat(&inode_info->crypt_stat); 57 ecryptfs_init_crypt_stat(&inode_info->crypt_stat);
58 mutex_init(&inode_info->lower_file_mutex);
59 inode_info->lower_file = NULL; 58 inode_info->lower_file = NULL;
60 inode = &inode_info->vfs_inode; 59 inode = &inode_info->vfs_inode;
61out: 60out:
@@ -198,7 +197,7 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
198const struct super_operations ecryptfs_sops = { 197const struct super_operations ecryptfs_sops = {
199 .alloc_inode = ecryptfs_alloc_inode, 198 .alloc_inode = ecryptfs_alloc_inode,
200 .destroy_inode = ecryptfs_destroy_inode, 199 .destroy_inode = ecryptfs_destroy_inode,
201 .drop_inode = generic_delete_inode, 200 .drop_inode = generic_drop_inode,
202 .statfs = ecryptfs_statfs, 201 .statfs = ecryptfs_statfs,
203 .remount_fs = NULL, 202 .remount_fs = NULL,
204 .evict_inode = ecryptfs_evict_inode, 203 .evict_inode = ecryptfs_evict_inode,