• Miao Xie's avatar
    Btrfs: fix inode caching vs tree log · d6db8ad7
    Miao Xie authored
    commit 1c70d8fb upstream.
    
    Currently, with inode cache enabled, we will reuse its inode id immediately
    after unlinking file, we may hit something like following:
    
    |->iput inode
    |->return inode id into inode cache
    |->create dir,fsync
    |->power off
    
    An easy way to reproduce this problem is:
    
    mkfs.btrfs -f /dev/sdb
    mount /dev/sdb /mnt -o inode_cache,commit=100
    dd if=/dev/zero of=/mnt/data bs=1M count=10 oflag=sync
    inode_id=`ls -i /mnt/data | awk '{print $1}'`
    rm -f /mnt/data
    
    i=1
    while [ 1 ]
    do
            mkdir /mnt/dir_$i
            test1=`stat /mnt/dir_$i | grep Inode: | awk '{print $4}'`
            if [ $test1 -eq $inode_id ]
            then
    		dd if=/dev/zero of=/mnt/dir_$i/data bs=1M count=1 oflag=sync
    		echo b > /proc/sysrq-trigger
    	fi
    	sleep 1
            i=$(($i+1))
    done
    
    mount /dev/sdb /mnt
    umount /dev/sdb
    btrfs check /dev/sdb
    
    We fix this problem by adding unlinked inode's id into pinned tree,
    and we can not reuse them until committing transaction.
    Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
    Signed-off-by: default avatarWang Shilong <wangsl.fnst@cn.fujitsu.com>
    Signed-off-by: default avatarChris Mason <clm@fb.com>
    [bwh: Backported to 3.2: adjust context]
    Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
    d6db8ad7
inode-map.c 13.3 KB