aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/vfs.txt6
-rw-r--r--fs/ecryptfs/mmap.c40
-rw-r--r--include/linux/fs.h2
-rw-r--r--mm/filemap.c16
4 files changed, 16 insertions, 48 deletions
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 281c19ff7f45..6f8e16e3d6c0 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -621,11 +621,7 @@ struct address_space_operations {
621 any basic-blocks on storage, then those blocks should be 621 any basic-blocks on storage, then those blocks should be
622 pre-read (if they haven't been read already) so that the 622 pre-read (if they haven't been read already) so that the
623 updated blocks can be written out properly. 623 updated blocks can be written out properly.
624 The page will be locked. If prepare_write wants to unlock the 624 The page will be locked.
625 page it, like readpage, may do so and return
626 AOP_TRUNCATED_PAGE.
627 In this case the prepare_write will be retried one the lock is
628 regained.
629 625
630 Note: the page _must not_ be marked uptodate in this function 626 Note: the page _must not_ be marked uptodate in this function
631 (or anywhere else) unless it actually is uptodate right now. As 627 (or anywhere else) unless it actually is uptodate right now. As
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index fd3f94d4a668..aaea55a61ea1 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -446,11 +446,9 @@ out:
446 return rc; 446 return rc;
447} 447}
448 448
449static 449static void ecryptfs_release_lower_page(struct page *lower_page)
450void ecryptfs_release_lower_page(struct page *lower_page, int page_locked)
451{ 450{
452 if (page_locked) 451 unlock_page(lower_page);
453 unlock_page(lower_page);
454 page_cache_release(lower_page); 452 page_cache_release(lower_page);
455} 453}
456 454
@@ -471,7 +469,6 @@ static int ecryptfs_write_inode_size_to_header(struct file *lower_file,
471 const struct address_space_operations *lower_a_ops; 469 const struct address_space_operations *lower_a_ops;
472 u64 file_size; 470 u64 file_size;
473 471
474retry:
475 header_page = grab_cache_page(lower_inode->i_mapping, 0); 472 header_page = grab_cache_page(lower_inode->i_mapping, 0);
476 if (!header_page) { 473 if (!header_page) {
477 ecryptfs_printk(KERN_ERR, "grab_cache_page for " 474 ecryptfs_printk(KERN_ERR, "grab_cache_page for "
@@ -482,11 +479,7 @@ retry:
482 lower_a_ops = lower_inode->i_mapping->a_ops; 479 lower_a_ops = lower_inode->i_mapping->a_ops;
483 rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8); 480 rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8);
484 if (rc) { 481 if (rc) {
485 if (rc == AOP_TRUNCATED_PAGE) { 482 ecryptfs_release_lower_page(header_page);
486 ecryptfs_release_lower_page(header_page, 0);
487 goto retry;
488 } else
489 ecryptfs_release_lower_page(header_page, 1);
490 goto out; 483 goto out;
491 } 484 }
492 file_size = (u64)i_size_read(inode); 485 file_size = (u64)i_size_read(inode);
@@ -500,11 +493,7 @@ retry:
500 if (rc < 0) 493 if (rc < 0)
501 ecryptfs_printk(KERN_ERR, "Error commiting header page " 494 ecryptfs_printk(KERN_ERR, "Error commiting header page "
502 "write\n"); 495 "write\n");
503 if (rc == AOP_TRUNCATED_PAGE) { 496 ecryptfs_release_lower_page(header_page);
504 ecryptfs_release_lower_page(header_page, 0);
505 goto retry;
506 } else
507 ecryptfs_release_lower_page(header_page, 1);
508 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; 497 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
509 mark_inode_dirty_sync(inode); 498 mark_inode_dirty_sync(inode);
510out: 499out:
@@ -593,7 +582,6 @@ int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
593{ 582{
594 int rc = 0; 583 int rc = 0;
595 584
596retry:
597 *lower_page = grab_cache_page(lower_inode->i_mapping, lower_page_index); 585 *lower_page = grab_cache_page(lower_inode->i_mapping, lower_page_index);
598 if (!(*lower_page)) { 586 if (!(*lower_page)) {
599 rc = -EINVAL; 587 rc = -EINVAL;
@@ -607,16 +595,11 @@ retry:
607 byte_offset, 595 byte_offset,
608 region_bytes); 596 region_bytes);
609 if (rc) { 597 if (rc) {
610 if (rc == AOP_TRUNCATED_PAGE) { 598 ecryptfs_printk(KERN_ERR, "prepare_write for "
611 ecryptfs_release_lower_page(*lower_page, 0); 599 "lower_page_index = [0x%.16x] failed; rc = "
612 goto retry; 600 "[%d]\n", lower_page_index, rc);
613 } else { 601 ecryptfs_release_lower_page(*lower_page);
614 ecryptfs_printk(KERN_ERR, "prepare_write for " 602 (*lower_page) = NULL;
615 "lower_page_index = [0x%.16x] failed; rc = "
616 "[%d]\n", lower_page_index, rc);
617 ecryptfs_release_lower_page(*lower_page, 1);
618 (*lower_page) = NULL;
619 }
620 } 603 }
621out: 604out:
622 return rc; 605 return rc;
@@ -632,19 +615,16 @@ ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
632 struct file *lower_file, int byte_offset, 615 struct file *lower_file, int byte_offset,
633 int region_size) 616 int region_size)
634{ 617{
635 int page_locked = 1;
636 int rc = 0; 618 int rc = 0;
637 619
638 rc = lower_inode->i_mapping->a_ops->commit_write( 620 rc = lower_inode->i_mapping->a_ops->commit_write(
639 lower_file, lower_page, byte_offset, region_size); 621 lower_file, lower_page, byte_offset, region_size);
640 if (rc == AOP_TRUNCATED_PAGE)
641 page_locked = 0;
642 if (rc < 0) { 622 if (rc < 0) {
643 ecryptfs_printk(KERN_ERR, 623 ecryptfs_printk(KERN_ERR,
644 "Error committing write; rc = [%d]\n", rc); 624 "Error committing write; rc = [%d]\n", rc);
645 } else 625 } else
646 rc = 0; 626 rc = 0;
647 ecryptfs_release_lower_page(lower_page, page_locked); 627 ecryptfs_release_lower_page(lower_page);
648 return rc; 628 return rc;
649} 629}
650 630
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a40557eae2ed..f70d52c46617 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -381,7 +381,7 @@ struct iattr {
381 * trying again. The aop will be taking reasonable 381 * trying again. The aop will be taking reasonable
382 * precautions not to livelock. If the caller held a page 382 * precautions not to livelock. If the caller held a page
383 * reference, it should drop it before retrying. Returned 383 * reference, it should drop it before retrying. Returned
384 * by readpage(), prepare_write(), and commit_write(). 384 * by readpage().
385 * 385 *
386 * address_space_operation functions return these large constants to indicate 386 * address_space_operation functions return these large constants to indicate
387 * special semantics to the caller. These are much larger than the bytes in a 387 * special semantics to the caller. These are much larger than the bytes in a
diff --git a/mm/filemap.c b/mm/filemap.c
index 195339b27e9a..c6049e947cd9 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1898,13 +1898,10 @@ again:
1898 1898
1899 ret = aops->prepare_write(file, page, offset, offset+len); 1899 ret = aops->prepare_write(file, page, offset, offset+len);
1900 if (ret) { 1900 if (ret) {
1901 if (ret != AOP_TRUNCATED_PAGE) 1901 unlock_page(page);
1902 unlock_page(page);
1903 page_cache_release(page); 1902 page_cache_release(page);
1904 if (pos + len > inode->i_size) 1903 if (pos + len > inode->i_size)
1905 vmtruncate(inode, inode->i_size); 1904 vmtruncate(inode, inode->i_size);
1906 if (ret == AOP_TRUNCATED_PAGE)
1907 goto again;
1908 } 1905 }
1909 return ret; 1906 return ret;
1910 } 1907 }
@@ -1931,7 +1928,6 @@ int pagecache_write_end(struct file *file, struct address_space *mapping,
1931 unlock_page(page); 1928 unlock_page(page);
1932 mark_page_accessed(page); 1929 mark_page_accessed(page);
1933 page_cache_release(page); 1930 page_cache_release(page);
1934 BUG_ON(ret == AOP_TRUNCATED_PAGE); /* can't deal with */
1935 1931
1936 if (ret < 0) { 1932 if (ret < 0) {
1937 if (pos + len > inode->i_size) 1933 if (pos + len > inode->i_size)
@@ -2142,7 +2138,7 @@ static ssize_t generic_perform_write_2copy(struct file *file,
2142 flush_dcache_page(page); 2138 flush_dcache_page(page);
2143 2139
2144 status = a_ops->commit_write(file, page, offset, offset+bytes); 2140 status = a_ops->commit_write(file, page, offset, offset+bytes);
2145 if (unlikely(status < 0 || status == AOP_TRUNCATED_PAGE)) 2141 if (unlikely(status < 0))
2146 goto fs_write_aop_error; 2142 goto fs_write_aop_error;
2147 if (unlikely(status > 0)) /* filesystem did partial write */ 2143 if (unlikely(status > 0)) /* filesystem did partial write */
2148 copied = min_t(size_t, copied, status); 2144 copied = min_t(size_t, copied, status);
@@ -2162,8 +2158,7 @@ static ssize_t generic_perform_write_2copy(struct file *file,
2162 continue; 2158 continue;
2163 2159
2164fs_write_aop_error: 2160fs_write_aop_error:
2165 if (status != AOP_TRUNCATED_PAGE) 2161 unlock_page(page);
2166 unlock_page(page);
2167 page_cache_release(page); 2162 page_cache_release(page);
2168 if (src_page) 2163 if (src_page)
2169 page_cache_release(src_page); 2164 page_cache_release(src_page);
@@ -2175,10 +2170,7 @@ fs_write_aop_error:
2175 */ 2170 */
2176 if (pos + bytes > inode->i_size) 2171 if (pos + bytes > inode->i_size)
2177 vmtruncate(inode, inode->i_size); 2172 vmtruncate(inode, inode->i_size);
2178 if (status == AOP_TRUNCATED_PAGE) 2173 break;
2179 continue;
2180 else
2181 break;
2182 } while (iov_iter_count(i)); 2174 } while (iov_iter_count(i));
2183 2175
2184 return written ? written : status; 2176 return written ? written : status;