• Qu Wenruo's avatar
    btrfs: preallocate anon block device at first phase of snapshot creation · 2dfb1e43
    Qu Wenruo authored
    [BUG]
    When the anonymous block device pool is exhausted, subvolume/snapshot
    creation fails with EMFILE (Too many files open). This has been reported
    by a user. The allocation happens in the second phase during transaction
    commit where it's only way out is to abort the transaction
    
      BTRFS: Transaction aborted (error -24)
      WARNING: CPU: 17 PID: 17041 at fs/btrfs/transaction.c:1576 create_pending_snapshot+0xbc4/0xd10 [btrfs]
      RIP: 0010:create_pending_snapshot+0xbc4/0xd10 [btrfs]
      Call Trace:
       create_pending_snapshots+0x82/0xa0 [btrfs]
       btrfs_commit_transaction+0x275/0x8c0 [btrfs]
       btrfs_mksubvol+0x4b9/0x500 [btrfs]
       btrfs_ioctl_snap_create_transid+0x174/0x180 [btrfs]
       btrfs_ioctl_snap_create_v2+0x11c/0x180 [btrfs]
       btrfs_ioctl+0x11a4/0x2da0 [btrfs]
       do_vfs_ioctl+0xa9/0x640
       ksys_ioctl+0x67/0x90
       __x64_sys_ioctl+0x1a/0x20
       do_syscall_64+0x5a/0x110
       entry_SYSCALL_64_after_hwframe+0x44/0xa9
      ---[ end trace 33f2f83f3d5250e9 ]---
      BTRFS: error (device sda1) in create_pending_snapshot:1576: errno=-24 unknown
      BTRFS info (device sda1): forced readonly
      BTRFS warning (device sda1): Skipping commit of aborted transaction.
      BTRFS: error (device sda1) in cleanup_transaction:1831: errno=-24 unknown
    
    [CAUSE]
    When the global anonymous block device pool is exhausted, the following
    call chain will fail, and lead to transaction abort:
    
     btrfs_ioctl_snap_create_v2()
     |- btrfs_ioctl_snap_create_transid()
        |- btrfs_mksubvol()
           |- btrfs_commit_transaction()
              |- create_pending_snapshot()
                 |- btrfs_get_fs_root()
                    |- btrfs_init_fs_root()
                       |- get_anon_bdev()
    
    [FIX]
    Although we can't enlarge the anonymous block device pool, at least we
    can preallocate anon_dev for subvolume/snapshot in the first phase,
    outside of transaction context and exactly at the moment the user calls
    the creation ioctl.
    Reported-by: default avatarGreed Rong <greedrong@gmail.com>
    Link: https://lore.kernel.org/linux-btrfs/CA+UqX+NTrZ6boGnWHhSeZmEY5J76CTqmYjO2S+=tHJX7nb9DPw@mail.gmail.com/
    CC: stable@vger.kernel.org # 4.4+
    Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    2dfb1e43
ioctl.c 118 KB