Skip to content

Commit 57db4e8

Browse files
Thieu LeTyler Hicks
authored andcommitted
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 <[email protected]> [tyhicks: Changed NULL .drop_inode sop pointer to generic_drop_inode] Signed-off-by: Tyler Hicks <[email protected]>
1 parent fed8859 commit 57db4e8

File tree

6 files changed

+38
-30
lines changed

6 files changed

+38
-30
lines changed

fs/ecryptfs/ecryptfs_kernel.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,6 @@ struct ecryptfs_inode_info {
296296
struct inode vfs_inode;
297297
struct inode *wii_inode;
298298
struct file *lower_file;
299-
struct mutex lower_file_mutex;
300299
struct ecryptfs_crypt_stat crypt_stat;
301300
};
302301

fs/ecryptfs/file.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,14 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
273273
static int
274274
ecryptfs_fsync(struct file *file, int datasync)
275275
{
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);
282+
out:
283+
return rc;
277284
}
278285

279286
static int ecryptfs_fasync(int fd, struct file *file, int flag)

fs/ecryptfs/main.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
122122
ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
123123
int rc = 0;
124124

125-
mutex_lock(&inode_info->lower_file_mutex);
126125
if (!inode_info->lower_file) {
127126
struct dentry *lower_dentry;
128127
struct vfsmount *lower_mnt =
@@ -138,7 +137,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
138137
inode_info->lower_file = NULL;
139138
}
140139
}
141-
mutex_unlock(&inode_info->lower_file_mutex);
142140
return rc;
143141
}
144142

fs/ecryptfs/mmap.c

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
6262
{
6363
int rc;
6464

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+
6577
rc = ecryptfs_encrypt_page(page);
6678
if (rc) {
6779
ecryptfs_printk(KERN_WARNING, "Error encrypting "
@@ -70,8 +82,8 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
7082
goto out;
7183
}
7284
SetPageUptodate(page);
73-
unlock_page(page);
7485
out:
86+
unlock_page(page);
7587
return rc;
7688
}
7789

@@ -481,6 +493,7 @@ static int ecryptfs_write_end(struct file *file,
481493
struct ecryptfs_crypt_stat *crypt_stat =
482494
&ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
483495
int rc;
496+
int need_unlock_page = 1;
484497

485498
ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
486499
"(page w/ index = [0x%.16lx], to = [%d])\n", index, to);
@@ -501,26 +514,26 @@ static int ecryptfs_write_end(struct file *file,
501514
"zeros in page with index = [0x%.16lx]\n", index);
502515
goto out;
503516
}
504-
rc = ecryptfs_encrypt_page(page);
505-
if (rc) {
506-
ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
507-
"index [0x%.16lx])\n", index);
508-
goto out;
509-
}
517+
set_page_dirty(page);
518+
unlock_page(page);
519+
need_unlock_page = 0;
510520
if (pos + copied > i_size_read(ecryptfs_inode)) {
511521
i_size_write(ecryptfs_inode, pos + copied);
512522
ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
513523
"[0x%.16llx]\n",
514524
(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+
}
515532
}
516-
rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
517-
if (rc)
518-
printk(KERN_ERR "Error writing inode size to metadata; "
519-
"rc = [%d]\n", rc);
520-
else
521-
rc = copied;
533+
rc = copied;
522534
out:
523-
unlock_page(page);
535+
if (need_unlock_page)
536+
unlock_page(page);
524537
page_cache_release(page);
525538
return rc;
526539
}

fs/ecryptfs/read_write.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,11 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
4444
ssize_t rc;
4545

4646
inode_info = ecryptfs_inode_to_private(ecryptfs_inode);
47-
mutex_lock(&inode_info->lower_file_mutex);
4847
BUG_ON(!inode_info->lower_file);
49-
inode_info->lower_file->f_pos = offset;
5048
fs_save = get_fs();
5149
set_fs(get_ds());
52-
rc = vfs_write(inode_info->lower_file, data, size,
53-
&inode_info->lower_file->f_pos);
50+
rc = vfs_write(inode_info->lower_file, data, size, &offset);
5451
set_fs(fs_save);
55-
mutex_unlock(&inode_info->lower_file_mutex);
5652
mark_inode_dirty_sync(ecryptfs_inode);
5753
return rc;
5854
}
@@ -234,15 +230,11 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
234230
mm_segment_t fs_save;
235231
ssize_t rc;
236232

237-
mutex_lock(&inode_info->lower_file_mutex);
238233
BUG_ON(!inode_info->lower_file);
239-
inode_info->lower_file->f_pos = offset;
240234
fs_save = get_fs();
241235
set_fs(get_ds());
242-
rc = vfs_read(inode_info->lower_file, data, size,
243-
&inode_info->lower_file->f_pos);
236+
rc = vfs_read(inode_info->lower_file, data, size, &offset);
244237
set_fs(fs_save);
245-
mutex_unlock(&inode_info->lower_file_mutex);
246238
return rc;
247239
}
248240

fs/ecryptfs/super.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb)
5555
if (unlikely(!inode_info))
5656
goto out;
5757
ecryptfs_init_crypt_stat(&inode_info->crypt_stat);
58-
mutex_init(&inode_info->lower_file_mutex);
5958
inode_info->lower_file = NULL;
6059
inode = &inode_info->vfs_inode;
6160
out:
@@ -198,7 +197,7 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
198197
const struct super_operations ecryptfs_sops = {
199198
.alloc_inode = ecryptfs_alloc_inode,
200199
.destroy_inode = ecryptfs_destroy_inode,
201-
.drop_inode = generic_delete_inode,
200+
.drop_inode = generic_drop_inode,
202201
.statfs = ecryptfs_statfs,
203202
.remount_fs = NULL,
204203
.evict_inode = ecryptfs_evict_inode,

0 commit comments

Comments
 (0)