Btrfs: fix accessing a freed tree root
authorMiao Xie <miaox@cn.fujitsu.com>
Wed, 15 May 2013 07:48:15 +0000 (07:48 +0000)
committerJosef Bacik <jbacik@fusionio.com>
Sat, 18 May 2013 01:40:29 +0000 (21:40 -0400)
inode_tree_del() will move the tree root into the dead root list, and
then the tree will be destroyed by the cleaner. So if we remove the
delayed node which is cached in the inode after inode_tree_del(),
we may access a freed tree root. Fix it.

Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
fs/btrfs/inode.c

index 99a9c25d36a6b8eb2eb074362e61ac205aa6715e..790eceb48fb07ee193985727bf4fcc6daf11757a 100644 (file)
@@ -4727,6 +4727,7 @@ void btrfs_evict_inode(struct inode *inode)
        btrfs_end_transaction(trans, root);
        btrfs_btree_balance_dirty(root);
 no_delete:
+       btrfs_remove_delayed_node(inode);
        clear_inode(inode);
        return;
 }
@@ -7982,7 +7983,6 @@ void btrfs_destroy_inode(struct inode *inode)
        inode_tree_del(inode);
        btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
 free:
-       btrfs_remove_delayed_node(inode);
        call_rcu(&inode->i_rcu, btrfs_i_callback);
 }