diff options
Diffstat (limited to 'fs/ext4/inode.c')
| -rw-r--r-- | fs/ext4/inode.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 37f834bc7cd6..2697eaf0368f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -191,6 +191,7 @@ static int ext4_journal_test_restart(handle_t *handle, struct inode *inode) | |||
| 191 | void ext4_delete_inode (struct inode * inode) | 191 | void ext4_delete_inode (struct inode * inode) |
| 192 | { | 192 | { |
| 193 | handle_t *handle; | 193 | handle_t *handle; |
| 194 | int err; | ||
| 194 | 195 | ||
| 195 | if (ext4_should_order_data(inode)) | 196 | if (ext4_should_order_data(inode)) |
| 196 | ext4_begin_ordered_truncate(inode, 0); | 197 | ext4_begin_ordered_truncate(inode, 0); |
| @@ -199,8 +200,9 @@ void ext4_delete_inode (struct inode * inode) | |||
| 199 | if (is_bad_inode(inode)) | 200 | if (is_bad_inode(inode)) |
| 200 | goto no_delete; | 201 | goto no_delete; |
| 201 | 202 | ||
| 202 | handle = start_transaction(inode); | 203 | handle = ext4_journal_start(inode, blocks_for_truncate(inode)+3); |
| 203 | if (IS_ERR(handle)) { | 204 | if (IS_ERR(handle)) { |
| 205 | ext4_std_error(inode->i_sb, PTR_ERR(handle)); | ||
| 204 | /* | 206 | /* |
| 205 | * If we're going to skip the normal cleanup, we still need to | 207 | * If we're going to skip the normal cleanup, we still need to |
| 206 | * make sure that the in-core orphan linked list is properly | 208 | * make sure that the in-core orphan linked list is properly |
| @@ -213,8 +215,34 @@ void ext4_delete_inode (struct inode * inode) | |||
| 213 | if (IS_SYNC(inode)) | 215 | if (IS_SYNC(inode)) |
| 214 | handle->h_sync = 1; | 216 | handle->h_sync = 1; |
| 215 | inode->i_size = 0; | 217 | inode->i_size = 0; |
| 218 | err = ext4_mark_inode_dirty(handle, inode); | ||
| 219 | if (err) { | ||
| 220 | ext4_warning(inode->i_sb, __func__, | ||
| 221 | "couldn't mark inode dirty (err %d)", err); | ||
| 222 | goto stop_handle; | ||
| 223 | } | ||
| 216 | if (inode->i_blocks) | 224 | if (inode->i_blocks) |
| 217 | ext4_truncate(inode); | 225 | ext4_truncate(inode); |
| 226 | |||
| 227 | /* | ||
| 228 | * ext4_ext_truncate() doesn't reserve any slop when it | ||
| 229 | * restarts journal transactions; therefore there may not be | ||
| 230 | * enough credits left in the handle to remove the inode from | ||
| 231 | * the orphan list and set the dtime field. | ||
| 232 | */ | ||
| 233 | if (handle->h_buffer_credits < 3) { | ||
| 234 | err = ext4_journal_extend(handle, 3); | ||
| 235 | if (err > 0) | ||
| 236 | err = ext4_journal_restart(handle, 3); | ||
| 237 | if (err != 0) { | ||
| 238 | ext4_warning(inode->i_sb, __func__, | ||
| 239 | "couldn't extend journal (err %d)", err); | ||
| 240 | stop_handle: | ||
| 241 | ext4_journal_stop(handle); | ||
| 242 | goto no_delete; | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 218 | /* | 246 | /* |
| 219 | * Kill off the orphan record which ext4_truncate created. | 247 | * Kill off the orphan record which ext4_truncate created. |
| 220 | * AKPM: I think this can be inside the above `if'. | 248 | * AKPM: I think this can be inside the above `if'. |
