diff options
Diffstat (limited to 'fs/ext3/inode.c')
| -rw-r--r-- | fs/ext3/inode.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 354ed3b47b30..ad14227f509e 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
| @@ -1151,6 +1151,16 @@ static int do_journal_get_write_access(handle_t *handle, | |||
| 1151 | return ext3_journal_get_write_access(handle, bh); | 1151 | return ext3_journal_get_write_access(handle, bh); |
| 1152 | } | 1152 | } |
| 1153 | 1153 | ||
| 1154 | /* | ||
| 1155 | * Truncate blocks that were not used by write. We have to truncate the | ||
| 1156 | * pagecache as well so that corresponding buffers get properly unmapped. | ||
| 1157 | */ | ||
| 1158 | static void ext3_truncate_failed_write(struct inode *inode) | ||
| 1159 | { | ||
| 1160 | truncate_inode_pages(inode->i_mapping, inode->i_size); | ||
| 1161 | ext3_truncate(inode); | ||
| 1162 | } | ||
| 1163 | |||
| 1154 | static int ext3_write_begin(struct file *file, struct address_space *mapping, | 1164 | static int ext3_write_begin(struct file *file, struct address_space *mapping, |
| 1155 | loff_t pos, unsigned len, unsigned flags, | 1165 | loff_t pos, unsigned len, unsigned flags, |
| 1156 | struct page **pagep, void **fsdata) | 1166 | struct page **pagep, void **fsdata) |
| @@ -1209,7 +1219,7 @@ write_begin_failed: | |||
| 1209 | unlock_page(page); | 1219 | unlock_page(page); |
| 1210 | page_cache_release(page); | 1220 | page_cache_release(page); |
| 1211 | if (pos + len > inode->i_size) | 1221 | if (pos + len > inode->i_size) |
| 1212 | ext3_truncate(inode); | 1222 | ext3_truncate_failed_write(inode); |
| 1213 | } | 1223 | } |
| 1214 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) | 1224 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) |
| 1215 | goto retry; | 1225 | goto retry; |
| @@ -1304,7 +1314,7 @@ static int ext3_ordered_write_end(struct file *file, | |||
| 1304 | page_cache_release(page); | 1314 | page_cache_release(page); |
| 1305 | 1315 | ||
| 1306 | if (pos + len > inode->i_size) | 1316 | if (pos + len > inode->i_size) |
| 1307 | ext3_truncate(inode); | 1317 | ext3_truncate_failed_write(inode); |
| 1308 | return ret ? ret : copied; | 1318 | return ret ? ret : copied; |
| 1309 | } | 1319 | } |
| 1310 | 1320 | ||
| @@ -1330,7 +1340,7 @@ static int ext3_writeback_write_end(struct file *file, | |||
| 1330 | page_cache_release(page); | 1340 | page_cache_release(page); |
| 1331 | 1341 | ||
| 1332 | if (pos + len > inode->i_size) | 1342 | if (pos + len > inode->i_size) |
| 1333 | ext3_truncate(inode); | 1343 | ext3_truncate_failed_write(inode); |
| 1334 | return ret ? ret : copied; | 1344 | return ret ? ret : copied; |
| 1335 | } | 1345 | } |
| 1336 | 1346 | ||
| @@ -1383,7 +1393,7 @@ static int ext3_journalled_write_end(struct file *file, | |||
| 1383 | page_cache_release(page); | 1393 | page_cache_release(page); |
| 1384 | 1394 | ||
| 1385 | if (pos + len > inode->i_size) | 1395 | if (pos + len > inode->i_size) |
| 1386 | ext3_truncate(inode); | 1396 | ext3_truncate_failed_write(inode); |
| 1387 | return ret ? ret : copied; | 1397 | return ret ? ret : copied; |
| 1388 | } | 1398 | } |
| 1389 | 1399 | ||
| @@ -2033,7 +2043,7 @@ static Indirect *ext3_find_shared(struct inode *inode, int depth, | |||
| 2033 | int k, err; | 2043 | int k, err; |
| 2034 | 2044 | ||
| 2035 | *top = 0; | 2045 | *top = 0; |
| 2036 | /* Make k index the deepest non-null offest + 1 */ | 2046 | /* Make k index the deepest non-null offset + 1 */ |
| 2037 | for (k = depth; k > 1 && !offsets[k-1]; k--) | 2047 | for (k = depth; k > 1 && !offsets[k-1]; k--) |
| 2038 | ; | 2048 | ; |
| 2039 | partial = ext3_get_branch(inode, k, offsets, chain, &err); | 2049 | partial = ext3_get_branch(inode, k, offsets, chain, &err); |
