aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-02-28 23:12:16 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-01 17:53:37 -0500
commitae73fc093a8cae4d92e22ab8b635e3590e80785d (patch)
treed593f88dd5ab406bc785b7acaf137d7fb67d07b2 /fs
parent05fb6bf0b29552b64dc86f405a484de2514e0ac2 (diff)
[PATCH] eCryptfs: resolve lower page unlocking problem
eCryptfs lower file handling code has several issues: - Retval from prepare_write()/commit_write() wasn't checked to equality to AOP_TRUNCATED_PAGE. - In some places page wasn't unmapped and unlocked after error. 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')
-rw-r--r--fs/ecryptfs/mmap.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index 3a6f65c3f14f..82bdbed658d7 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -422,9 +422,11 @@ out:
422 return rc; 422 return rc;
423} 423}
424 424
425static void ecryptfs_release_lower_page(struct page *lower_page) 425static
426void ecryptfs_release_lower_page(struct page *lower_page, int page_locked)
426{ 427{
427 unlock_page(lower_page); 428 if (page_locked)
429 unlock_page(lower_page);
428 page_cache_release(lower_page); 430 page_cache_release(lower_page);
429} 431}
430 432
@@ -454,6 +456,13 @@ 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 else
463 ecryptfs_release_lower_page(header_page, 1);
464 goto out;
465 }
457 file_size = (u64)i_size_read(inode); 466 file_size = (u64)i_size_read(inode);
458 ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size); 467 ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size);
459 file_size = cpu_to_be64(file_size); 468 file_size = cpu_to_be64(file_size);
@@ -465,7 +474,10 @@ static int ecryptfs_write_inode_size_to_header(struct file *lower_file,
465 if (rc < 0) 474 if (rc < 0)
466 ecryptfs_printk(KERN_ERR, "Error commiting header page " 475 ecryptfs_printk(KERN_ERR, "Error commiting header page "
467 "write\n"); 476 "write\n");
468 ecryptfs_release_lower_page(header_page); 477 if (rc == AOP_TRUNCATED_PAGE)
478 ecryptfs_release_lower_page(header_page, 0);
479 else
480 ecryptfs_release_lower_page(header_page, 1);
469 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; 481 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
470 mark_inode_dirty_sync(inode); 482 mark_inode_dirty_sync(inode);
471out: 483out:
@@ -572,7 +584,10 @@ int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
572 } 584 }
573out: 585out:
574 if (rc && (*lower_page)) { 586 if (rc && (*lower_page)) {
575 ecryptfs_release_lower_page(*lower_page); 587 if (rc == AOP_TRUNCATED_PAGE)
588 ecryptfs_release_lower_page(*lower_page, 0);
589 else
590 ecryptfs_release_lower_page(*lower_page, 1);
576 (*lower_page) = NULL; 591 (*lower_page) = NULL;
577 } 592 }
578 return rc; 593 return rc;
@@ -588,16 +603,19 @@ ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
588 struct file *lower_file, int byte_offset, 603 struct file *lower_file, int byte_offset,
589 int region_size) 604 int region_size)
590{ 605{
606 int page_locked = 1;
591 int rc = 0; 607 int rc = 0;
592 608
593 rc = lower_inode->i_mapping->a_ops->commit_write( 609 rc = lower_inode->i_mapping->a_ops->commit_write(
594 lower_file, lower_page, byte_offset, region_size); 610 lower_file, lower_page, byte_offset, region_size);
611 if (rc == AOP_TRUNCATED_PAGE)
612 page_locked = 0;
595 if (rc < 0) { 613 if (rc < 0) {
596 ecryptfs_printk(KERN_ERR, 614 ecryptfs_printk(KERN_ERR,
597 "Error committing write; rc = [%d]\n", rc); 615 "Error committing write; rc = [%d]\n", rc);
598 } else 616 } else
599 rc = 0; 617 rc = 0;
600 ecryptfs_release_lower_page(lower_page); 618 ecryptfs_release_lower_page(lower_page, page_locked);
601 return rc; 619 return rc;
602} 620}
603 621