aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2009-12-17 18:27:06 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-17 18:45:30 -0500
commitec8e2f7466ca370f5e09000ca40a71759afc9ac8 (patch)
tree41c33d2317d9ffb0cc60cdacebf246bc023f8677
parent2bf212b9e48e1c35eaf8f0cc1729d7c4a39b7b5a (diff)
reiserfs: truncate blocks not used by a write
It can happen that write does not use all the blocks allocated in write_begin either because of some filesystem error (like ENOSPC) or because page with data to write has been removed from memory. We truncate these blocks so that we don't have dangling blocks beyond i_size. Cc: Jeff Mahoney <jeffm@suse.com> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/reiserfs/inode.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 3a28e7751b3c..290ae38fca8a 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2538,6 +2538,12 @@ static int reiserfs_writepage(struct page *page, struct writeback_control *wbc)
2538 return reiserfs_write_full_page(page, wbc); 2538 return reiserfs_write_full_page(page, wbc);
2539} 2539}
2540 2540
2541static void reiserfs_truncate_failed_write(struct inode *inode)
2542{
2543 truncate_inode_pages(inode->i_mapping, inode->i_size);
2544 reiserfs_truncate_file(inode, 0);
2545}
2546
2541static int reiserfs_write_begin(struct file *file, 2547static int reiserfs_write_begin(struct file *file,
2542 struct address_space *mapping, 2548 struct address_space *mapping,
2543 loff_t pos, unsigned len, unsigned flags, 2549 loff_t pos, unsigned len, unsigned flags,
@@ -2604,6 +2610,8 @@ static int reiserfs_write_begin(struct file *file,
2604 if (ret) { 2610 if (ret) {
2605 unlock_page(page); 2611 unlock_page(page);
2606 page_cache_release(page); 2612 page_cache_release(page);
2613 /* Truncate allocated blocks */
2614 reiserfs_truncate_failed_write(inode);
2607 } 2615 }
2608 return ret; 2616 return ret;
2609} 2617}
@@ -2701,9 +2709,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2701 ** transaction tracking stuff when the size changes. So, we have 2709 ** transaction tracking stuff when the size changes. So, we have
2702 ** to do the i_size updates here. 2710 ** to do the i_size updates here.
2703 */ 2711 */
2704 pos += copied; 2712 if (pos + copied > inode->i_size) {
2705
2706 if (pos > inode->i_size) {
2707 struct reiserfs_transaction_handle myth; 2713 struct reiserfs_transaction_handle myth;
2708 lock_depth = reiserfs_write_lock_once(inode->i_sb); 2714 lock_depth = reiserfs_write_lock_once(inode->i_sb);
2709 locked = true; 2715 locked = true;
@@ -2721,7 +2727,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2721 goto journal_error; 2727 goto journal_error;
2722 2728
2723 reiserfs_update_inode_transaction(inode); 2729 reiserfs_update_inode_transaction(inode);
2724 inode->i_size = pos; 2730 inode->i_size = pos + copied;
2725 /* 2731 /*
2726 * this will just nest into our transaction. It's important 2732 * this will just nest into our transaction. It's important
2727 * to use mark_inode_dirty so the inode gets pushed around on the 2733 * to use mark_inode_dirty so the inode gets pushed around on the
@@ -2751,6 +2757,10 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2751 reiserfs_write_unlock_once(inode->i_sb, lock_depth); 2757 reiserfs_write_unlock_once(inode->i_sb, lock_depth);
2752 unlock_page(page); 2758 unlock_page(page);
2753 page_cache_release(page); 2759 page_cache_release(page);
2760
2761 if (pos + len > inode->i_size)
2762 reiserfs_truncate_failed_write(inode);
2763
2754 return ret == 0 ? copied : ret; 2764 return ret == 0 ? copied : ret;
2755 2765
2756 journal_error: 2766 journal_error: