diff options
Diffstat (limited to 'fs/ext3/inode.c')
-rw-r--r-- | fs/ext3/inode.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index b0248c6d5d4c..05dea8132fc0 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -820,7 +820,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
820 | while (count < maxblocks && count <= blocks_to_boundary) { | 820 | while (count < maxblocks && count <= blocks_to_boundary) { |
821 | ext3_fsblk_t blk; | 821 | ext3_fsblk_t blk; |
822 | 822 | ||
823 | if (!verify_chain(chain, partial)) { | 823 | if (!verify_chain(chain, chain + depth - 1)) { |
824 | /* | 824 | /* |
825 | * Indirect block might be removed by | 825 | * Indirect block might be removed by |
826 | * truncate while we were reading it. | 826 | * truncate while we were reading it. |
@@ -2374,7 +2374,7 @@ void ext3_truncate(struct inode *inode) | |||
2374 | struct page *page; | 2374 | struct page *page; |
2375 | 2375 | ||
2376 | if (!ext3_can_truncate(inode)) | 2376 | if (!ext3_can_truncate(inode)) |
2377 | return; | 2377 | goto out_notrans; |
2378 | 2378 | ||
2379 | if (inode->i_size == 0 && ext3_should_writeback_data(inode)) | 2379 | if (inode->i_size == 0 && ext3_should_writeback_data(inode)) |
2380 | ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE; | 2380 | ei->i_state |= EXT3_STATE_FLUSH_ON_CLOSE; |
@@ -2390,7 +2390,7 @@ void ext3_truncate(struct inode *inode) | |||
2390 | page = grab_cache_page(mapping, | 2390 | page = grab_cache_page(mapping, |
2391 | inode->i_size >> PAGE_CACHE_SHIFT); | 2391 | inode->i_size >> PAGE_CACHE_SHIFT); |
2392 | if (!page) | 2392 | if (!page) |
2393 | return; | 2393 | goto out_notrans; |
2394 | } | 2394 | } |
2395 | 2395 | ||
2396 | handle = start_transaction(inode); | 2396 | handle = start_transaction(inode); |
@@ -2401,7 +2401,7 @@ void ext3_truncate(struct inode *inode) | |||
2401 | unlock_page(page); | 2401 | unlock_page(page); |
2402 | page_cache_release(page); | 2402 | page_cache_release(page); |
2403 | } | 2403 | } |
2404 | return; /* AKPM: return what? */ | 2404 | goto out_notrans; |
2405 | } | 2405 | } |
2406 | 2406 | ||
2407 | last_block = (inode->i_size + blocksize-1) | 2407 | last_block = (inode->i_size + blocksize-1) |
@@ -2525,6 +2525,14 @@ out_stop: | |||
2525 | ext3_orphan_del(handle, inode); | 2525 | ext3_orphan_del(handle, inode); |
2526 | 2526 | ||
2527 | ext3_journal_stop(handle); | 2527 | ext3_journal_stop(handle); |
2528 | return; | ||
2529 | out_notrans: | ||
2530 | /* | ||
2531 | * Delete the inode from orphan list so that it doesn't stay there | ||
2532 | * forever and trigger assertion on umount. | ||
2533 | */ | ||
2534 | if (inode->i_nlink) | ||
2535 | ext3_orphan_del(NULL, inode); | ||
2528 | } | 2536 | } |
2529 | 2537 | ||
2530 | static ext3_fsblk_t ext3_get_inode_block(struct super_block *sb, | 2538 | static ext3_fsblk_t ext3_get_inode_block(struct super_block *sb, |
@@ -3122,12 +3130,6 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) | |||
3122 | 3130 | ||
3123 | rc = inode_setattr(inode, attr); | 3131 | rc = inode_setattr(inode, attr); |
3124 | 3132 | ||
3125 | /* If inode_setattr's call to ext3_truncate failed to get a | ||
3126 | * transaction handle at all, we need to clean up the in-core | ||
3127 | * orphan list manually. */ | ||
3128 | if (inode->i_nlink) | ||
3129 | ext3_orphan_del(NULL, inode); | ||
3130 | |||
3131 | if (!rc && (ia_valid & ATTR_MODE)) | 3133 | if (!rc && (ia_valid & ATTR_MODE)) |
3132 | rc = ext3_acl_chmod(inode); | 3134 | rc = ext3_acl_chmod(inode); |
3133 | 3135 | ||