diff linux-2.6.10.orig/fs/ext2/ext2.h linux-2.6.10/fs/ext2/ext2.h --- linux-2.6.10.orig/fs/ext2/ext2.h 2004-10-19 05:55:29.000000000 +0800 +++ linux-2.6.10/fs/ext2/ext2.h 2004-12-25 05:35:40.000000000 +0800 @@ -116,6 +116,7 @@ extern unsigned long ext2_count_free (st /* inode.c */ extern void ext2_read_inode (struct inode *); extern int ext2_write_inode (struct inode *, int); +extern void ext2_put_inode (struct inode *); extern void ext2_delete_inode (struct inode *); extern int ext2_sync_inode (struct inode *); extern void ext2_discard_prealloc (struct inode *); diff linux-2.6.10.orig/fs/ext2/inode.c linux-2.6.10/fs/ext2/inode.c --- linux-2.6.10.orig/fs/ext2/inode.c 2004-10-19 05:53:11.000000000 +0800 +++ linux-2.6.10/fs/ext2/inode.c 2004-12-25 05:33:51.000000000 +0800 @@ -53,6 +53,19 @@ static inline int ext2_inode_is_fast_sym } /* + * Called at each iput(). + * + * The inode may be "bad" if ext2_read_inode() saw an error from + * ext2_get_inode(), so we need to check that to avoid freeing random disk + * blocks. + */ +void ext2_put_inode(struct inode *inode) +{ + if (!is_bad_inode(inode)) + ext2_discard_prealloc(inode); +} + +/* * Called at the last iput() if i_nlink is zero. */ void ext2_delete_inode (struct inode * inode) diff linux-2.6.10.orig/fs/ext2/super.c linux-2.6.10/fs/ext2/super.c --- linux-2.6.10.orig/fs/ext2/super.c 2004-10-19 05:54:38.000000000 +0800 +++ linux-2.6.10/fs/ext2/super.c 2004-12-25 05:35:01.000000000 +0800 @@ -197,17 +199,16 @@ static void ext2_clear_inode(struct inod posix_acl_release(ei->i_default_acl); ei->i_default_acl = EXT2_ACL_NOT_CACHED; } #endif - if (!is_bad_inode(inode)) - ext2_discard_prealloc(inode); } static struct super_operations ext2_sops = { .alloc_inode = ext2_alloc_inode, .destroy_inode = ext2_destroy_inode, .read_inode = ext2_read_inode, .write_inode = ext2_write_inode, + .put_inode = ext2_put_inode, .delete_inode = ext2_delete_inode, .put_super = ext2_put_super, .write_super = ext2_write_super,