aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2010-07-02 20:20:27 -0400
committerJoel Becker <joel.becker@oracle.com>2010-07-12 16:55:27 -0400
commit693c241a5f6aa01417f5f4caf9f82e60e316398d (patch)
tree4d3509db621c7af934332c433e62b49bb548a60b /fs/ocfs2/aops.c
parent5693486bad2bc2ac585a2c24f7e2f3964b478df9 (diff)
ocfs2: No need to zero pages past i_size.
When ocfs2 fills a hole, it does so by allocating clusters. When a cluster is larger than the write, ocfs2 must zero the portions of the cluster outside of the write. If the clustersize is smaller than a pagecache page, this is handled by the normal pagecache mechanisms, but when the clustersize is larger than a page, ocfs2's write code will zero the pages adjacent to the write. This makes sure the entire cluster is zeroed correctly. Currently ocfs2 behaves exactly the same when writing past i_size. However, this means ocfs2 is writing zeroed pages for portions of a new cluster that are beyond i_size. The page writeback code isn't expecting this. It treats all pages past the one containing i_size as left behind due to a previous truncate operation. Thankfully, ocfs2 calculates the number of pages it will be working on up front. The rest of the write code merely honors the original calculation. We can simply trim the number of pages to only cover the actual file data. Signed-off-by: Joel Becker <joel.becker@oracle.com> Cc: stable@kernel.org
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r--fs/ocfs2/aops.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 742893ea7390..356e976772bf 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1100,23 +1100,37 @@ out:
1100 */ 1100 */
1101static int ocfs2_grab_pages_for_write(struct address_space *mapping, 1101static int ocfs2_grab_pages_for_write(struct address_space *mapping,
1102 struct ocfs2_write_ctxt *wc, 1102 struct ocfs2_write_ctxt *wc,
1103 u32 cpos, loff_t user_pos, int new, 1103 u32 cpos, loff_t user_pos,
1104 unsigned user_len, int new,
1104 struct page *mmap_page) 1105 struct page *mmap_page)
1105{ 1106{
1106 int ret = 0, i; 1107 int ret = 0, i;
1107 unsigned long start, target_index, index; 1108 unsigned long start, target_index, end_index, index;
1108 struct inode *inode = mapping->host; 1109 struct inode *inode = mapping->host;
1110 loff_t last_byte;
1109 1111
1110 target_index = user_pos >> PAGE_CACHE_SHIFT; 1112 target_index = user_pos >> PAGE_CACHE_SHIFT;
1111 1113
1112 /* 1114 /*
1113 * Figure out how many pages we'll be manipulating here. For 1115 * Figure out how many pages we'll be manipulating here. For
1114 * non allocating write, we just change the one 1116 * non allocating write, we just change the one
1115 * page. Otherwise, we'll need a whole clusters worth. 1117 * page. Otherwise, we'll need a whole clusters worth. If we're
1118 * writing past i_size, we only need enough pages to cover the
1119 * last page of the write.
1116 */ 1120 */
1117 if (new) { 1121 if (new) {
1118 wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb); 1122 wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb);
1119 start = ocfs2_align_clusters_to_page_index(inode->i_sb, cpos); 1123 start = ocfs2_align_clusters_to_page_index(inode->i_sb, cpos);
1124 /*
1125 * We need the index *past* the last page we could possibly
1126 * touch. This is the page past the end of the write or
1127 * i_size, whichever is greater.
1128 */
1129 last_byte = max(user_pos + user_len, i_size_read(inode));
1130 BUG_ON(last_byte < 1);
1131 end_index = ((last_byte - 1) >> PAGE_CACHE_SHIFT) + 1;
1132 if ((start + wc->w_num_pages) > end_index)
1133 wc->w_num_pages = end_index - start;
1120 } else { 1134 } else {
1121 wc->w_num_pages = 1; 1135 wc->w_num_pages = 1;
1122 start = target_index; 1136 start = target_index;
@@ -1773,7 +1787,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
1773 * that we can zero and flush if we error after adding the 1787 * that we can zero and flush if we error after adding the
1774 * extent. 1788 * extent.
1775 */ 1789 */
1776 ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, 1790 ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
1777 cluster_of_pages, mmap_page); 1791 cluster_of_pages, mmap_page);
1778 if (ret) { 1792 if (ret) {
1779 mlog_errno(ret); 1793 mlog_errno(ret);