summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@canonical.com>2012-01-18 18:30:04 -0600
committerSimone Willett <swillett@nvidia.com>2012-02-09 18:20:03 -0800
commitab9cf2e9f3ddf639b56cec1edb2ec8d2563106a3 (patch)
tree3f9b19d96fbd72087818e80370454309abea4343 /fs
parent0460bba0e4b2042a2bd5984a8e96e5bda706c4cd (diff)
eCryptfs: Make truncate path killable
commit 5e6f0d769017cc49207ef56996e42363ec26c1f0 upstream. ecryptfs_write() handles the truncation of eCryptfs inodes. It grabs a page, zeroes out the appropriate portions, and then encrypts the page before writing it to the lower filesystem. It was unkillable and due to the lack of sparse file support could result in tying up a large portion of system resources, while encrypting pages of zeros, with no way for the truncate operation to be stopped from userspace. This patch adds the ability for ecryptfs_write() to detect a pending fatal signal and return as gracefully as possible. The intent is to leave the lower file in a useable state, while still allowing a user to break out of the encryption loop. If a pending fatal signal is detected, the eCryptfs inode size is updated to reflect the modified inode size and then -EINTR is returned. Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Change-Id: I80e83c16c58586c700df081500b6c3e2a4a06270 Reviewed-on: http://git-master/r/79650 Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'fs')
-rw-r--r--fs/ecryptfs/read_write.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
index 3745f7c2b9c2..54eb14caad7b 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -132,6 +132,11 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
size_t total_remaining_bytes = ((offset + size) - pos);
+ if (fatal_signal_pending(current)) {
+ rc = -EINTR;
+ break;
+ }
+
if (num_bytes > total_remaining_bytes)
num_bytes = total_remaining_bytes;
if (pos < offset) {
@@ -193,15 +198,19 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
}
pos += num_bytes;
}
- if ((offset + size) > ecryptfs_file_size) {
- i_size_write(ecryptfs_inode, (offset + size));
+ if (pos > ecryptfs_file_size) {
+ i_size_write(ecryptfs_inode, pos);
if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) {
- rc = ecryptfs_write_inode_size_to_metadata(
+ int rc2;
+
+ rc2 = ecryptfs_write_inode_size_to_metadata(
ecryptfs_inode);
- if (rc) {
+ if (rc2) {
printk(KERN_ERR "Problem with "
"ecryptfs_write_inode_size_to_metadata; "
- "rc = [%d]\n", rc);
+ "rc = [%d]\n", rc2);
+ if (!rc)
+ rc = rc2;
goto out;
}
}