aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorYongqiang Yang <xiaoqiangnk@gmail.com>2011-12-13 22:05:05 -0500
committerTheodore Ts'o <tytso@mit.edu>2011-12-13 22:05:05 -0500
commit093e6e3666f47d29763a235b404c84ee47ba8bb0 (patch)
treea337f1415bf1c98b63fa5536c42b97059309b8d1 /fs
parent13a79a4741d37fda2fbafb953f0f301dc007928f (diff)
ext4: correctly handle pages w/o buffers in ext4_discard_partial_buffers()
If a page has been read into memory and never been written, it has no buffers, but we should handle the page in truncate or punch hole. VFS code of writing operations has handled holes correctly, so this patch removes the code handling holes in writing operations. Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: stable@kernel.org
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/inode.c41
1 files changed, 2 insertions, 39 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index cf20e1fe7782..92655fd89657 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2390,7 +2390,6 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping,
2390 pgoff_t index; 2390 pgoff_t index;
2391 struct inode *inode = mapping->host; 2391 struct inode *inode = mapping->host;
2392 handle_t *handle; 2392 handle_t *handle;
2393 loff_t page_len;
2394 2393
2395 index = pos >> PAGE_CACHE_SHIFT; 2394 index = pos >> PAGE_CACHE_SHIFT;
2396 2395
@@ -2437,13 +2436,6 @@ retry:
2437 */ 2436 */
2438 if (pos + len > inode->i_size) 2437 if (pos + len > inode->i_size)
2439 ext4_truncate_failed_write(inode); 2438 ext4_truncate_failed_write(inode);
2440 } else {
2441 page_len = pos & (PAGE_CACHE_SIZE - 1);
2442 if (page_len > 0) {
2443 ret = ext4_discard_partial_page_buffers_no_lock(handle,
2444 inode, page, pos - page_len, page_len,
2445 EXT4_DISCARD_PARTIAL_PG_ZERO_UNMAPPED);
2446 }
2447 } 2439 }
2448 2440
2449 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) 2441 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
@@ -2486,7 +2478,6 @@ static int ext4_da_write_end(struct file *file,
2486 loff_t new_i_size; 2478 loff_t new_i_size;
2487 unsigned long start, end; 2479 unsigned long start, end;
2488 int write_mode = (int)(unsigned long)fsdata; 2480 int write_mode = (int)(unsigned long)fsdata;
2489 loff_t page_len;
2490 2481
2491 if (write_mode == FALL_BACK_TO_NONDELALLOC) { 2482 if (write_mode == FALL_BACK_TO_NONDELALLOC) {
2492 if (ext4_should_order_data(inode)) { 2483 if (ext4_should_order_data(inode)) {
@@ -2535,16 +2526,6 @@ static int ext4_da_write_end(struct file *file,
2535 } 2526 }
2536 ret2 = generic_write_end(file, mapping, pos, len, copied, 2527 ret2 = generic_write_end(file, mapping, pos, len, copied,
2537 page, fsdata); 2528 page, fsdata);
2538
2539 page_len = PAGE_CACHE_SIZE -
2540 ((pos + copied - 1) & (PAGE_CACHE_SIZE - 1));
2541
2542 if (page_len > 0) {
2543 ret = ext4_discard_partial_page_buffers_no_lock(handle,
2544 inode, page, pos + copied - 1, page_len,
2545 EXT4_DISCARD_PARTIAL_PG_ZERO_UNMAPPED);
2546 }
2547
2548 copied = ret2; 2529 copied = ret2;
2549 if (ret2 < 0) 2530 if (ret2 < 0)
2550 ret = ret2; 2531 ret = ret2;
@@ -3206,26 +3187,8 @@ int ext4_discard_partial_page_buffers_no_lock(handle_t *handle,
3206 3187
3207 iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); 3188 iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
3208 3189
3209 if (!page_has_buffers(page)) { 3190 if (!page_has_buffers(page))
3210 /* 3191 create_empty_buffers(page, blocksize, 0);
3211 * If the range to be discarded covers a partial block
3212 * we need to get the page buffers. This is because
3213 * partial blocks cannot be released and the page needs
3214 * to be updated with the contents of the block before
3215 * we write the zeros on top of it.
3216 */
3217 if ((from & (blocksize - 1)) ||
3218 ((from + length) & (blocksize - 1))) {
3219 create_empty_buffers(page, blocksize, 0);
3220 } else {
3221 /*
3222 * If there are no partial blocks,
3223 * there is nothing to update,
3224 * so we can return now
3225 */
3226 return 0;
3227 }
3228 }
3229 3192
3230 /* Find the buffer that contains "offset" */ 3193 /* Find the buffer that contains "offset" */
3231 bh = page_buffers(page); 3194 bh = page_buffers(page);