• Naohiro Aota's avatar
    btrfs: fix invalid mapping of extent xarray state · 6252690f
    Naohiro Aota authored
    In __extent_writepage_io(), we call btrfs_set_range_writeback() ->
    folio_start_writeback(), which clears PAGECACHE_TAG_DIRTY mark from the
    mapping xarray if the folio is not dirty. This worked fine before commit
    97713b1a ("btrfs: do not clear page dirty inside
    extent_write_locked_range()").
    
    After the commit, however, the folio is still dirty at this point, so the
    mapping DIRTY tag is not cleared anymore. Then, __extent_writepage_io()
    calls btrfs_folio_clear_dirty() to clear the folio's dirty flag. That
    results in the page being unlocked with a "strange" state. The page is not
    PageDirty, but the mapping tag is set as PAGECACHE_TAG_DIRTY.
    
    This strange state looks like causing a hang with a call trace below when
    running fstests generic/091 on a null_blk device. It is waiting for a folio
    lock.
    
    While I don't have an exact relation between this hang and the strange
    state, fixing the state also fixes the hang. And, that state is worth
    fixing anyway.
    
    This commit reorders btrfs_folio_clear_dirty() and
    btrfs_set_range_writeback() in __extent_writepage_io(), so that the
    PAGECACHE_TAG_DIRTY tag is properly removed from the xarray.
    
      [464.274] task:fsx             state:D stack:0     pid:3034  tgid:3034  ppid:2853   flags:0x00004002
      [464.286] Call Trace:
      [464.291]  <TASK>
      [464.295]  __schedule+0x10ed/0x6260
      [464.301]  ? __pfx___blk_flush_plug+0x10/0x10
      [464.308]  ? __submit_bio+0x37c/0x450
      [464.314]  ? __pfx___schedule+0x10/0x10
      [464.321]  ? lock_release+0x567/0x790
      [464.327]  ? __pfx_lock_acquire+0x10/0x10
      [464.334]  ? __pfx_lock_release+0x10/0x10
      [464.340]  ? __pfx_lock_acquire+0x10/0x10
      [464.347]  ? __pfx_lock_release+0x10/0x10
      [464.353]  ? do_raw_spin_lock+0x12e/0x270
      [464.360]  schedule+0xdf/0x3b0
      [464.365]  io_schedule+0x8f/0xf0
      [464.371]  folio_wait_bit_common+0x2ca/0x6d0
      [464.378]  ? folio_wait_bit_common+0x1cc/0x6d0
      [464.385]  ? __pfx_folio_wait_bit_common+0x10/0x10
      [464.392]  ? __pfx_filemap_get_folios_tag+0x10/0x10
      [464.400]  ? __pfx_wake_page_function+0x10/0x10
      [464.407]  ? __pfx___might_resched+0x10/0x10
      [464.414]  ? do_raw_spin_unlock+0x58/0x1f0
      [464.420]  extent_write_cache_pages+0xe49/0x1620 [btrfs]
      [464.428]  ? lock_acquire+0x435/0x500
      [464.435]  ? __pfx_extent_write_cache_pages+0x10/0x10 [btrfs]
      [464.443]  ? btrfs_do_write_iter+0x493/0x640 [btrfs]
      [464.451]  ? orc_find.part.0+0x1d4/0x380
      [464.457]  ? __pfx_lock_release+0x10/0x10
      [464.464]  ? __pfx_lock_release+0x10/0x10
      [464.471]  ? btrfs_do_write_iter+0x493/0x640 [btrfs]
      [464.478]  btrfs_writepages+0x1cc/0x460 [btrfs]
      [464.485]  ? __pfx_btrfs_writepages+0x10/0x10 [btrfs]
      [464.493]  ? is_bpf_text_address+0x6e/0x100
      [464.500]  ? kernel_text_address+0x145/0x160
      [464.507]  ? unwind_get_return_address+0x5e/0xa0
      [464.514]  ? arch_stack_walk+0xac/0x100
      [464.521]  do_writepages+0x176/0x780
      [464.527]  ? lock_release+0x567/0x790
      [464.533]  ? __pfx_do_writepages+0x10/0x10
      [464.540]  ? __pfx_lock_acquire+0x10/0x10
      [464.546]  ? __pfx_stack_trace_save+0x10/0x10
      [464.553]  ? do_raw_spin_lock+0x12e/0x270
      [464.560]  ? do_raw_spin_unlock+0x58/0x1f0
      [464.566]  ? _raw_spin_unlock+0x23/0x40
      [464.573]  ? wbc_attach_and_unlock_inode+0x3da/0x7d0
      [464.580]  filemap_fdatawrite_wbc+0x113/0x180
      [464.587]  ? prepare_pages.constprop.0+0x13c/0x5c0 [btrfs]
      [464.596]  __filemap_fdatawrite_range+0xaf/0xf0
      [464.603]  ? __pfx___filemap_fdatawrite_range+0x10/0x10
      [464.611]  ? trace_irq_enable.constprop.0+0xce/0x110
      [464.618]  ? kasan_quarantine_put+0xd7/0x1e0
      [464.625]  btrfs_start_ordered_extent+0x46f/0x570 [btrfs]
      [464.633]  ? __pfx_btrfs_start_ordered_extent+0x10/0x10 [btrfs]
      [464.642]  ? __clear_extent_bit+0x2c0/0x9d0 [btrfs]
      [464.650]  btrfs_lock_and_flush_ordered_range+0xc6/0x180 [btrfs]
      [464.659]  ? __pfx_btrfs_lock_and_flush_ordered_range+0x10/0x10 [btrfs]
      [464.669]  btrfs_read_folio+0x12a/0x1d0 [btrfs]
      [464.676]  ? __pfx_btrfs_read_folio+0x10/0x10 [btrfs]
      [464.684]  ? __pfx_filemap_add_folio+0x10/0x10
      [464.691]  ? __pfx___might_resched+0x10/0x10
      [464.698]  ? __filemap_get_folio+0x1c5/0x450
      [464.705]  prepare_uptodate_page+0x12e/0x4d0 [btrfs]
      [464.713]  prepare_pages.constprop.0+0x13c/0x5c0 [btrfs]
      [464.721]  ? fault_in_iov_iter_readable+0xd2/0x240
      [464.729]  btrfs_buffered_write+0x5bd/0x12f0 [btrfs]
      [464.737]  ? __pfx_btrfs_buffered_write+0x10/0x10 [btrfs]
      [464.745]  ? __pfx_lock_release+0x10/0x10
      [464.752]  ? generic_write_checks+0x275/0x400
      [464.759]  ? down_write+0x118/0x1f0
      [464.765]  ? up_write+0x19b/0x500
      [464.770]  btrfs_direct_write+0x731/0xba0 [btrfs]
      [464.778]  ? __pfx_btrfs_direct_write+0x10/0x10 [btrfs]
      [464.785]  ? __pfx___might_resched+0x10/0x10
      [464.792]  ? lock_acquire+0x435/0x500
      [464.798]  ? lock_acquire+0x435/0x500
      [464.804]  btrfs_do_write_iter+0x494/0x640 [btrfs]
      [464.811]  ? __pfx_btrfs_do_write_iter+0x10/0x10 [btrfs]
      [464.819]  ? __pfx___might_resched+0x10/0x10
      [464.825]  ? rw_verify_area+0x6d/0x590
      [464.831]  vfs_write+0x5d7/0xf50
      [464.837]  ? __might_fault+0x9d/0x120
      [464.843]  ? __pfx_vfs_write+0x10/0x10
      [464.849]  ? btrfs_file_llseek+0xb1/0xfb0 [btrfs]
      [464.856]  ? lock_release+0x567/0x790
      [464.862]  ksys_write+0xfb/0x1d0
      [464.867]  ? __pfx_ksys_write+0x10/0x10
      [464.873]  ? _raw_spin_unlock+0x23/0x40
      [464.879]  ? btrfs_getattr+0x4af/0x670 [btrfs]
      [464.886]  ? vfs_getattr_nosec+0x79/0x340
      [464.892]  do_syscall_64+0x95/0x180
      [464.898]  ? __do_sys_newfstat+0xde/0xf0
      [464.904]  ? __pfx___do_sys_newfstat+0x10/0x10
      [464.911]  ? trace_irq_enable.constprop.0+0xce/0x110
      [464.918]  ? syscall_exit_to_user_mode+0xac/0x2a0
      [464.925]  ? do_syscall_64+0xa1/0x180
      [464.931]  ? trace_irq_enable.constprop.0+0xce/0x110
      [464.939]  ? trace_irq_enable.constprop.0+0xce/0x110
      [464.946]  ? syscall_exit_to_user_mode+0xac/0x2a0
      [464.953]  ? btrfs_file_llseek+0xb1/0xfb0 [btrfs]
      [464.960]  ? do_syscall_64+0xa1/0x180
      [464.966]  ? btrfs_file_llseek+0xb1/0xfb0 [btrfs]
      [464.973]  ? trace_irq_enable.constprop.0+0xce/0x110
      [464.980]  ? syscall_exit_to_user_mode+0xac/0x2a0
      [464.987]  ? __pfx_btrfs_file_llseek+0x10/0x10 [btrfs]
      [464.995]  ? trace_irq_enable.constprop.0+0xce/0x110
      [465.002]  ? __pfx_btrfs_file_llseek+0x10/0x10 [btrfs]
      [465.010]  ? do_syscall_64+0xa1/0x180
      [465.016]  ? lock_release+0x567/0x790
      [465.022]  ? __pfx_lock_acquire+0x10/0x10
      [465.028]  ? __pfx_lock_release+0x10/0x10
      [465.034]  ? trace_irq_enable.constprop.0+0xce/0x110
      [465.042]  ? syscall_exit_to_user_mode+0xac/0x2a0
      [465.049]  ? do_syscall_64+0xa1/0x180
      [465.055]  ? syscall_exit_to_user_mode+0xac/0x2a0
      [465.062]  ? do_syscall_64+0xa1/0x180
      [465.068]  ? syscall_exit_to_user_mode+0xac/0x2a0
      [465.075]  ? do_syscall_64+0xa1/0x180
      [465.081]  ? clear_bhb_loop+0x25/0x80
      [465.087]  ? clear_bhb_loop+0x25/0x80
      [465.093]  ? clear_bhb_loop+0x25/0x80
      [465.099]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
      [465.106] RIP: 0033:0x7f093b8ee784
      [465.111] RSP: 002b:00007ffc29d31b28 EFLAGS: 00000202 ORIG_RAX: 0000000000000001
      [465.122] RAX: ffffffffffffffda RBX: 0000000000006000 RCX: 00007f093b8ee784
      [465.131] RDX: 000000000001de00 RSI: 00007f093b6ed200 RDI: 0000000000000003
      [465.141] RBP: 000000000001de00 R08: 0000000000006000 R09: 0000000000000000
      [465.150] R10: 0000000000023e00 R11: 0000000000000202 R12: 0000000000006000
      [465.160] R13: 0000000000023e00 R14: 0000000000023e00 R15: 0000000000000001
      [465.170]  </TASK>
      [465.174] INFO: lockdep is turned off.
    Reported-by: default avatarShinichiro Kawasaki <shinichiro.kawasaki@wdc.com>
    Fixes: 97713b1a ("btrfs: do not clear page dirty inside extent_write_locked_range()")
    Reviewed-by: default avatarQu Wenruo <wqu@suse.com>
    Signed-off-by: default avatarNaohiro Aota <naohiro.aota@wdc.com>
    Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
    6252690f
extent_io.c 123 KB