diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 498021eb88fb..4ab72db3559e 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -119,20 +119,8 @@ void ext3_free_inode (handle_t *handle, struct inode * inode) ino = inode->i_ino; ext3_debug ("freeing inode %lu\n", ino); - /* - * Note: we must free any quota before locking the superblock, - * as writing the quota to disk may need the lock as well. - */ - dquot_initialize(inode); - ext3_xattr_delete_inode(handle, inode); - dquot_free_inode(inode); - dquot_drop(inode); - is_directory = S_ISDIR(inode->i_mode); - /* Do this BEFORE marking the inode not in use or returning an error */ - clear_inode (inode); - es = EXT3_SB(sb)->s_es; if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { ext3_error (sb, "ext3_free_inode", 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) } /* - * Called at the last iput() if i_nlink is zero. + * Called at inode eviction from icache */ -void ext3_delete_inode (struct inode * inode) +void ext3_evict_inode (struct inode *inode) { + struct ext3_block_alloc_info *rsv; handle_t *handle; + int want_delete = 0; - if (!is_bad_inode(inode)) + if (!inode->i_nlink && !is_bad_inode(inode)) { dquot_initialize(inode); + want_delete = 1; + } truncate_inode_pages(&inode->i_data, 0); - if (is_bad_inode(inode)) + ext3_discard_reservation(inode); + rsv = EXT3_I(inode)->i_block_alloc_info; + EXT3_I(inode)->i_block_alloc_info = NULL; + if (unlikely(rsv)) + kfree(rsv); + + if (!want_delete) goto no_delete; handle = start_transaction(inode); @@ -238,15 +248,22 @@ void ext3_delete_inode (struct inode * inode) * having errors), but we can't free the inode if the mark_dirty * fails. */ - if (ext3_mark_inode_dirty(handle, inode)) - /* If that failed, just do the required in-core inode clear. */ - clear_inode(inode); - else + if (ext3_mark_inode_dirty(handle, inode)) { + /* If that failed, just dquot_drop() and be done with that */ + dquot_drop(inode); + end_writeback(inode); + } else { + ext3_xattr_delete_inode(handle, inode); + dquot_free_inode(inode); + dquot_drop(inode); + end_writeback(inode); ext3_free_inode(handle, inode); + } ext3_journal_stop(handle); return; no_delete: - clear_inode(inode); /* We must guarantee clearing of inode... */ + end_writeback(inode); + dquot_drop(inode); } typedef struct { @@ -2564,7 +2581,7 @@ out_stop: * If this was a simple ftruncate(), and the file will remain alive * then we need to clear up the orphan record which we created above. * However, if this was a real unlink then we were called by - * ext3_delete_inode(), and we allow that function to clean up the + * ext3_evict_inode(), and we allow that function to clean up the * orphan info for us. */ if (inode->i_nlink) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 6c953bb255e7..a951fd5c081c 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -527,17 +527,6 @@ static void destroy_inodecache(void) kmem_cache_destroy(ext3_inode_cachep); } -static void ext3_clear_inode(struct inode *inode) -{ - struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info; - - dquot_drop(inode); - ext3_discard_reservation(inode); - EXT3_I(inode)->i_block_alloc_info = NULL; - if (unlikely(rsv)) - kfree(rsv); -} - static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb) { #if defined(CONFIG_QUOTA) @@ -783,14 +772,13 @@ static const struct super_operations ext3_sops = { .destroy_inode = ext3_destroy_inode, .write_inode = ext3_write_inode, .dirty_inode = ext3_dirty_inode, - .delete_inode = ext3_delete_inode, + .evict_inode = ext3_evict_inode, .put_super = ext3_put_super, .sync_fs = ext3_sync_fs, .freeze_fs = ext3_freeze, .unfreeze_fs = ext3_unfreeze, .statfs = ext3_statfs, .remount_fs = ext3_remount, - .clear_inode = ext3_clear_inode, .show_options = ext3_show_options, #ifdef CONFIG_QUOTA .quota_read = ext3_quota_read, diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 7fc62d4550b2..e7cb21766992 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -896,7 +896,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, extern struct inode *ext3_iget(struct super_block *, unsigned long); extern int ext3_write_inode (struct inode *, struct writeback_control *); extern int ext3_setattr (struct dentry *, struct iattr *); -extern void ext3_delete_inode (struct inode *); +extern void ext3_evict_inode (struct inode *); extern int ext3_sync_inode (handle_t *, struct inode *); extern void ext3_discard_reservation (struct inode *); extern void ext3_dirty_inode(struct inode *);