On Mon, 17 Sep 2007 16:50:16 -0500 Michael Halcrow <[EMAIL PROTECTED]> wrote:

> Convert readpage, prepare_write, and commit_write to use read_write.c
> routines. Remove sync_page; I cannot think of a good reason for
> implementing that in eCryptfs.
> 
> Signed-off-by: Michael Halcrow <[EMAIL PROTECTED]>
> ---
>  fs/ecryptfs/mmap.c |  199 
> +++++++++++++++++++++++++++-------------------------
>  1 files changed, 103 insertions(+), 96 deletions(-)
> 
> diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
> index 60e635e..dd68dd3 100644
> --- a/fs/ecryptfs/mmap.c
> +++ b/fs/ecryptfs/mmap.c
> @@ -267,9 +267,78 @@ static void set_header_info(char *page_virt,
>  }
>  
>  /**
> + * ecryptfs_copy_up_encrypted_with_header
> + * @page: Sort of a ``virtual'' representation of the encrypted lower
> + *        file. The actual lower file does not have the metadata in
> + *        the header.
> + * @crypt_stat: The eCryptfs inode's cryptographic context
> + *
> + * The ``view'' is the version of the file that userspace winds up
> + * seeing, with the header information inserted.
> + */
> +static int
> +ecryptfs_copy_up_encrypted_with_header(struct page *page,
> +                                    struct ecryptfs_crypt_stat *crypt_stat)
> +{
> +     loff_t extent_num_in_page = 0;
> +     loff_t num_extents_per_page = (PAGE_CACHE_SIZE
> +                                    / crypt_stat->extent_size);
> +     int rc = 0;
> +
> +     while (extent_num_in_page < num_extents_per_page) {
> +             loff_t view_extent_num = ((page->index * num_extents_per_page)

overflow?

> +                                       + extent_num_in_page);
> +
> +             if (view_extent_num < crypt_stat->num_header_extents_at_front) {
> +                     /* This is a header extent */
> +                     char *page_virt;
> +
> +                     page_virt = kmap_atomic(page, KM_USER0);
> +                     memset(page_virt, 0, PAGE_CACHE_SIZE);
> +                     /* TODO: Support more than one header extent */
> +                     if (view_extent_num == 0) {
> +                             rc = ecryptfs_read_xattr_region(
> +                                     page_virt, page->mapping->host);
> +                             set_header_info(page_virt, crypt_stat);
> +                     }
> +                     kunmap_atomic(page_virt, KM_USER0);
> +                     flush_dcache_page(page);
> +                     if (rc) {
> +                             ClearPageUptodate(page);
> +                             printk(KERN_ERR "%s: Error reading xattr "
> +                                    "region; rc = [%d]\n", __FUNCTION__, rc);
> +                             goto out;
> +                     }
> +                     SetPageUptodate(page);

I don't know what sort of page `page' refers to here, but normally we only
manipulate the page uptodate status under lock_page().


> +             } else {
> +                     /* This is an encrypted data extent */
> +                     loff_t lower_offset =
> +                             ((view_extent_num -
> +                               crypt_stat->num_header_extents_at_front)
> +                              * crypt_stat->extent_size);

overflow?

> +                     rc = ecryptfs_read_lower_page_segment(
> +                             page, (lower_offset >> PAGE_CACHE_SHIFT),
> +                             (lower_offset & ~PAGE_CACHE_MASK),
> +                             crypt_stat->extent_size, page->mapping->host);
> +                     if (rc) {
> +                             printk(KERN_ERR "%s: Error attempting to read "
> +                                    "extent at offset [%lld] in the lower "
> +                                    "file; rc = [%d]\n", __FUNCTION__,
> +                                    lower_offset, rc);
> +                             goto out;
> +                     }
> +             }
> +             extent_num_in_page++;
> +     }
> +out:
> +     return rc;
> +}
> +
> +/**
>   * ecryptfs_readpage
> - * @file: This is an ecryptfs file
> - * @page: ecryptfs associated page to stick the read data into
> + * @file: An eCryptfs file
> + * @page: Page from eCryptfs inode mapping into which to stick the read data
>   *
>   * Read in a page, decrypting if necessary.
>   *
> @@ -277,59 +346,35 @@ static void set_header_info(char *page_virt,
>   */
>  static int ecryptfs_readpage(struct file *file, struct page *page)
>  {
> +     struct ecryptfs_crypt_stat *crypt_stat =
> +             
> &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
>       int rc = 0;
> -     struct ecryptfs_crypt_stat *crypt_stat;
>  
> -     BUG_ON(!(file && file->f_path.dentry && file->f_path.dentry->d_inode));
> -     crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)
> -                     ->crypt_stat;
>       if (!crypt_stat
>           || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
>           || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
>               ecryptfs_printk(KERN_DEBUG,
>                               "Passing through unencrypted page\n");
> -             rc = ecryptfs_do_readpage(file, page, page->index);
> -             if (rc) {
> -                     ecryptfs_printk(KERN_ERR, "Error reading page; rc = "
> -                                     "[%d]\n", rc);
> -                     goto out;
> -             }
> +             rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
> +                                                   PAGE_CACHE_SIZE,
> +                                                   page->mapping->host);
>       } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
>               if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
> -                     int num_pages_in_header_region =
> -                             (crypt_stat->extent_size
> -                              / PAGE_CACHE_SIZE);
> -
> -                     if (page->index < num_pages_in_header_region) {
> -                             char *page_virt;
> -
> -                             page_virt = kmap_atomic(page, KM_USER0);
> -                             memset(page_virt, 0, PAGE_CACHE_SIZE);
> -                             if (page->index == 0) {
> -                                     rc = ecryptfs_read_xattr_region(
> -                                             page_virt, page->mapping->host);
> -                                     set_header_info(page_virt, crypt_stat);
> -                             }
> -                             kunmap_atomic(page_virt, KM_USER0);
> -                             flush_dcache_page(page);
> -                             if (rc) {
> -                                     printk(KERN_ERR "Error reading xattr "
> -                                            "region\n");
> -                                     goto out;
> -                             }
> -                     } else {
> -                             rc = ecryptfs_do_readpage(
> -                                     file, page,
> -                                     (page->index
> -                                      - num_pages_in_header_region));
> -                             if (rc) {
> -                                     printk(KERN_ERR "Error reading page; "
> -                                            "rc = [%d]\n", rc);
> -                                     goto out;
> -                             }
> +                     rc = ecryptfs_copy_up_encrypted_with_header(page,
> +                                                                 crypt_stat);
> +                     if (rc) {
> +                             printk(KERN_ERR "%s: Error attempting to copy "
> +                                    "the encrypted content from the lower "
> +                                    "file whilst inserting the metadata "
> +                                    "from the xattr into the header; rc = "
> +                                    "[%d]\n", __FUNCTION__, rc);
> +                             goto out;
>                       }
> +
>               } else {
> -                     rc = ecryptfs_do_readpage(file, page, page->index);
> +                     rc = ecryptfs_read_lower_page_segment(
> +                             page, page->index, 0, PAGE_CACHE_SIZE,
> +                             page->mapping->host);
>                       if (rc) {
>                               printk(KERN_ERR "Error reading page; rc = "
>                                      "[%d]\n", rc);
> @@ -344,10 +389,7 @@ static int ecryptfs_readpage(struct file *file, struct 
> page *page)
>                       goto out;
>               }
>       }
> -     SetPageUptodate(page);
>  out:
> -     if (rc)
> -             ClearPageUptodate(page);
>       ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
>                       page->index);
>       unlock_page(page);
> @@ -403,9 +445,12 @@ static int ecryptfs_prepare_write(struct file *file, 
> struct page *page,
>               goto out;       /* If we are writing a full page, it will be
>                                  up to date. */
>       if (!PageUptodate(page))
> -             rc = ecryptfs_do_readpage(file, page, page->index);
> +             rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
> +                                                   PAGE_CACHE_SIZE,
> +                                                   page->mapping->host);
>       if (page->index != 0) {
> -             loff_t end_of_prev_pg_pos = page_offset(page) - 1;
> +             loff_t end_of_prev_pg_pos =
> +                     (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1);
>  
>               if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) {
>                       rc = ecryptfs_truncate(file->f_path.dentry,
> @@ -633,18 +678,11 @@ static int ecryptfs_commit_write(struct file *file, 
> struct page *page,
>                                unsigned from, unsigned to)
>  {
>       loff_t pos;
> -     struct inode *inode;
> -     struct inode *lower_inode;
> -     struct file *lower_file;
> -     struct ecryptfs_crypt_stat *crypt_stat;
> +     struct inode *ecryptfs_inode = page->mapping->host;
> +     struct ecryptfs_crypt_stat *crypt_stat =
> +             
> &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
>       int rc;
>  
> -     inode = page->mapping->host;
> -     lower_inode = ecryptfs_inode_to_lower(inode);
> -     lower_file = ecryptfs_file_to_lower(file);
> -     mutex_lock(&lower_inode->i_mutex);
> -     crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)
> -                             ->crypt_stat;
>       if (crypt_stat->flags & ECRYPTFS_NEW_FILE) {
>               ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in "
>                       "crypt_stat at memory location [%p]\n", crypt_stat);
> @@ -654,6 +692,7 @@ static int ecryptfs_commit_write(struct file *file, 
> struct page *page,
>       ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
>                       "(page w/ index = [0x%.16x], to = [%d])\n", page->index,
>                       to);
> +     /* Fills in zeros if 'to' goes beyond inode size */
>       rc = fill_zeros_to_end_of_page(page, to);
>       if (rc) {
>               ecryptfs_printk(KERN_WARNING, "Error attempting to fill "
> @@ -667,25 +706,17 @@ static int ecryptfs_commit_write(struct file *file, 
> struct page *page,
>                               "index [0x%.16x])\n", page->index);
>               goto out;
>       }
> -     inode->i_blocks = lower_inode->i_blocks;
> -     pos = page_offset(page) + to;
> -     if (pos > i_size_read(inode)) {
> -             i_size_write(inode, pos);
> +     pos = (page->index << PAGE_CACHE_SHIFT) + to;

overflow

> +     if (pos > i_size_read(ecryptfs_inode)) {
> +             i_size_write(ecryptfs_inode, pos);
>               ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
> -                             "[0x%.16x]\n", i_size_read(inode));
> +                             "[0x%.16x]\n", i_size_read(ecryptfs_inode));
>       }
> -     rc = ecryptfs_write_inode_size_to_metadata(inode);
> +     rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
>       if (rc)
>               printk(KERN_ERR "Error writing inode size to metadata; "
>                      "rc = [%d]\n", rc);
> -     lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
> -     mark_inode_dirty_sync(inode);
>  out:
> -     if (rc < 0)
> -             ClearPageUptodate(page);
> -     else
> -             SetPageUptodate(page);
> -     mutex_unlock(&lower_inode->i_mutex);
>       return rc;
>  }
>  
> @@ -751,34 +782,10 @@ static sector_t ecryptfs_bmap(struct address_space 
> *mapping, sector_t block)
>       return rc;
>  }
>  
> -static void ecryptfs_sync_page(struct page *page)
> -{
> -     struct inode *inode;
> -     struct inode *lower_inode;
> -     struct page *lower_page;
> -
> -     inode = page->mapping->host;
> -     lower_inode = ecryptfs_inode_to_lower(inode);
> -     /* NOTE: Recently swapped with grab_cache_page(), since
> -      * sync_page() just makes sure that pending I/O gets done. */
> -     lower_page = find_lock_page(lower_inode->i_mapping, page->index);
> -     if (!lower_page) {
> -             ecryptfs_printk(KERN_DEBUG, "find_lock_page failed\n");
> -             return;
> -     }
> -     if (lower_page->mapping->a_ops->sync_page)
> -             lower_page->mapping->a_ops->sync_page(lower_page);
> -     ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
> -                     lower_page->index);
> -     unlock_page(lower_page);
> -     page_cache_release(lower_page);
> -}
> -
>  struct address_space_operations ecryptfs_aops = {
>       .writepage = ecryptfs_writepage,
>       .readpage = ecryptfs_readpage,
>       .prepare_write = ecryptfs_prepare_write,
>       .commit_write = ecryptfs_commit_write,
>       .bmap = ecryptfs_bmap,
> -     .sync_page = ecryptfs_sync_page,
>  };
> -- 
> 1.5.1.6
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to