• Liu Bo's avatar
    Btrfs: fix an oops when deleting snapshots · 14c7cca7
    Liu Bo authored
    We can reproduce this oops via the following steps:
    
    $ mkfs.btrfs /dev/sdb7
    $ mount /dev/sdb7 /mnt/btrfs
    $ for ((i=0; i<3; i++)); do btrfs sub snap /mnt/btrfs /mnt/btrfs/s_$i; done
    $ rm -fr /mnt/btrfs/*
    $ rm -fr /mnt/btrfs/*
    
    then we'll get
    ------------[ cut here ]------------
    kernel BUG at fs/btrfs/inode.c:2264!
    [...]
    Call Trace:
     [<ffffffffa05578c7>] btrfs_rmdir+0xf7/0x1b0 [btrfs]
     [<ffffffff81150b95>] vfs_rmdir+0xa5/0xf0
     [<ffffffff81153cc3>] do_rmdir+0x123/0x140
     [<ffffffff81145ac7>] ? fput+0x197/0x260
     [<ffffffff810aecff>] ? audit_syscall_entry+0x1bf/0x1f0
     [<ffffffff81153d0d>] sys_unlinkat+0x2d/0x40
     [<ffffffff8147896b>] system_call_fastpath+0x16/0x1b
    RIP  [<ffffffffa054f7b9>] btrfs_orphan_add+0x179/0x1a0 [btrfs]
    
    When it comes to btrfs_lookup_dentry, we may set a snapshot's inode->i_ino
    to BTRFS_EMPTY_SUBVOL_DIR_OBJECTID instead of BTRFS_FIRST_FREE_OBJECTID,
    while the snapshot's location.objectid remains unchanged.
    
    However, btrfs_ino() does not take this into account, and returns a wrong ino,
    and causes the oops.
    Signed-off-by: default avatarLiu Bo <liubo2009@cn.fujitsu.com>
    Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
    14c7cca7
btrfs_inode.h 5.31 KB