aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@linux.vnet.ibm.com>2009-09-16 20:04:20 -0400
committerTyler Hicks <tyhicks@linux.vnet.ibm.com>2009-09-23 10:10:34 -0400
commit96a7b9c2f5df899f302ade45cf17ad753fe130fd (patch)
tree096b67dbaad8e795344554994e28433a1e5b5de1 /fs
parent3891959846709a19f76628e33478cd85edb0e79f (diff)
eCryptfs: Propagate vfs_read and vfs_write return codes
Errors returned from vfs_read() and vfs_write() calls to the lower filesystem were being masked as -EINVAL. This caused some confusion to users who saw EINVAL instead of ENOSPC when the disk was full, for instance. Also, the actual bytes read or written were not accessible by callers to ecryptfs_read_lower() and ecryptfs_write_lower(), which may be useful in some cases. This patch updates the error handling logic where those functions are called in order to accept positive return codes indicating success. Cc: Eric Sandeen <esandeen@redhat.com> Acked-by: Serge Hallyn <serue@us.ibm.com> Cc: ecryptfs-devel@lists.launchpad.net Signed-off-by: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ecryptfs/crypto.c19
-rw-r--r--fs/ecryptfs/mmap.c4
-rw-r--r--fs/ecryptfs/read_write.c32
3 files changed, 26 insertions, 29 deletions
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index bae20ad1a504..fbb6e5eed697 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -509,13 +509,14 @@ int ecryptfs_encrypt_page(struct page *page)
509 + extent_offset), crypt_stat); 509 + extent_offset), crypt_stat);
510 rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt, 510 rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt,
511 offset, crypt_stat->extent_size); 511 offset, crypt_stat->extent_size);
512 if (rc) { 512 if (rc < 0) {
513 ecryptfs_printk(KERN_ERR, "Error attempting " 513 ecryptfs_printk(KERN_ERR, "Error attempting "
514 "to write lower page; rc = [%d]" 514 "to write lower page; rc = [%d]"
515 "\n", rc); 515 "\n", rc);
516 goto out; 516 goto out;
517 } 517 }
518 } 518 }
519 rc = 0;
519out: 520out:
520 if (enc_extent_page) { 521 if (enc_extent_page) {
521 kunmap(enc_extent_page); 522 kunmap(enc_extent_page);
@@ -631,7 +632,7 @@ int ecryptfs_decrypt_page(struct page *page)
631 rc = ecryptfs_read_lower(enc_extent_virt, offset, 632 rc = ecryptfs_read_lower(enc_extent_virt, offset,
632 crypt_stat->extent_size, 633 crypt_stat->extent_size,
633 ecryptfs_inode); 634 ecryptfs_inode);
634 if (rc) { 635 if (rc < 0) {
635 ecryptfs_printk(KERN_ERR, "Error attempting " 636 ecryptfs_printk(KERN_ERR, "Error attempting "
636 "to read lower page; rc = [%d]" 637 "to read lower page; rc = [%d]"
637 "\n", rc); 638 "\n", rc);
@@ -1213,14 +1214,15 @@ int ecryptfs_read_and_validate_header_region(char *data,
1213 crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE; 1214 crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE;
1214 rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size, 1215 rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size,
1215 ecryptfs_inode); 1216 ecryptfs_inode);
1216 if (rc) { 1217 if (rc < 0) {
1217 printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n", 1218 printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n",
1218 __func__, rc); 1219 __func__, rc);
1219 goto out; 1220 goto out;
1220 } 1221 }
1221 if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) { 1222 if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) {
1222 rc = -EINVAL; 1223 rc = -EINVAL;
1223 } 1224 } else
1225 rc = 0;
1224out: 1226out:
1225 return rc; 1227 return rc;
1226} 1228}
@@ -1315,10 +1317,11 @@ ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry,
1315 1317
1316 rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt, 1318 rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt,
1317 0, virt_len); 1319 0, virt_len);
1318 if (rc) 1320 if (rc < 0)
1319 printk(KERN_ERR "%s: Error attempting to write header " 1321 printk(KERN_ERR "%s: Error attempting to write header "
1320 "information to lower file; rc = [%d]\n", __func__, 1322 "information to lower file; rc = [%d]\n", __func__, rc);
1321 rc); 1323 else
1324 rc = 0;
1322 return rc; 1325 return rc;
1323} 1326}
1324 1327
@@ -1598,7 +1601,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
1598 } 1601 }
1599 rc = ecryptfs_read_lower(page_virt, 0, crypt_stat->extent_size, 1602 rc = ecryptfs_read_lower(page_virt, 0, crypt_stat->extent_size,
1600 ecryptfs_inode); 1603 ecryptfs_inode);
1601 if (!rc) 1604 if (rc >= 0)
1602 rc = ecryptfs_read_headers_virt(page_virt, crypt_stat, 1605 rc = ecryptfs_read_headers_virt(page_virt, crypt_stat,
1603 ecryptfs_dentry, 1606 ecryptfs_dentry,
1604 ECRYPTFS_VALIDATE_HEADER_SIZE); 1607 ECRYPTFS_VALIDATE_HEADER_SIZE);
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 05772aeaa8f4..df4ce99d0597 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -396,9 +396,11 @@ static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode)
396 rc = ecryptfs_write_lower(ecryptfs_inode, file_size_virt, 0, 396 rc = ecryptfs_write_lower(ecryptfs_inode, file_size_virt, 0,
397 sizeof(u64)); 397 sizeof(u64));
398 kfree(file_size_virt); 398 kfree(file_size_virt);
399 if (rc) 399 if (rc < 0)
400 printk(KERN_ERR "%s: Error writing file size to header; " 400 printk(KERN_ERR "%s: Error writing file size to header; "
401 "rc = [%d]\n", __func__, rc); 401 "rc = [%d]\n", __func__, rc);
402 else
403 rc = 0;
402out: 404out:
403 return rc; 405 return rc;
404} 406}
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
index a137c6ea2fee..0cc4fafd6552 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -34,15 +34,14 @@
34 * 34 *
35 * Write data to the lower file. 35 * Write data to the lower file.
36 * 36 *
37 * Returns zero on success; non-zero on error 37 * Returns bytes written on success; less than zero on error
38 */ 38 */
39int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, 39int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
40 loff_t offset, size_t size) 40 loff_t offset, size_t size)
41{ 41{
42 struct ecryptfs_inode_info *inode_info; 42 struct ecryptfs_inode_info *inode_info;
43 ssize_t octets_written;
44 mm_segment_t fs_save; 43 mm_segment_t fs_save;
45 int rc = 0; 44 ssize_t rc;
46 45
47 inode_info = ecryptfs_inode_to_private(ecryptfs_inode); 46 inode_info = ecryptfs_inode_to_private(ecryptfs_inode);
48 mutex_lock(&inode_info->lower_file_mutex); 47 mutex_lock(&inode_info->lower_file_mutex);
@@ -50,14 +49,9 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
50 inode_info->lower_file->f_pos = offset; 49 inode_info->lower_file->f_pos = offset;
51 fs_save = get_fs(); 50 fs_save = get_fs();
52 set_fs(get_ds()); 51 set_fs(get_ds());
53 octets_written = vfs_write(inode_info->lower_file, data, size, 52 rc = vfs_write(inode_info->lower_file, data, size,
54 &inode_info->lower_file->f_pos); 53 &inode_info->lower_file->f_pos);
55 set_fs(fs_save); 54 set_fs(fs_save);
56 if (octets_written < 0) {
57 printk(KERN_ERR "%s: octets_written = [%td]; "
58 "expected [%td]\n", __func__, octets_written, size);
59 rc = -EINVAL;
60 }
61 mutex_unlock(&inode_info->lower_file_mutex); 55 mutex_unlock(&inode_info->lower_file_mutex);
62 mark_inode_dirty_sync(ecryptfs_inode); 56 mark_inode_dirty_sync(ecryptfs_inode);
63 return rc; 57 return rc;
@@ -91,6 +85,8 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
91 + offset_in_page); 85 + offset_in_page);
92 virt = kmap(page_for_lower); 86 virt = kmap(page_for_lower);
93 rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size); 87 rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size);
88 if (rc > 0)
89 rc = 0;
94 kunmap(page_for_lower); 90 kunmap(page_for_lower);
95 return rc; 91 return rc;
96} 92}
@@ -229,30 +225,24 @@ out:
229 * Read @size bytes of data at byte offset @offset from the lower 225 * Read @size bytes of data at byte offset @offset from the lower
230 * inode into memory location @data. 226 * inode into memory location @data.
231 * 227 *
232 * Returns zero on success; non-zero on error 228 * Returns bytes read on success; 0 on EOF; less than zero on error
233 */ 229 */
234int ecryptfs_read_lower(char *data, loff_t offset, size_t size, 230int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
235 struct inode *ecryptfs_inode) 231 struct inode *ecryptfs_inode)
236{ 232{
237 struct ecryptfs_inode_info *inode_info = 233 struct ecryptfs_inode_info *inode_info =
238 ecryptfs_inode_to_private(ecryptfs_inode); 234 ecryptfs_inode_to_private(ecryptfs_inode);
239 ssize_t octets_read;
240 mm_segment_t fs_save; 235 mm_segment_t fs_save;
241 int rc = 0; 236 ssize_t rc;
242 237
243 mutex_lock(&inode_info->lower_file_mutex); 238 mutex_lock(&inode_info->lower_file_mutex);
244 BUG_ON(!inode_info->lower_file); 239 BUG_ON(!inode_info->lower_file);
245 inode_info->lower_file->f_pos = offset; 240 inode_info->lower_file->f_pos = offset;
246 fs_save = get_fs(); 241 fs_save = get_fs();
247 set_fs(get_ds()); 242 set_fs(get_ds());
248 octets_read = vfs_read(inode_info->lower_file, data, size, 243 rc = vfs_read(inode_info->lower_file, data, size,
249 &inode_info->lower_file->f_pos); 244 &inode_info->lower_file->f_pos);
250 set_fs(fs_save); 245 set_fs(fs_save);
251 if (octets_read < 0) {
252 printk(KERN_ERR "%s: octets_read = [%td]; "
253 "expected [%td]\n", __func__, octets_read, size);
254 rc = -EINVAL;
255 }
256 mutex_unlock(&inode_info->lower_file_mutex); 246 mutex_unlock(&inode_info->lower_file_mutex);
257 return rc; 247 return rc;
258} 248}
@@ -284,6 +274,8 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
284 offset = ((((loff_t)page_index) << PAGE_CACHE_SHIFT) + offset_in_page); 274 offset = ((((loff_t)page_index) << PAGE_CACHE_SHIFT) + offset_in_page);
285 virt = kmap(page_for_ecryptfs); 275 virt = kmap(page_for_ecryptfs);
286 rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode); 276 rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode);
277 if (rc > 0)
278 rc = 0;
287 kunmap(page_for_ecryptfs); 279 kunmap(page_for_ecryptfs);
288 flush_dcache_page(page_for_ecryptfs); 280 flush_dcache_page(page_for_ecryptfs);
289 return rc; 281 return rc;