]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
eCryptfs: Propagate vfs_read and vfs_write return codes
authorTyler Hicks <tyhicks@linux.vnet.ibm.com>
Thu, 17 Sep 2009 00:04:20 +0000 (19:04 -0500)
committerTyler Hicks <tyhicks@linux.vnet.ibm.com>
Wed, 23 Sep 2009 14:10:34 +0000 (09:10 -0500)
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>
fs/ecryptfs/crypto.c
fs/ecryptfs/mmap.c
fs/ecryptfs/read_write.c

index bae20ad1a50478a3287fc4f72696069f8a12ab8d..fbb6e5eed6971a5a3b68e0e6c55bfa26fc8ec623 100644 (file)
@@ -509,13 +509,14 @@ int ecryptfs_encrypt_page(struct page *page)
                                  + extent_offset), crypt_stat);
                rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt,
                                          offset, crypt_stat->extent_size);
-               if (rc) {
+               if (rc < 0) {
                        ecryptfs_printk(KERN_ERR, "Error attempting "
                                        "to write lower page; rc = [%d]"
                                        "\n", rc);
                        goto out;
                }
        }
+       rc = 0;
 out:
        if (enc_extent_page) {
                kunmap(enc_extent_page);
@@ -631,7 +632,7 @@ int ecryptfs_decrypt_page(struct page *page)
                rc = ecryptfs_read_lower(enc_extent_virt, offset,
                                         crypt_stat->extent_size,
                                         ecryptfs_inode);
-               if (rc) {
+               if (rc < 0) {
                        ecryptfs_printk(KERN_ERR, "Error attempting "
                                        "to read lower page; rc = [%d]"
                                        "\n", rc);
@@ -1213,14 +1214,15 @@ int ecryptfs_read_and_validate_header_region(char *data,
                crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE;
        rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size,
                                 ecryptfs_inode);
-       if (rc) {
+       if (rc < 0) {
                printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n",
                       __func__, rc);
                goto out;
        }
        if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) {
                rc = -EINVAL;
-       }
+       } else
+               rc = 0;
 out:
        return rc;
 }
@@ -1315,10 +1317,11 @@ ecryptfs_write_metadata_to_contents(struct dentry *ecryptfs_dentry,
 
        rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt,
                                  0, virt_len);
-       if (rc)
+       if (rc < 0)
                printk(KERN_ERR "%s: Error attempting to write header "
-                      "information to lower file; rc = [%d]\n", __func__,
-                      rc);
+                      "information to lower file; rc = [%d]\n", __func__, rc);
+       else
+               rc = 0;
        return rc;
 }
 
@@ -1598,7 +1601,7 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
        }
        rc = ecryptfs_read_lower(page_virt, 0, crypt_stat->extent_size,
                                 ecryptfs_inode);
-       if (!rc)
+       if (rc >= 0)
                rc = ecryptfs_read_headers_virt(page_virt, crypt_stat,
                                                ecryptfs_dentry,
                                                ECRYPTFS_VALIDATE_HEADER_SIZE);
index 05772aeaa8f4ce09a9cf31e446315802c6cc1969..df4ce99d0597bb2743dfd3c6b2fccfc807ec55d7 100644 (file)
@@ -396,9 +396,11 @@ static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode)
        rc = ecryptfs_write_lower(ecryptfs_inode, file_size_virt, 0,
                                  sizeof(u64));
        kfree(file_size_virt);
-       if (rc)
+       if (rc < 0)
                printk(KERN_ERR "%s: Error writing file size to header; "
                       "rc = [%d]\n", __func__, rc);
+       else
+               rc = 0;
 out:
        return rc;
 }
index a137c6ea2feec65181741ad1531bd35b6bfe0012..0cc4fafd6552c3d8ddef02e38a81dad96eb6ff6f 100644 (file)
  *
  * Write data to the lower file.
  *
- * Returns zero on success; non-zero on error
+ * Returns bytes written on success; less than zero on error
  */
 int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
                         loff_t offset, size_t size)
 {
        struct ecryptfs_inode_info *inode_info;
-       ssize_t octets_written;
        mm_segment_t fs_save;
-       int rc = 0;
+       ssize_t rc;
 
        inode_info = ecryptfs_inode_to_private(ecryptfs_inode);
        mutex_lock(&inode_info->lower_file_mutex);
@@ -50,14 +49,9 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
        inode_info->lower_file->f_pos = offset;
        fs_save = get_fs();
        set_fs(get_ds());
-       octets_written = vfs_write(inode_info->lower_file, data, size,
-                                  &inode_info->lower_file->f_pos);
+       rc = vfs_write(inode_info->lower_file, data, size,
+                      &inode_info->lower_file->f_pos);
        set_fs(fs_save);
-       if (octets_written < 0) {
-               printk(KERN_ERR "%s: octets_written = [%td]; "
-                      "expected [%td]\n", __func__, octets_written, size);
-               rc = -EINVAL;
-       }
        mutex_unlock(&inode_info->lower_file_mutex);
        mark_inode_dirty_sync(ecryptfs_inode);
        return rc;
@@ -91,6 +85,8 @@ int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
                  + offset_in_page);
        virt = kmap(page_for_lower);
        rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size);
+       if (rc > 0)
+               rc = 0;
        kunmap(page_for_lower);
        return rc;
 }
@@ -229,30 +225,24 @@ out:
  * Read @size bytes of data at byte offset @offset from the lower
  * inode into memory location @data.
  *
- * Returns zero on success; non-zero on error
+ * Returns bytes read on success; 0 on EOF; less than zero on error
  */
 int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
                        struct inode *ecryptfs_inode)
 {
        struct ecryptfs_inode_info *inode_info =
                ecryptfs_inode_to_private(ecryptfs_inode);
-       ssize_t octets_read;
        mm_segment_t fs_save;
-       int rc = 0;
+       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());
-       octets_read = vfs_read(inode_info->lower_file, data, size,
-                              &inode_info->lower_file->f_pos);
+       rc = vfs_read(inode_info->lower_file, data, size,
+                     &inode_info->lower_file->f_pos);
        set_fs(fs_save);
-       if (octets_read < 0) {
-               printk(KERN_ERR "%s: octets_read = [%td]; "
-                      "expected [%td]\n", __func__, octets_read, size);
-               rc = -EINVAL;
-       }
        mutex_unlock(&inode_info->lower_file_mutex);
        return rc;
 }
@@ -284,6 +274,8 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
        offset = ((((loff_t)page_index) << PAGE_CACHE_SHIFT) + offset_in_page);
        virt = kmap(page_for_ecryptfs);
        rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode);
+       if (rc > 0)
+               rc = 0;
        kunmap(page_for_ecryptfs);
        flush_dcache_page(page_for_ecryptfs);
        return rc;