aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/mmap.c
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-10-16 04:28:11 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:12 -0400
commitbf12be1cc851cface331b0e74713a6bb1cb046b0 (patch)
treec20afee72af830fce2bf8255d63aed59a6db3c4e /fs/ecryptfs/mmap.c
parent2ed92554abc5c40d4450f9869c9565a1919a9242 (diff)
eCryptfs: convert mmap functions to use persistent file
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 <mhalcrow@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs/mmap.c')
-rw-r--r--fs/ecryptfs/mmap.c199
1 files changed, 103 insertions, 96 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 60e635eddc77..9bc707df3b60 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -267,9 +267,78 @@ static void set_header_info(char *page_virt,
267} 267}
268 268
269/** 269/**
270 * ecryptfs_copy_up_encrypted_with_header
271 * @page: Sort of a ``virtual'' representation of the encrypted lower
272 * file. The actual lower file does not have the metadata in
273 * the header. This is locked.
274 * @crypt_stat: The eCryptfs inode's cryptographic context
275 *
276 * The ``view'' is the version of the file that userspace winds up
277 * seeing, with the header information inserted.
278 */
279static int
280ecryptfs_copy_up_encrypted_with_header(struct page *page,
281 struct ecryptfs_crypt_stat *crypt_stat)
282{
283 loff_t extent_num_in_page = 0;
284 loff_t num_extents_per_page = (PAGE_CACHE_SIZE
285 / crypt_stat->extent_size);
286 int rc = 0;
287
288 while (extent_num_in_page < num_extents_per_page) {
289 loff_t view_extent_num = ((page->index * num_extents_per_page)
290 + extent_num_in_page);
291
292 if (view_extent_num < crypt_stat->num_header_extents_at_front) {
293 /* This is a header extent */
294 char *page_virt;
295
296 page_virt = kmap_atomic(page, KM_USER0);
297 memset(page_virt, 0, PAGE_CACHE_SIZE);
298 /* TODO: Support more than one header extent */
299 if (view_extent_num == 0) {
300 rc = ecryptfs_read_xattr_region(
301 page_virt, page->mapping->host);
302 set_header_info(page_virt, crypt_stat);
303 }
304 kunmap_atomic(page_virt, KM_USER0);
305 flush_dcache_page(page);
306 if (rc) {
307 ClearPageUptodate(page);
308 printk(KERN_ERR "%s: Error reading xattr "
309 "region; rc = [%d]\n", __FUNCTION__, rc);
310 goto out;
311 }
312 SetPageUptodate(page);
313 } else {
314 /* This is an encrypted data extent */
315 loff_t lower_offset =
316 ((view_extent_num -
317 crypt_stat->num_header_extents_at_front)
318 * crypt_stat->extent_size);
319
320 rc = ecryptfs_read_lower_page_segment(
321 page, (lower_offset >> PAGE_CACHE_SHIFT),
322 (lower_offset & ~PAGE_CACHE_MASK),
323 crypt_stat->extent_size, page->mapping->host);
324 if (rc) {
325 printk(KERN_ERR "%s: Error attempting to read "
326 "extent at offset [%lld] in the lower "
327 "file; rc = [%d]\n", __FUNCTION__,
328 lower_offset, rc);
329 goto out;
330 }
331 }
332 extent_num_in_page++;
333 }
334out:
335 return rc;
336}
337
338/**
270 * ecryptfs_readpage 339 * ecryptfs_readpage
271 * @file: This is an ecryptfs file 340 * @file: An eCryptfs file
272 * @page: ecryptfs associated page to stick the read data into 341 * @page: Page from eCryptfs inode mapping into which to stick the read data
273 * 342 *
274 * Read in a page, decrypting if necessary. 343 * Read in a page, decrypting if necessary.
275 * 344 *
@@ -277,59 +346,35 @@ static void set_header_info(char *page_virt,
277 */ 346 */
278static int ecryptfs_readpage(struct file *file, struct page *page) 347static int ecryptfs_readpage(struct file *file, struct page *page)
279{ 348{
349 struct ecryptfs_crypt_stat *crypt_stat =
350 &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
280 int rc = 0; 351 int rc = 0;
281 struct ecryptfs_crypt_stat *crypt_stat;
282 352
283 BUG_ON(!(file && file->f_path.dentry && file->f_path.dentry->d_inode));
284 crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)
285 ->crypt_stat;
286 if (!crypt_stat 353 if (!crypt_stat
287 || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED) 354 || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
288 || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { 355 || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
289 ecryptfs_printk(KERN_DEBUG, 356 ecryptfs_printk(KERN_DEBUG,
290 "Passing through unencrypted page\n"); 357 "Passing through unencrypted page\n");
291 rc = ecryptfs_do_readpage(file, page, page->index); 358 rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
292 if (rc) { 359 PAGE_CACHE_SIZE,
293 ecryptfs_printk(KERN_ERR, "Error reading page; rc = " 360 page->mapping->host);
294 "[%d]\n", rc);
295 goto out;
296 }
297 } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { 361 } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
298 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { 362 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
299 int num_pages_in_header_region = 363 rc = ecryptfs_copy_up_encrypted_with_header(page,
300 (crypt_stat->extent_size 364 crypt_stat);
301 / PAGE_CACHE_SIZE); 365 if (rc) {
302 366 printk(KERN_ERR "%s: Error attempting to copy "
303 if (page->index < num_pages_in_header_region) { 367 "the encrypted content from the lower "
304 char *page_virt; 368 "file whilst inserting the metadata "
305 369 "from the xattr into the header; rc = "
306 page_virt = kmap_atomic(page, KM_USER0); 370 "[%d]\n", __FUNCTION__, rc);
307 memset(page_virt, 0, PAGE_CACHE_SIZE); 371 goto out;
308 if (page->index == 0) {
309 rc = ecryptfs_read_xattr_region(
310 page_virt, page->mapping->host);
311 set_header_info(page_virt, crypt_stat);
312 }
313 kunmap_atomic(page_virt, KM_USER0);
314 flush_dcache_page(page);
315 if (rc) {
316 printk(KERN_ERR "Error reading xattr "
317 "region\n");
318 goto out;
319 }
320 } else {
321 rc = ecryptfs_do_readpage(
322 file, page,
323 (page->index
324 - num_pages_in_header_region));
325 if (rc) {
326 printk(KERN_ERR "Error reading page; "
327 "rc = [%d]\n", rc);
328 goto out;
329 }
330 } 372 }
373
331 } else { 374 } else {
332 rc = ecryptfs_do_readpage(file, page, page->index); 375 rc = ecryptfs_read_lower_page_segment(
376 page, page->index, 0, PAGE_CACHE_SIZE,
377 page->mapping->host);
333 if (rc) { 378 if (rc) {
334 printk(KERN_ERR "Error reading page; rc = " 379 printk(KERN_ERR "Error reading page; rc = "
335 "[%d]\n", rc); 380 "[%d]\n", rc);
@@ -344,10 +389,7 @@ static int ecryptfs_readpage(struct file *file, struct page *page)
344 goto out; 389 goto out;
345 } 390 }
346 } 391 }
347 SetPageUptodate(page);
348out: 392out:
349 if (rc)
350 ClearPageUptodate(page);
351 ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n", 393 ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
352 page->index); 394 page->index);
353 unlock_page(page); 395 unlock_page(page);
@@ -403,9 +445,12 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
403 goto out; /* If we are writing a full page, it will be 445 goto out; /* If we are writing a full page, it will be
404 up to date. */ 446 up to date. */
405 if (!PageUptodate(page)) 447 if (!PageUptodate(page))
406 rc = ecryptfs_do_readpage(file, page, page->index); 448 rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
449 PAGE_CACHE_SIZE,
450 page->mapping->host);
407 if (page->index != 0) { 451 if (page->index != 0) {
408 loff_t end_of_prev_pg_pos = page_offset(page) - 1; 452 loff_t end_of_prev_pg_pos =
453 (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1);
409 454
410 if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { 455 if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) {
411 rc = ecryptfs_truncate(file->f_path.dentry, 456 rc = ecryptfs_truncate(file->f_path.dentry,
@@ -633,18 +678,11 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
633 unsigned from, unsigned to) 678 unsigned from, unsigned to)
634{ 679{
635 loff_t pos; 680 loff_t pos;
636 struct inode *inode; 681 struct inode *ecryptfs_inode = page->mapping->host;
637 struct inode *lower_inode; 682 struct ecryptfs_crypt_stat *crypt_stat =
638 struct file *lower_file; 683 &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
639 struct ecryptfs_crypt_stat *crypt_stat;
640 int rc; 684 int rc;
641 685
642 inode = page->mapping->host;
643 lower_inode = ecryptfs_inode_to_lower(inode);
644 lower_file = ecryptfs_file_to_lower(file);
645 mutex_lock(&lower_inode->i_mutex);
646 crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)
647 ->crypt_stat;
648 if (crypt_stat->flags & ECRYPTFS_NEW_FILE) { 686 if (crypt_stat->flags & ECRYPTFS_NEW_FILE) {
649 ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " 687 ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in "
650 "crypt_stat at memory location [%p]\n", crypt_stat); 688 "crypt_stat at memory location [%p]\n", crypt_stat);
@@ -654,6 +692,7 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
654 ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" 692 ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
655 "(page w/ index = [0x%.16x], to = [%d])\n", page->index, 693 "(page w/ index = [0x%.16x], to = [%d])\n", page->index,
656 to); 694 to);
695 /* Fills in zeros if 'to' goes beyond inode size */
657 rc = fill_zeros_to_end_of_page(page, to); 696 rc = fill_zeros_to_end_of_page(page, to);
658 if (rc) { 697 if (rc) {
659 ecryptfs_printk(KERN_WARNING, "Error attempting to fill " 698 ecryptfs_printk(KERN_WARNING, "Error attempting to fill "
@@ -667,25 +706,17 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
667 "index [0x%.16x])\n", page->index); 706 "index [0x%.16x])\n", page->index);
668 goto out; 707 goto out;
669 } 708 }
670 inode->i_blocks = lower_inode->i_blocks; 709 pos = (page->index << PAGE_CACHE_SHIFT) + to;
671 pos = page_offset(page) + to; 710 if (pos > i_size_read(ecryptfs_inode)) {
672 if (pos > i_size_read(inode)) { 711 i_size_write(ecryptfs_inode, pos);
673 i_size_write(inode, pos);
674 ecryptfs_printk(KERN_DEBUG, "Expanded file size to " 712 ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
675 "[0x%.16x]\n", i_size_read(inode)); 713 "[0x%.16x]\n", i_size_read(ecryptfs_inode));
676 } 714 }
677 rc = ecryptfs_write_inode_size_to_metadata(inode); 715 rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
678 if (rc) 716 if (rc)
679 printk(KERN_ERR "Error writing inode size to metadata; " 717 printk(KERN_ERR "Error writing inode size to metadata; "
680 "rc = [%d]\n", rc); 718 "rc = [%d]\n", rc);
681 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
682 mark_inode_dirty_sync(inode);
683out: 719out:
684 if (rc < 0)
685 ClearPageUptodate(page);
686 else
687 SetPageUptodate(page);
688 mutex_unlock(&lower_inode->i_mutex);
689 return rc; 720 return rc;
690} 721}
691 722
@@ -751,34 +782,10 @@ static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block)
751 return rc; 782 return rc;
752} 783}
753 784
754static void ecryptfs_sync_page(struct page *page)
755{
756 struct inode *inode;
757 struct inode *lower_inode;
758 struct page *lower_page;
759
760 inode = page->mapping->host;
761 lower_inode = ecryptfs_inode_to_lower(inode);
762 /* NOTE: Recently swapped with grab_cache_page(), since
763 * sync_page() just makes sure that pending I/O gets done. */
764 lower_page = find_lock_page(lower_inode->i_mapping, page->index);
765 if (!lower_page) {
766 ecryptfs_printk(KERN_DEBUG, "find_lock_page failed\n");
767 return;
768 }
769 if (lower_page->mapping->a_ops->sync_page)
770 lower_page->mapping->a_ops->sync_page(lower_page);
771 ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
772 lower_page->index);
773 unlock_page(lower_page);
774 page_cache_release(lower_page);
775}
776
777struct address_space_operations ecryptfs_aops = { 785struct address_space_operations ecryptfs_aops = {
778 .writepage = ecryptfs_writepage, 786 .writepage = ecryptfs_writepage,
779 .readpage = ecryptfs_readpage, 787 .readpage = ecryptfs_readpage,
780 .prepare_write = ecryptfs_prepare_write, 788 .prepare_write = ecryptfs_prepare_write,
781 .commit_write = ecryptfs_commit_write, 789 .commit_write = ecryptfs_commit_write,
782 .bmap = ecryptfs_bmap, 790 .bmap = ecryptfs_bmap,
783 .sync_page = ecryptfs_sync_page,
784}; 791};