From: Nick Piggin prepare/commit_write no longer returns AOP_TRUNCATED_PAGE since OCFS2 and GFS2 were converted to the new aops, so we can make some simplifications for that. Signed-off-by: Nick Piggin Cc: Michael Halcrow Cc: Mark Fasheh Cc: Steven Whitehouse Signed-off-by: Andrew Morton --- Documentation/filesystems/vfs.txt | 6 ---- fs/ecryptfs/mmap.c | 39 +++++++--------------------- include/linux/fs.h | 2 - mm/filemap.c | 16 ++--------- 4 files changed, 16 insertions(+), 47 deletions(-) diff -puN Documentation/filesystems/vfs.txt~fs-remove-some-aop_truncated_page Documentation/filesystems/vfs.txt --- a/Documentation/filesystems/vfs.txt~fs-remove-some-aop_truncated_page +++ a/Documentation/filesystems/vfs.txt @@ -621,11 +621,7 @@ struct address_space_operations { any basic-blocks on storage, then those blocks should be pre-read (if they haven't been read already) so that the updated blocks can be written out properly. - The page will be locked. If prepare_write wants to unlock the - page it, like readpage, may do so and return - AOP_TRUNCATED_PAGE. - In this case the prepare_write will be retried one the lock is - regained. + The page will be locked. Note: the page _must not_ be marked uptodate in this function (or anywhere else) unless it actually is uptodate right now. As diff -puN fs/ecryptfs/mmap.c~fs-remove-some-aop_truncated_page fs/ecryptfs/mmap.c --- a/fs/ecryptfs/mmap.c~fs-remove-some-aop_truncated_page +++ a/fs/ecryptfs/mmap.c @@ -446,11 +446,9 @@ out: return rc; } -static -void ecryptfs_release_lower_page(struct page *lower_page, int page_locked) +static void ecryptfs_release_lower_page(struct page *lower_page) { - if (page_locked) - unlock_page(lower_page); + unlock_page(lower_page); page_cache_release(lower_page); } @@ -471,7 +469,6 @@ static int ecryptfs_write_inode_size_to_ const struct address_space_operations *lower_a_ops; u64 file_size; -retry: header_page = grab_cache_page(lower_inode->i_mapping, 0); if (!header_page) { ecryptfs_printk(KERN_ERR, "grab_cache_page for " @@ -482,11 +479,7 @@ retry: lower_a_ops = lower_inode->i_mapping->a_ops; rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8); if (rc) { - if (rc == AOP_TRUNCATED_PAGE) { - ecryptfs_release_lower_page(header_page, 0); - goto retry; - } else - ecryptfs_release_lower_page(header_page, 1); + ecryptfs_release_lower_page(header_page); goto out; } file_size = (u64)i_size_read(inode); @@ -500,11 +493,7 @@ retry: if (rc < 0) ecryptfs_printk(KERN_ERR, "Error commiting header page " "write\n"); - if (rc == AOP_TRUNCATED_PAGE) { - ecryptfs_release_lower_page(header_page, 0); - goto retry; - } else - ecryptfs_release_lower_page(header_page, 1); + ecryptfs_release_lower_page(header_page); lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME; mark_inode_dirty_sync(inode); out: @@ -607,16 +596,11 @@ retry: byte_offset, region_bytes); if (rc) { - if (rc == AOP_TRUNCATED_PAGE) { - ecryptfs_release_lower_page(*lower_page, 0); - goto retry; - } else { - ecryptfs_printk(KERN_ERR, "prepare_write for " - "lower_page_index = [0x%.16x] failed; rc = " - "[%d]\n", lower_page_index, rc); - ecryptfs_release_lower_page(*lower_page, 1); - (*lower_page) = NULL; - } + ecryptfs_printk(KERN_ERR, "prepare_write for " + "lower_page_index = [0x%.16x] failed; rc = " + "[%d]\n", lower_page_index, rc); + ecryptfs_release_lower_page(*lower_page); + (*lower_page) = NULL; } out: return rc; @@ -632,19 +616,16 @@ ecryptfs_commit_lower_page(struct page * struct file *lower_file, int byte_offset, int region_size) { - int page_locked = 1; int rc = 0; rc = lower_inode->i_mapping->a_ops->commit_write( lower_file, lower_page, byte_offset, region_size); - if (rc == AOP_TRUNCATED_PAGE) - page_locked = 0; if (rc < 0) { ecryptfs_printk(KERN_ERR, "Error committing write; rc = [%d]\n", rc); } else rc = 0; - ecryptfs_release_lower_page(lower_page, page_locked); + ecryptfs_release_lower_page(lower_page); return rc; } diff -puN include/linux/fs.h~fs-remove-some-aop_truncated_page include/linux/fs.h --- a/include/linux/fs.h~fs-remove-some-aop_truncated_page +++ a/include/linux/fs.h @@ -381,7 +381,7 @@ struct iattr { * trying again. The aop will be taking reasonable * precautions not to livelock. If the caller held a page * reference, it should drop it before retrying. Returned - * by readpage(), prepare_write(), and commit_write(). + * by readpage(). * * address_space_operation functions return these large constants to indicate * special semantics to the caller. These are much larger than the bytes in a diff -puN mm/filemap.c~fs-remove-some-aop_truncated_page mm/filemap.c --- a/mm/filemap.c~fs-remove-some-aop_truncated_page +++ a/mm/filemap.c @@ -1917,13 +1917,10 @@ again: ret = aops->prepare_write(file, page, offset, offset+len); if (ret) { - if (ret != AOP_TRUNCATED_PAGE) - unlock_page(page); + unlock_page(page); page_cache_release(page); if (pos + len > inode->i_size) vmtruncate(inode, inode->i_size); - if (ret == AOP_TRUNCATED_PAGE) - goto again; } return ret; } @@ -1948,7 +1945,6 @@ int pagecache_write_end(struct file *fil ret = aops->commit_write(file, page, offset, offset+len); unlock_page(page); page_cache_release(page); - BUG_ON(ret == AOP_TRUNCATED_PAGE); /* can't deal with */ if (ret < 0) { if (pos + len > inode->i_size) @@ -2159,7 +2155,7 @@ static ssize_t generic_perform_write_2co flush_dcache_page(page); status = a_ops->commit_write(file, page, offset, offset+bytes); - if (unlikely(status < 0 || status == AOP_TRUNCATED_PAGE)) + if (unlikely(status < 0)) goto fs_write_aop_error; if (unlikely(status > 0)) /* filesystem did partial write */ copied = min_t(size_t, copied, status); @@ -2179,8 +2175,7 @@ static ssize_t generic_perform_write_2co continue; fs_write_aop_error: - if (status != AOP_TRUNCATED_PAGE) - unlock_page(page); + unlock_page(page); page_cache_release(page); if (src_page) page_cache_release(src_page); @@ -2192,10 +2187,7 @@ fs_write_aop_error: */ if (pos + bytes > inode->i_size) vmtruncate(inode, inode->i_size); - if (status == AOP_TRUNCATED_PAGE) - continue; - else - break; + break; } while (iov_iter_count(i)); return written ? written : status; _