aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/mmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ecryptfs/mmap.c')
-rw-r--r--fs/ecryptfs/mmap.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 3a6f65c3f14f..b731b09499cb 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -238,7 +238,6 @@ int ecryptfs_do_readpage(struct file *file, struct page *page,
238 lower_page_data = kmap_atomic(lower_page, KM_USER1); 238 lower_page_data = kmap_atomic(lower_page, KM_USER1);
239 memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE); 239 memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE);
240 kunmap_atomic(lower_page_data, KM_USER1); 240 kunmap_atomic(lower_page_data, KM_USER1);
241 flush_dcache_page(lower_page);
242 kunmap_atomic(page_data, KM_USER0); 241 kunmap_atomic(page_data, KM_USER0);
243 flush_dcache_page(page); 242 flush_dcache_page(page);
244 rc = 0; 243 rc = 0;
@@ -422,9 +421,11 @@ out:
422 return rc; 421 return rc;
423} 422}
424 423
425static void ecryptfs_release_lower_page(struct page *lower_page) 424static
425void ecryptfs_release_lower_page(struct page *lower_page, int page_locked)
426{ 426{
427 unlock_page(lower_page); 427 if (page_locked)
428 unlock_page(lower_page);
428 page_cache_release(lower_page); 429 page_cache_release(lower_page);
429} 430}
430 431
@@ -445,6 +446,7 @@ static int ecryptfs_write_inode_size_to_header(struct file *lower_file,
445 const struct address_space_operations *lower_a_ops; 446 const struct address_space_operations *lower_a_ops;
446 u64 file_size; 447 u64 file_size;
447 448
449retry:
448 header_page = grab_cache_page(lower_inode->i_mapping, 0); 450 header_page = grab_cache_page(lower_inode->i_mapping, 0);
449 if (!header_page) { 451 if (!header_page) {
450 ecryptfs_printk(KERN_ERR, "grab_cache_page for " 452 ecryptfs_printk(KERN_ERR, "grab_cache_page for "
@@ -454,6 +456,14 @@ static int ecryptfs_write_inode_size_to_header(struct file *lower_file,
454 } 456 }
455 lower_a_ops = lower_inode->i_mapping->a_ops; 457 lower_a_ops = lower_inode->i_mapping->a_ops;
456 rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8); 458 rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8);
459 if (rc) {
460 if (rc == AOP_TRUNCATED_PAGE) {
461 ecryptfs_release_lower_page(header_page, 0);
462 goto retry;
463 } else
464 ecryptfs_release_lower_page(header_page, 1);
465 goto out;
466 }
457 file_size = (u64)i_size_read(inode); 467 file_size = (u64)i_size_read(inode);
458 ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size); 468 ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size);
459 file_size = cpu_to_be64(file_size); 469 file_size = cpu_to_be64(file_size);
@@ -465,7 +475,11 @@ static int ecryptfs_write_inode_size_to_header(struct file *lower_file,
465 if (rc < 0) 475 if (rc < 0)
466 ecryptfs_printk(KERN_ERR, "Error commiting header page " 476 ecryptfs_printk(KERN_ERR, "Error commiting header page "
467 "write\n"); 477 "write\n");
468 ecryptfs_release_lower_page(header_page); 478 if (rc == AOP_TRUNCATED_PAGE) {
479 ecryptfs_release_lower_page(header_page, 0);
480 goto retry;
481 } else
482 ecryptfs_release_lower_page(header_page, 1);
469 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; 483 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
470 mark_inode_dirty_sync(inode); 484 mark_inode_dirty_sync(inode);
471out: 485out:
@@ -491,7 +505,8 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *lower_inode,
491 goto out; 505 goto out;
492 } 506 }
493 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); 507 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
494 if (!lower_dentry->d_inode->i_op->getxattr) { 508 if (!lower_dentry->d_inode->i_op->getxattr ||
509 !lower_dentry->d_inode->i_op->setxattr) {
495 printk(KERN_WARNING 510 printk(KERN_WARNING
496 "No support for setting xattr in lower filesystem\n"); 511 "No support for setting xattr in lower filesystem\n");
497 rc = -ENOSYS; 512 rc = -ENOSYS;
@@ -553,6 +568,7 @@ int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
553{ 568{
554 int rc = 0; 569 int rc = 0;
555 570
571retry:
556 *lower_page = grab_cache_page(lower_inode->i_mapping, lower_page_index); 572 *lower_page = grab_cache_page(lower_inode->i_mapping, lower_page_index);
557 if (!(*lower_page)) { 573 if (!(*lower_page)) {
558 rc = -EINVAL; 574 rc = -EINVAL;
@@ -566,15 +582,18 @@ int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
566 byte_offset, 582 byte_offset,
567 region_bytes); 583 region_bytes);
568 if (rc) { 584 if (rc) {
569 ecryptfs_printk(KERN_ERR, "prepare_write for " 585 if (rc == AOP_TRUNCATED_PAGE) {
586 ecryptfs_release_lower_page(*lower_page, 0);
587 goto retry;
588 } else {
589 ecryptfs_printk(KERN_ERR, "prepare_write for "
570 "lower_page_index = [0x%.16x] failed; rc = " 590 "lower_page_index = [0x%.16x] failed; rc = "
571 "[%d]\n", lower_page_index, rc); 591 "[%d]\n", lower_page_index, rc);
592 ecryptfs_release_lower_page(*lower_page, 1);
593 (*lower_page) = NULL;
594 }
572 } 595 }
573out: 596out:
574 if (rc && (*lower_page)) {
575 ecryptfs_release_lower_page(*lower_page);
576 (*lower_page) = NULL;
577 }
578 return rc; 597 return rc;
579} 598}
580 599
@@ -588,16 +607,19 @@ ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
588 struct file *lower_file, int byte_offset, 607 struct file *lower_file, int byte_offset,
589 int region_size) 608 int region_size)
590{ 609{
610 int page_locked = 1;
591 int rc = 0; 611 int rc = 0;
592 612
593 rc = lower_inode->i_mapping->a_ops->commit_write( 613 rc = lower_inode->i_mapping->a_ops->commit_write(
594 lower_file, lower_page, byte_offset, region_size); 614 lower_file, lower_page, byte_offset, region_size);
615 if (rc == AOP_TRUNCATED_PAGE)
616 page_locked = 0;
595 if (rc < 0) { 617 if (rc < 0) {
596 ecryptfs_printk(KERN_ERR, 618 ecryptfs_printk(KERN_ERR,
597 "Error committing write; rc = [%d]\n", rc); 619 "Error committing write; rc = [%d]\n", rc);
598 } else 620 } else
599 rc = 0; 621 rc = 0;
600 ecryptfs_release_lower_page(lower_page); 622 ecryptfs_release_lower_page(lower_page, page_locked);
601 return rc; 623 return rc;
602} 624}
603 625