• xiaoshoukui's avatar
    btrfs: fix assertion of exclop condition when starting balance · ac868bc9
    xiaoshoukui authored
    Balance as exclusive state is compatible with paused balance and device
    add, which makes some things more complicated. The assertion of valid
    states when starting from paused balance needs to take into account two
    more states, the combinations can be hit when there are several threads
    racing to start balance and device add. This won't typically happen when
    the commands are started from command line.
    
    Scenario 1: With exclusive_operation state == BTRFS_EXCLOP_NONE.
    
    Concurrently adding multiple devices to the same mount point and
    btrfs_exclop_finish executed finishes before assertion in
    btrfs_exclop_balance, exclusive_operation will changed to
    BTRFS_EXCLOP_NONE state which lead to assertion failed:
    
      fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE ||
      fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD,
      in fs/btrfs/ioctl.c:456
      Call Trace:
       <TASK>
       btrfs_exclop_balance+0x13c/0x310
       ? memdup_user+0xab/0xc0
       ? PTR_ERR+0x17/0x20
       btrfs_ioctl_add_dev+0x2ee/0x320
       btrfs_ioctl+0x9d5/0x10d0
       ? btrfs_ioctl_encoded_write+0xb80/0xb80
       __x64_sys_ioctl+0x197/0x210
       do_syscall_64+0x3c/0xb0
       entry_SYSCALL_64_after_hwframe+0x63/0xcd
    
    Scenario 2: With exclusive_operation state == BTRFS_EXCLOP_BALANCE_PAUSED.
    
    Concurrently adding multiple devices to the same mount point and
    btrfs_exclop_balance executed finish before the latter thread execute
    assertion in btrfs_exclop_balance, exclusive_operation will changed to
    BTRFS_EXCLOP_BALANCE_PAUSED state which lead to assertion failed:
    
      fs_info->exclusive_operation == BTRFS_EXCLOP_BALANCE ||
      fs_info->exclusive_operation == BTRFS_EXCLOP_DEV_ADD ||
      fs_info->exclusive_operation == BTRFS_EXCLOP_NONE,
      fs/btrfs/ioctl.c:458
      Call Trace:
       <TASK>
       btrfs_exclop_balance+0x240/0x410
       ? memdup_user+0xab/0xc0
       ? PTR_ERR+0x17/0x20
       btrfs_ioctl_add_dev+0x2ee/0x320
       btrfs_ioctl+0x9d5/0x10d0
       ? btrfs_ioctl_encoded_write+0xb80/0xb80
       __x64_sys_ioctl+0x197/0x210
       do_syscall_64+0x3c/0xb0
       entry_SYSCALL_64_after_hwframe+0x63/0xcd
    
    An example of the failed assertion is below, which shows that the
    paused balance is also needed to be checked.
    
      root@syzkaller:/home/xsk# ./repro
      Failed to add device /dev/vda, errno 14
      Failed to add device /dev/vda, errno 14
      Failed to add device /dev/vda, errno 14
      Failed to add device /dev/vda, errno 14
      Failed to add device /dev/vda, errno 14
      Failed to add device /dev/vda, errno 14
      Failed to add device /dev/vda, errno 14
      Failed to add device /dev/vda, errno 14
      Failed to add device /dev/vda, errno 14
      [  416.611428][ T7970] BTRFS info (device loop0): fs_info exclusive_operation: 0
      Failed to add device /dev/vda, errno 14
      [  416.613973][ T7971] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      [  416.615456][ T7972] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      [  416.617528][ T7973] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      [  416.618359][ T7974] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      [  416.622589][ T7975] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      [  416.624034][ T7976] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      [  416.626420][ T7977] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      [  416.627643][ T7978] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      [  416.629006][ T7979] BTRFS info (device loop0): fs_info exclusive_operation: 3
      [  416.630298][ T7980] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      Failed to add device /dev/vda, errno 14
      [  416.632787][ T7981] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      [  416.634282][ T7982] BTRFS info (device loop0): fs_info exclusive_operation: 3
      Failed to add device /dev/vda, errno 14
      [  416.636202][ T7983] BTRFS info (device loop0): fs_info exclusive_operation: 3
      [  416.637012][ T7984] BTRFS info (device loop0): fs_info exclusive_operation: 1
      Failed to add device /dev/vda, errno 14
      [  416.637759][ T7984] assertion failed: fs_info->exclusive_operation ==
      BTRFS_EXCLOP_BALANCE || fs_info->exclusive_operation ==
      BTRFS_EXCLOP_DEV_ADD || fs_info->exclusive_operation ==
      BTRFS_EXCLOP_NONE, in fs/btrfs/ioctl.c:458
      [  416.639845][ T7984] invalid opcode: 0000 [#1] PREEMPT SMP KASAN
      [  416.640485][ T7984] CPU: 0 PID: 7984 Comm: repro Not tainted 6.2.0 #7
      [  416.641172][ T7984] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
      [  416.642090][ T7984] RIP: 0010:btrfs_assertfail+0x2c/0x2e
      [  416.644423][ T7984] RSP: 0018:ffffc90003ea7e28 EFLAGS: 00010282
      [  416.645018][ T7984] RAX: 00000000000000cc RBX: 0000000000000000 RCX: 0000000000000000
      [  416.645763][ T7984] RDX: ffff88801d030000 RSI: ffffffff81637e7c RDI: fffff520007d4fb7
      [  416.646554][ T7984] RBP: ffffffff8a533de0 R08: 00000000000000cc R09: 0000000000000000
      [  416.647299][ T7984] R10: 0000000000000001 R11: 0000000000000001 R12: ffffffff8a533da0
      [  416.648041][ T7984] R13: 00000000000001ca R14: 000000005000940a R15: 0000000000000000
      [  416.648785][ T7984] FS:  00007fa2985d4640(0000) GS:ffff88802cc00000(0000) knlGS:0000000000000000
      [  416.649616][ T7984] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [  416.650238][ T7984] CR2: 0000000000000000 CR3: 0000000018e5e000 CR4: 0000000000750ef0
      [  416.650980][ T7984] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      [  416.651725][ T7984] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
      [  416.652502][ T7984] PKRU: 55555554
      [  416.652888][ T7984] Call Trace:
      [  416.653241][ T7984]  <TASK>
      [  416.653527][ T7984]  btrfs_exclop_balance+0x240/0x410
      [  416.654036][ T7984]  ? memdup_user+0xab/0xc0
      [  416.654465][ T7984]  ? PTR_ERR+0x17/0x20
      [  416.654874][ T7984]  btrfs_ioctl_add_dev+0x2ee/0x320
      [  416.655380][ T7984]  btrfs_ioctl+0x9d5/0x10d0
      [  416.655822][ T7984]  ? btrfs_ioctl_encoded_write+0xb80/0xb80
      [  416.656400][ T7984]  __x64_sys_ioctl+0x197/0x210
      [  416.656874][ T7984]  do_syscall_64+0x3c/0xb0
      [  416.657346][ T7984]  entry_SYSCALL_64_after_hwframe+0x63/0xcd
      [  416.657922][ T7984] RIP: 0033:0x4546af
      [  416.660170][ T7984] RSP: 002b:00007fa2985d4150 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
      [  416.660972][ T7984] RAX: ffffffffffffffda RBX: 00007fa2985d4640 RCX: 00000000004546af
      [  416.661714][ T7984] RDX: 0000000000000000 RSI: 000000005000940a RDI: 0000000000000003
      [  416.662449][ T7984] RBP: 00007fa2985d41d0 R08: 0000000000000000 R09: 00007ffee37a4c4f
      [  416.663195][ T7984] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fa2985d4640
      [  416.663951][ T7984] R13: 0000000000000009 R14: 000000000041b320 R15: 00007fa297dd4000
      [  416.664703][ T7984]  </TASK>
      [  416.665040][ T7984] Modules linked in:
      [  416.665590][ T7984] ---[ end trace 0000000000000000 ]---
      [  416.666176][ T7984] RIP: 0010:btrfs_assertfail+0x2c/0x2e
      [  416.668775][ T7984] RSP: 0018:ffffc90003ea7e28 EFLAGS: 00010282
      [  416.669425][ T7984] RAX: 00000000000000cc RBX: 0000000000000000 RCX: 0000000000000000
      [  416.670235][ T7984] RDX: ffff88801d030000 RSI: ffffffff81637e7c RDI: fffff520007d4fb7
      [  416.671050][ T7984] RBP: ffffffff8a533de0 R08: 00000000000000cc R09: 0000000000000000
      [  416.671867][ T7984] R10: 0000000000000001 R11: 0000000000000001 R12: ffffffff8a533da0
      [  416.672685][ T7984] R13: 00000000000001ca R14: 000000005000940a R15: 0000000000000000
      [  416.673501][ T7984] FS:  00007fa2985d4640(0000) GS:ffff88802cc00000(0000) knlGS:0000000000000000
      [  416.674425][ T7984] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      [  416.675114][ T7984] CR2: 0000000000000000 CR3: 0000000018e5e000 CR4: 0000000000750ef0
      [  416.675933][ T7984] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
      [  416.676760][ T7984] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    
    Link: https://lore.kernel.org/linux-btrfs/20230324031611.98986-1-xiaoshoukui@gmail.com/
    CC: stable@vger.kernel.org # 6.1+
    Signed-off-by: default avatarxiaoshoukui <xiaoshoukui@ruijie.com.cn>
    Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    ac868bc9
ioctl.c 115 KB