Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57db4e8d authored by Thieu Le's avatar Thieu Le Committed by Tyler Hicks
Browse files

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: default avatarThieu Le <thieule@chromium.org>
[tyhicks: Changed NULL .drop_inode sop pointer to generic_drop_inode]
Signed-off-by: default avatarTyler Hicks <tyhicks@linux.vnet.ibm.com>
parent fed8859b
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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;
};

+8 −1
Original line number Diff line number Diff line
@@ -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)
+0 −2
Original line number Diff line number Diff line
@@ -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 =
@@ -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;
}

+27 −14
Original line number Diff line number Diff line
@@ -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 "
@@ -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;
}

@@ -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);
@@ -501,25 +514,25 @@ 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)
		if (rc) {
			printk(KERN_ERR "Error writing inode size to metadata; "
			       "rc = [%d]\n", rc);
	else
			goto out;
		}
	}
	rc = copied;
out:
	if (need_unlock_page)
		unlock_page(page);
	page_cache_release(page);
	return rc;
+2 −10
Original line number Diff line number Diff line
@@ -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;
}
@@ -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;
}

Loading