Skip to content

Commit

Permalink
ecryptfs: modify write path to encrypt page in writepage
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Thieu Le authored and Tyler Hicks committed Mar 28, 2011
1 parent fed8859 commit 57db4e8
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 30 deletions.
1 change: 0 additions & 1 deletion fs/ecryptfs/ecryptfs_kernel.h
Expand Up @@ -296,7 +296,6 @@ struct ecryptfs_inode_info {
struct inode vfs_inode;
struct inode *wii_inode;
struct file *lower_file;
struct mutex lower_file_mutex;
struct ecryptfs_crypt_stat crypt_stat;
};

Expand Down
9 changes: 8 additions & 1 deletion fs/ecryptfs/file.c
Expand Up @@ -273,7 +273,14 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
static int
ecryptfs_fsync(struct file *file, int datasync)
{
return vfs_fsync(ecryptfs_file_to_lower(file), datasync);
int rc = 0;

rc = generic_file_fsync(file, datasync);
if (rc)
goto out;
rc = vfs_fsync(ecryptfs_file_to_lower(file), datasync);
out:
return rc;
}

static int ecryptfs_fasync(int fd, struct file *file, int flag)
Expand Down
2 changes: 0 additions & 2 deletions fs/ecryptfs/main.c
Expand Up @@ -122,7 +122,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
int rc = 0;

mutex_lock(&inode_info->lower_file_mutex);
if (!inode_info->lower_file) {
struct dentry *lower_dentry;
struct vfsmount *lower_mnt =
Expand All @@ -138,7 +137,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
inode_info->lower_file = NULL;
}
}
mutex_unlock(&inode_info->lower_file_mutex);
return rc;
}

Expand Down
41 changes: 27 additions & 14 deletions fs/ecryptfs/mmap.c
Expand Up @@ -62,6 +62,18 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
{
int rc;

/*
* Refuse to write the page out if we are called from reclaim context
* since our writepage() path may potentially allocate memory when
* calling into the lower fs vfs_write() which may in turn invoke
* us again.
*/
if (current->flags & PF_MEMALLOC) {
redirty_page_for_writepage(wbc, page);
rc = 0;
goto out;
}

rc = ecryptfs_encrypt_page(page);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error encrypting "
Expand All @@ -70,8 +82,8 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
goto out;
}
SetPageUptodate(page);
unlock_page(page);
out:
unlock_page(page);
return rc;
}

Expand Down Expand Up @@ -481,6 +493,7 @@ static int ecryptfs_write_end(struct file *file,
struct ecryptfs_crypt_stat *crypt_stat =
&ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
int rc;
int need_unlock_page = 1;

ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
"(page w/ index = [0x%.16lx], to = [%d])\n", index, to);
Expand All @@ -501,26 +514,26 @@ static int ecryptfs_write_end(struct file *file,
"zeros in page with index = [0x%.16lx]\n", index);
goto out;
}
rc = ecryptfs_encrypt_page(page);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
"index [0x%.16lx])\n", index);
goto out;
}
set_page_dirty(page);
unlock_page(page);
need_unlock_page = 0;
if (pos + copied > i_size_read(ecryptfs_inode)) {
i_size_write(ecryptfs_inode, pos + copied);
ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
"[0x%.16llx]\n",
(unsigned long long)i_size_read(ecryptfs_inode));
balance_dirty_pages_ratelimited(mapping);
rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
if (rc) {
printk(KERN_ERR "Error writing inode size to metadata; "
"rc = [%d]\n", rc);
goto out;
}
}
rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
if (rc)
printk(KERN_ERR "Error writing inode size to metadata; "
"rc = [%d]\n", rc);
else
rc = copied;
rc = copied;
out:
unlock_page(page);
if (need_unlock_page)
unlock_page(page);
page_cache_release(page);
return rc;
}
Expand Down
12 changes: 2 additions & 10 deletions fs/ecryptfs/read_write.c
Expand Up @@ -44,15 +44,11 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
ssize_t rc;

inode_info = ecryptfs_inode_to_private(ecryptfs_inode);
mutex_lock(&inode_info->lower_file_mutex);
BUG_ON(!inode_info->lower_file);
inode_info->lower_file->f_pos = offset;
fs_save = get_fs();
set_fs(get_ds());
rc = vfs_write(inode_info->lower_file, data, size,
&inode_info->lower_file->f_pos);
rc = vfs_write(inode_info->lower_file, data, size, &offset);
set_fs(fs_save);
mutex_unlock(&inode_info->lower_file_mutex);
mark_inode_dirty_sync(ecryptfs_inode);
return rc;
}
Expand Down Expand Up @@ -234,15 +230,11 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
mm_segment_t fs_save;
ssize_t rc;

mutex_lock(&inode_info->lower_file_mutex);
BUG_ON(!inode_info->lower_file);
inode_info->lower_file->f_pos = offset;
fs_save = get_fs();
set_fs(get_ds());
rc = vfs_read(inode_info->lower_file, data, size,
&inode_info->lower_file->f_pos);
rc = vfs_read(inode_info->lower_file, data, size, &offset);
set_fs(fs_save);
mutex_unlock(&inode_info->lower_file_mutex);
return rc;
}

Expand Down
3 changes: 1 addition & 2 deletions fs/ecryptfs/super.c
Expand Up @@ -55,7 +55,6 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb)
if (unlikely(!inode_info))
goto out;
ecryptfs_init_crypt_stat(&inode_info->crypt_stat);
mutex_init(&inode_info->lower_file_mutex);
inode_info->lower_file = NULL;
inode = &inode_info->vfs_inode;
out:
Expand Down Expand Up @@ -198,7 +197,7 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
const struct super_operations ecryptfs_sops = {
.alloc_inode = ecryptfs_alloc_inode,
.destroy_inode = ecryptfs_destroy_inode,
.drop_inode = generic_delete_inode,
.drop_inode = generic_drop_inode,
.statfs = ecryptfs_statfs,
.remount_fs = NULL,
.evict_inode = ecryptfs_evict_inode,
Expand Down

0 comments on commit 57db4e8

Please sign in to comment.