On Wed, Aug 21, 2024 at 07:46:28PM +0800, Julian Sun wrote:
There is a race condition generic_shutdown_super() and __btrfs_run_defrag_inode(). Consider the following scenario:
umount thread: btrfs-cleaner thread: btrfs_run_delayed_iputs() ->run_delayed_iput_locked() ->iput(inode) // Here the inode (ie ino 261) will be cleared and freed btrfs_kill_super() ->generic_shutdown_super() btrfs_run_defrag_inodes() ->__btrfs_run_defrag_inode() ->btrfs_iget(ino) // The inode 261 was recreated with i_count=1 // and added to the sb list ->evict_inodes(sb) // After some work // inode 261 was added ->iput(inode) // to the dispose list ->iput_funal() ->evict(inode) ->evict(inode)
This is wrong though, evict_inodes() isn't supposed to isolate if i_count == 1, and iput_final sets I_FREEING, so we won't get the evict() from evict_inodes. Something else is happening here. Thanks,
Josef