aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@canonical.com>2012-01-18 19:30:04 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-02-03 12:18:50 -0500
commita8d66a0b58b353d47b05891fd20b3bdc4c8a8015 (patch)
tree3edad990cea1e70a57775ca6f82557d7dcf7b6f9 /fs/ecryptfs
parent9b9f40e785724a265fb6027216fb2bd1e97894f7 (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>
Diffstat (limited to 'fs/ecryptfs')
-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 3745f7c2b9c..54eb14caad7 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,
132 size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page); 132 size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
133 size_t total_remaining_bytes = ((offset + size) - pos); 133 size_t total_remaining_bytes = ((offset + size) - pos);
134 134
135 if (fatal_signal_pending(current)) {
136 rc = -EINTR;
137 break;
138 }
139
135 if (num_bytes > total_remaining_bytes) 140 if (num_bytes > total_remaining_bytes)
136 num_bytes = total_remaining_bytes; 141 num_bytes = total_remaining_bytes;
137 if (pos < offset) { 142 if (pos < offset) {
@@ -193,15 +198,19 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset,
193 } 198 }
194 pos += num_bytes; 199 pos += num_bytes;
195 } 200 }
196 if ((offset + size) > ecryptfs_file_size) { 201 if (pos > ecryptfs_file_size) {
197 i_size_write(ecryptfs_inode, (offset + size)); 202 i_size_write(ecryptfs_inode, pos);
198 if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) { 203 if (crypt_stat->flags & ECRYPTFS_ENCRYPTED) {
199 rc = ecryptfs_write_inode_size_to_metadata( 204 int rc2;
205
206 rc2 = ecryptfs_write_inode_size_to_metadata(
200 ecryptfs_inode); 207 ecryptfs_inode);
201 if (rc) { 208 if (rc2) {
202 printk(KERN_ERR "Problem with " 209 printk(KERN_ERR "Problem with "
203 "ecryptfs_write_inode_size_to_metadata; " 210 "ecryptfs_write_inode_size_to_metadata; "
204 "rc = [%d]\n", rc); 211 "rc = [%d]\n", rc2);
212 if (!rc)
213 rc = rc2;
205 goto out; 214 goto out;
206 } 215 }
207 } 216 }