diff options
Diffstat (limited to 'fs/ecryptfs/mmap.c')
-rw-r--r-- | fs/ecryptfs/mmap.c | 131 |
1 files changed, 41 insertions, 90 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 0c53320b9eb8..9b621108d5c1 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -171,13 +171,9 @@ out: | |||
171 | */ | 171 | */ |
172 | static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) | 172 | static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) |
173 | { | 173 | { |
174 | struct ecryptfs_page_crypt_context ctx; | ||
175 | int rc; | 174 | int rc; |
176 | 175 | ||
177 | ctx.page = page; | 176 | rc = ecryptfs_encrypt_page(page); |
178 | ctx.mode = ECRYPTFS_WRITEPAGE_MODE; | ||
179 | ctx.param.wbc = wbc; | ||
180 | rc = ecryptfs_encrypt_page(&ctx); | ||
181 | if (rc) { | 177 | if (rc) { |
182 | ecryptfs_printk(KERN_WARNING, "Error encrypting " | 178 | ecryptfs_printk(KERN_WARNING, "Error encrypting " |
183 | "page (upper index [0x%.16x])\n", page->index); | 179 | "page (upper index [0x%.16x])\n", page->index); |
@@ -341,7 +337,7 @@ static int ecryptfs_readpage(struct file *file, struct page *page) | |||
341 | } | 337 | } |
342 | } | 338 | } |
343 | } else { | 339 | } else { |
344 | rc = ecryptfs_decrypt_page(file, page); | 340 | rc = ecryptfs_decrypt_page(page); |
345 | if (rc) { | 341 | if (rc) { |
346 | ecryptfs_printk(KERN_ERR, "Error decrypting page; " | 342 | ecryptfs_printk(KERN_ERR, "Error decrypting page; " |
347 | "rc = [%d]\n", rc); | 343 | "rc = [%d]\n", rc); |
@@ -459,58 +455,48 @@ static void ecryptfs_release_lower_page(struct page *lower_page) | |||
459 | * | 455 | * |
460 | * Returns zero on success; non-zero on error. | 456 | * Returns zero on success; non-zero on error. |
461 | */ | 457 | */ |
462 | static int ecryptfs_write_inode_size_to_header(struct file *lower_file, | 458 | static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode) |
463 | struct inode *lower_inode, | ||
464 | struct inode *inode) | ||
465 | { | 459 | { |
466 | int rc = 0; | ||
467 | struct page *header_page; | ||
468 | char *header_virt; | ||
469 | const struct address_space_operations *lower_a_ops; | ||
470 | u64 file_size; | 460 | u64 file_size; |
461 | char *file_size_virt; | ||
462 | int rc; | ||
471 | 463 | ||
472 | header_page = grab_cache_page(lower_inode->i_mapping, 0); | 464 | file_size_virt = kmalloc(sizeof(u64), GFP_KERNEL); |
473 | if (!header_page) { | 465 | if (!file_size_virt) { |
474 | ecryptfs_printk(KERN_ERR, "grab_cache_page for " | 466 | rc = -ENOMEM; |
475 | "lower_page_index 0 failed\n"); | ||
476 | rc = -EINVAL; | ||
477 | goto out; | ||
478 | } | ||
479 | lower_a_ops = lower_inode->i_mapping->a_ops; | ||
480 | rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8); | ||
481 | if (rc) { | ||
482 | ecryptfs_release_lower_page(header_page); | ||
483 | goto out; | 467 | goto out; |
484 | } | 468 | } |
485 | file_size = (u64)i_size_read(inode); | 469 | file_size = (u64)i_size_read(ecryptfs_inode); |
486 | ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size); | ||
487 | file_size = cpu_to_be64(file_size); | 470 | file_size = cpu_to_be64(file_size); |
488 | header_virt = kmap_atomic(header_page, KM_USER0); | 471 | memcpy(file_size_virt, &file_size, sizeof(u64)); |
489 | memcpy(header_virt, &file_size, sizeof(u64)); | 472 | rc = ecryptfs_write_lower(ecryptfs_inode, file_size_virt, 0, |
490 | kunmap_atomic(header_virt, KM_USER0); | 473 | sizeof(u64)); |
491 | flush_dcache_page(header_page); | 474 | kfree(file_size_virt); |
492 | rc = lower_a_ops->commit_write(lower_file, header_page, 0, 8); | 475 | if (rc) |
493 | if (rc < 0) | 476 | printk(KERN_ERR "%s: Error writing file size to header; " |
494 | ecryptfs_printk(KERN_ERR, "Error commiting header page " | 477 | "rc = [%d]\n", __FUNCTION__, rc); |
495 | "write\n"); | ||
496 | ecryptfs_release_lower_page(header_page); | ||
497 | lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; | ||
498 | mark_inode_dirty_sync(inode); | ||
499 | out: | 478 | out: |
500 | return rc; | 479 | return rc; |
501 | } | 480 | } |
502 | 481 | ||
503 | static int ecryptfs_write_inode_size_to_xattr(struct inode *lower_inode, | 482 | struct kmem_cache *ecryptfs_xattr_cache; |
504 | struct inode *inode, | 483 | |
505 | struct dentry *ecryptfs_dentry, | 484 | static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode) |
506 | int lower_i_mutex_held) | ||
507 | { | 485 | { |
508 | ssize_t size; | 486 | ssize_t size; |
509 | void *xattr_virt; | 487 | void *xattr_virt; |
510 | struct dentry *lower_dentry; | 488 | struct dentry *lower_dentry = |
489 | ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry; | ||
490 | struct inode *lower_inode = lower_dentry->d_inode; | ||
511 | u64 file_size; | 491 | u64 file_size; |
512 | int rc; | 492 | int rc; |
513 | 493 | ||
494 | if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) { | ||
495 | printk(KERN_WARNING | ||
496 | "No support for setting xattr in lower filesystem\n"); | ||
497 | rc = -ENOSYS; | ||
498 | goto out; | ||
499 | } | ||
514 | xattr_virt = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL); | 500 | xattr_virt = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL); |
515 | if (!xattr_virt) { | 501 | if (!xattr_virt) { |
516 | printk(KERN_ERR "Out of memory whilst attempting to write " | 502 | printk(KERN_ERR "Out of memory whilst attempting to write " |
@@ -518,35 +504,17 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *lower_inode, | |||
518 | rc = -ENOMEM; | 504 | rc = -ENOMEM; |
519 | goto out; | 505 | goto out; |
520 | } | 506 | } |
521 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 507 | mutex_lock(&lower_inode->i_mutex); |
522 | if (!lower_dentry->d_inode->i_op->getxattr || | 508 | size = lower_inode->i_op->getxattr(lower_dentry, ECRYPTFS_XATTR_NAME, |
523 | !lower_dentry->d_inode->i_op->setxattr) { | 509 | xattr_virt, PAGE_CACHE_SIZE); |
524 | printk(KERN_WARNING | ||
525 | "No support for setting xattr in lower filesystem\n"); | ||
526 | rc = -ENOSYS; | ||
527 | kmem_cache_free(ecryptfs_xattr_cache, xattr_virt); | ||
528 | goto out; | ||
529 | } | ||
530 | if (!lower_i_mutex_held) | ||
531 | mutex_lock(&lower_dentry->d_inode->i_mutex); | ||
532 | size = lower_dentry->d_inode->i_op->getxattr(lower_dentry, | ||
533 | ECRYPTFS_XATTR_NAME, | ||
534 | xattr_virt, | ||
535 | PAGE_CACHE_SIZE); | ||
536 | if (!lower_i_mutex_held) | ||
537 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
538 | if (size < 0) | 510 | if (size < 0) |
539 | size = 8; | 511 | size = 8; |
540 | file_size = (u64)i_size_read(inode); | 512 | file_size = (u64)i_size_read(ecryptfs_inode); |
541 | file_size = cpu_to_be64(file_size); | 513 | file_size = cpu_to_be64(file_size); |
542 | memcpy(xattr_virt, &file_size, sizeof(u64)); | 514 | memcpy(xattr_virt, &file_size, sizeof(u64)); |
543 | if (!lower_i_mutex_held) | 515 | rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME, |
544 | mutex_lock(&lower_dentry->d_inode->i_mutex); | 516 | xattr_virt, size, 0); |
545 | rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry, | 517 | mutex_unlock(&lower_inode->i_mutex); |
546 | ECRYPTFS_XATTR_NAME, | ||
547 | xattr_virt, size, 0); | ||
548 | if (!lower_i_mutex_held) | ||
549 | mutex_unlock(&lower_dentry->d_inode->i_mutex); | ||
550 | if (rc) | 518 | if (rc) |
551 | printk(KERN_ERR "Error whilst attempting to write inode size " | 519 | printk(KERN_ERR "Error whilst attempting to write inode size " |
552 | "to lower file xattr; rc = [%d]\n", rc); | 520 | "to lower file xattr; rc = [%d]\n", rc); |
@@ -555,24 +523,15 @@ out: | |||
555 | return rc; | 523 | return rc; |
556 | } | 524 | } |
557 | 525 | ||
558 | int | 526 | int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode) |
559 | ecryptfs_write_inode_size_to_metadata(struct file *lower_file, | ||
560 | struct inode *lower_inode, | ||
561 | struct inode *inode, | ||
562 | struct dentry *ecryptfs_dentry, | ||
563 | int lower_i_mutex_held) | ||
564 | { | 527 | { |
565 | struct ecryptfs_crypt_stat *crypt_stat; | 528 | struct ecryptfs_crypt_stat *crypt_stat; |
566 | 529 | ||
567 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | 530 | crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
568 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 531 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
569 | return ecryptfs_write_inode_size_to_xattr(lower_inode, inode, | 532 | return ecryptfs_write_inode_size_to_xattr(ecryptfs_inode); |
570 | ecryptfs_dentry, | ||
571 | lower_i_mutex_held); | ||
572 | else | 533 | else |
573 | return ecryptfs_write_inode_size_to_header(lower_file, | 534 | return ecryptfs_write_inode_size_to_header(ecryptfs_inode); |
574 | lower_inode, | ||
575 | inode); | ||
576 | } | 535 | } |
577 | 536 | ||
578 | int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, | 537 | int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode, |
@@ -659,8 +618,6 @@ out: | |||
659 | return rc; | 618 | return rc; |
660 | } | 619 | } |
661 | 620 | ||
662 | struct kmem_cache *ecryptfs_xattr_cache; | ||
663 | |||
664 | /** | 621 | /** |
665 | * ecryptfs_commit_write | 622 | * ecryptfs_commit_write |
666 | * @file: The eCryptfs file object | 623 | * @file: The eCryptfs file object |
@@ -675,7 +632,6 @@ struct kmem_cache *ecryptfs_xattr_cache; | |||
675 | static int ecryptfs_commit_write(struct file *file, struct page *page, | 632 | static int ecryptfs_commit_write(struct file *file, struct page *page, |
676 | unsigned from, unsigned to) | 633 | unsigned from, unsigned to) |
677 | { | 634 | { |
678 | struct ecryptfs_page_crypt_context ctx; | ||
679 | loff_t pos; | 635 | loff_t pos; |
680 | struct inode *inode; | 636 | struct inode *inode; |
681 | struct inode *lower_inode; | 637 | struct inode *lower_inode; |
@@ -705,10 +661,7 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, | |||
705 | page->index); | 661 | page->index); |
706 | goto out; | 662 | goto out; |
707 | } | 663 | } |
708 | ctx.page = page; | 664 | rc = ecryptfs_encrypt_page(page); |
709 | ctx.mode = ECRYPTFS_PREPARE_COMMIT_MODE; | ||
710 | ctx.param.lower_file = lower_file; | ||
711 | rc = ecryptfs_encrypt_page(&ctx); | ||
712 | if (rc) { | 665 | if (rc) { |
713 | ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " | 666 | ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " |
714 | "index [0x%.16x])\n", page->index); | 667 | "index [0x%.16x])\n", page->index); |
@@ -721,9 +674,7 @@ static int ecryptfs_commit_write(struct file *file, struct page *page, | |||
721 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " | 674 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " |
722 | "[0x%.16x]\n", i_size_read(inode)); | 675 | "[0x%.16x]\n", i_size_read(inode)); |
723 | } | 676 | } |
724 | rc = ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode, | 677 | rc = ecryptfs_write_inode_size_to_metadata(inode); |
725 | inode, file->f_dentry, | ||
726 | ECRYPTFS_LOWER_I_MUTEX_HELD); | ||
727 | if (rc) | 678 | if (rc) |
728 | printk(KERN_ERR "Error writing inode size to metadata; " | 679 | printk(KERN_ERR "Error writing inode size to metadata; " |
729 | "rc = [%d]\n", rc); | 680 | "rc = [%d]\n", rc); |