summaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/inode.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2009-12-24 15:16:02 +0900
committerPaul Mundt <lethal@linux-sh.org>2009-12-24 15:16:02 +0900
commitf34548cb735b7a80bbbb0bdd09ad4c2173ba92d5 (patch)
treee53c9e39b3149221779c10595bc59fa02de4f45f /fs/reiserfs/inode.c
parent76382b5bdb77c29ab430e1b82ef1c604c8dd113b (diff)
parent32b53076c31ce9159740b744d5eb5d9505312add (diff)
Merge branch 'sh/g3-prep' into sh/for-2.6.33
Diffstat (limited to 'fs/reiserfs/inode.c')
-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 3a28e7751b3..290ae38fca8 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)
return reiserfs_write_full_page(page, wbc);
}
+static void reiserfs_truncate_failed_write(struct inode *inode)
+{
+ truncate_inode_pages(inode->i_mapping, inode->i_size);
+ reiserfs_truncate_file(inode, 0);
+}
+
static int reiserfs_write_begin(struct file *file,
struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
@@ -2604,6 +2610,8 @@ static int reiserfs_write_begin(struct file *file,
if (ret) {
unlock_page(page);
page_cache_release(page);
+ /* Truncate allocated blocks */
+ reiserfs_truncate_failed_write(inode);
}
return ret;
}
@@ -2701,9 +2709,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
** transaction tracking stuff when the size changes. So, we have
** to do the i_size updates here.
*/
- pos += copied;
-
- if (pos > inode->i_size) {
+ if (pos + copied > inode->i_size) {
struct reiserfs_transaction_handle myth;
lock_depth = reiserfs_write_lock_once(inode->i_sb);
locked = true;
@@ -2721,7 +2727,7 @@ static int reiserfs_write_end(struct file *file, struct address_space *mapping,
goto journal_error;
reiserfs_update_inode_transaction(inode);
- inode->i_size = pos;
+ inode->i_size = pos + copied;
/*
* this will just nest into our transaction. It's important
* 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,
reiserfs_write_unlock_once(inode->i_sb, lock_depth);
unlock_page(page);
page_cache_release(page);
+
+ if (pos + len > inode->i_size)
+ reiserfs_truncate_failed_write(inode);
+
return ret == 0 ? copied : ret;
journal_error: