diff options
Diffstat (limited to 'fs/ext3/inode.c')
-rw-r--r-- | fs/ext3/inode.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index b04d11936683..cc55cecf9fbc 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -190,18 +190,28 @@ static int truncate_restart_transaction(handle_t *handle, struct inode *inode) | |||
190 | } | 190 | } |
191 | 191 | ||
192 | /* | 192 | /* |
193 | * Called at the last iput() if i_nlink is zero. | 193 | * Called at inode eviction from icache |
194 | */ | 194 | */ |
195 | void ext3_delete_inode (struct inode * inode) | 195 | void ext3_evict_inode (struct inode *inode) |
196 | { | 196 | { |
197 | struct ext3_block_alloc_info *rsv; | ||
197 | handle_t *handle; | 198 | handle_t *handle; |
199 | int want_delete = 0; | ||
198 | 200 | ||
199 | if (!is_bad_inode(inode)) | 201 | if (!inode->i_nlink && !is_bad_inode(inode)) { |
200 | dquot_initialize(inode); | 202 | dquot_initialize(inode); |
203 | want_delete = 1; | ||
204 | } | ||
201 | 205 | ||
202 | truncate_inode_pages(&inode->i_data, 0); | 206 | truncate_inode_pages(&inode->i_data, 0); |
203 | 207 | ||
204 | if (is_bad_inode(inode)) | 208 | ext3_discard_reservation(inode); |
209 | rsv = EXT3_I(inode)->i_block_alloc_info; | ||
210 | EXT3_I(inode)->i_block_alloc_info = NULL; | ||
211 | if (unlikely(rsv)) | ||
212 | kfree(rsv); | ||
213 | |||
214 | if (!want_delete) | ||
205 | goto no_delete; | 215 | goto no_delete; |
206 | 216 | ||
207 | handle = start_transaction(inode); | 217 | handle = start_transaction(inode); |
@@ -238,15 +248,22 @@ void ext3_delete_inode (struct inode * inode) | |||
238 | * having errors), but we can't free the inode if the mark_dirty | 248 | * having errors), but we can't free the inode if the mark_dirty |
239 | * fails. | 249 | * fails. |
240 | */ | 250 | */ |
241 | if (ext3_mark_inode_dirty(handle, inode)) | 251 | if (ext3_mark_inode_dirty(handle, inode)) { |
242 | /* If that failed, just do the required in-core inode clear. */ | 252 | /* If that failed, just dquot_drop() and be done with that */ |
243 | clear_inode(inode); | 253 | dquot_drop(inode); |
244 | else | 254 | end_writeback(inode); |
255 | } else { | ||
256 | ext3_xattr_delete_inode(handle, inode); | ||
257 | dquot_free_inode(inode); | ||
258 | dquot_drop(inode); | ||
259 | end_writeback(inode); | ||
245 | ext3_free_inode(handle, inode); | 260 | ext3_free_inode(handle, inode); |
261 | } | ||
246 | ext3_journal_stop(handle); | 262 | ext3_journal_stop(handle); |
247 | return; | 263 | return; |
248 | no_delete: | 264 | no_delete: |
249 | clear_inode(inode); /* We must guarantee clearing of inode... */ | 265 | end_writeback(inode); |
266 | dquot_drop(inode); | ||
250 | } | 267 | } |
251 | 268 | ||
252 | typedef struct { | 269 | typedef struct { |
@@ -2564,7 +2581,7 @@ out_stop: | |||
2564 | * If this was a simple ftruncate(), and the file will remain alive | 2581 | * If this was a simple ftruncate(), and the file will remain alive |
2565 | * then we need to clear up the orphan record which we created above. | 2582 | * then we need to clear up the orphan record which we created above. |
2566 | * However, if this was a real unlink then we were called by | 2583 | * However, if this was a real unlink then we were called by |
2567 | * ext3_delete_inode(), and we allow that function to clean up the | 2584 | * ext3_evict_inode(), and we allow that function to clean up the |
2568 | * orphan info for us. | 2585 | * orphan info for us. |
2569 | */ | 2586 | */ |
2570 | if (inode->i_nlink) | 2587 | if (inode->i_nlink) |