1. 23 3月, 2020 7 次提交
  2. 14 3月, 2020 3 次提交
  3. 03 3月, 2020 1 次提交
    • B
      xfs: fix iclog release error check race with shutdown · 6b789c33
      Brian Foster 提交于
      Prior to commit df732b29 ("xfs: call xlog_state_release_iclog with
      l_icloglock held"), xlog_state_release_iclog() always performed a
      locked check of the iclog error state before proceeding into the
      sync state processing code. As of this commit, part of
      xlog_state_release_iclog() was open-coded into
      xfs_log_release_iclog() and as a result the locked error state check
      was lost.
      
      The lockless check still exists, but this doesn't account for the
      possibility of a race with a shutdown being performed by another
      task causing the iclog state to change while the original task waits
      on ->l_icloglock. This has reproduced very rarely via generic/475
      and manifests as an assert failure in __xlog_state_release_iclog()
      due to an unexpected iclog state.
      
      Restore the locked error state check in xlog_state_release_iclog()
      to ensure that an iclog state update via shutdown doesn't race with
      the iclog release state processing code.
      
      Fixes: df732b29 ("xfs: call xlog_state_release_iclog with l_icloglock held")
      Reported-by: NZorro Lang <zlang@redhat.com>
      Signed-off-by: NBrian Foster <bfoster@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      6b789c33
  4. 04 12月, 2019 1 次提交
    • B
      xfs: fix mount failure crash on invalid iclog memory access · 798a9cad
      Brian Foster 提交于
      syzbot (via KASAN) reports a use-after-free in the error path of
      xlog_alloc_log(). Specifically, the iclog freeing loop doesn't
      handle the case of a fully initialized ->l_iclog linked list.
      Instead, it assumes that the list is partially constructed and NULL
      terminated.
      
      This bug manifested because there was no possible error scenario
      after iclog list setup when the original code was added.  Subsequent
      code and associated error conditions were added some time later,
      while the original error handling code was never updated. Fix up the
      error loop to terminate either on a NULL iclog or reaching the end
      of the list.
      
      Reported-by: syzbot+c732f8644185de340492@syzkaller.appspotmail.com
      Signed-off-by: NBrian Foster <bfoster@redhat.com>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      798a9cad
  5. 19 11月, 2019 1 次提交
  6. 11 11月, 2019 1 次提交
  7. 06 11月, 2019 1 次提交
  8. 22 10月, 2019 7 次提交
  9. 07 10月, 2019 1 次提交
  10. 06 9月, 2019 7 次提交
    • D
      xfs: push the grant head when the log head moves forward · 14e15f1b
      Dave Chinner 提交于
      When the log fills up, we can get into the state where the
      outstanding items in the CIL being committed and aggregated are
      larger than the range that the reservation grant head tail pushing
      will attempt to clean. This can result in the tail pushing range
      being trimmed back to the the log head (l_last_sync_lsn) and so
      may not actually move the push target at all.
      
      When the iclogs associated with the CIL commit finally land, the
      log head moves forward, and this removes the restriction on the AIL
      push target. However, if we already have transactions sleeping on
      the grant head, and there's nothing in the AIL still to flush from
      the current push target, then nothing will move the tail of the log
      and trigger a log reservation wakeup.
      
      Hence the there is nothing that will trigger xlog_grant_push_ail()
      to recalculate the AIL push target and start pushing on the AIL
      again to write back the metadata objects that pin the tail of the
      log and hence free up space and allow the transaction reservations
      to be woken and make progress.
      
      Hence we need to push on the grant head when we move the log head
      forward, as this may be the only trigger we have that can move the
      AIL push target forwards in this situation.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      14e15f1b
    • D
      xfs: push iclog state cleaning into xlog_state_clean_log · 0383f543
      Dave Chinner 提交于
      xlog_state_clean_log() is only called from one place, and it occurs
      when an iclog is transitioning back to ACTIVE. Prior to calling
      xlog_state_clean_log, the iclog we are processing has a hard coded
      state check to DIRTY so that xlog_state_clean_log() processes it
      correctly. We also have a hard coded wakeup after
      xlog_state_clean_log() to enfore log force waiters on that iclog
      are woken correctly.
      
      Both of these things are operations required to finish processing an
      iclog and return it to the ACTIVE state again, so they make little
      sense to be separated from the rest of the clean state transition
      code.
      
      Hence push these things inside xlog_state_clean_log(), document the
      behaviour and rename it xlog_state_clean_iclog() to indicate that
      it's being driven by an iclog state change and does the iclog state
      change work itself.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      0383f543
    • D
      xfs: factor iclog state processing out of xlog_state_do_callback() · 5e96fa8d
      Dave Chinner 提交于
      The iclog IO completion state processing is somewhat complex, and
      because it's inside two nested loops it is highly indented and very
      hard to read. Factor it out, flatten the logic flow and clean up the
      comments so that it much easier to see what the code is doing both
      in processing the individual iclogs and in the over
      xlog_state_do_callback() operation.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      5e96fa8d
    • D
      xfs: factor callbacks out of xlog_state_do_callback() · 6546818c
      Dave Chinner 提交于
      Simplify the code flow by lifting the iclog callback work out of
      the main iclog iteration loop. This isolates the log juggling and
      callbacks from the iclog state change logic in the loop.
      
      Note that the loopdidcallbacks variable is not actually tracking
      whether callbacks are actually run - it is tracking whether the
      icloglock was dropped during the loop and so determines if we
      completed the entire iclog scan loop atomically. Hence we know for
      certain there are either no more ordered completions to run or
      that the next completion will run the remaining ordered iclog
      completions. Hence rename that variable appropriately for it's
      function.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      6546818c
    • D
      xfs: factor debug code out of xlog_state_do_callback() · 6769aa2a
      Dave Chinner 提交于
      Start making this function readable by lifting the debug code into
      a conditional function.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      6769aa2a
    • R
      xfs: fix missed wakeup on l_flush_wait · cdea5459
      Rik van Riel 提交于
      The code in xlog_wait uses the spinlock to make adding the task to
      the wait queue, and setting the task state to UNINTERRUPTIBLE atomic
      with respect to the waker.
      
      Doing the wakeup after releasing the spinlock opens up the following
      race condition:
      
      Task 1					task 2
      add task to wait queue
      					wake up task
      set task state to UNINTERRUPTIBLE
      
      This issue was found through code inspection as a result of kworkers
      being observed stuck in UNINTERRUPTIBLE state with an empty
      wait queue. It is rare and largely unreproducable.
      
      Simply moving the spin_unlock to after the wake_up_all results
      in the waker not being able to see a task on the waitqueue before
      it has set its state to UNINTERRUPTIBLE.
      
      This bug dates back to the conversion of this code to generic
      waitqueue infrastructure from a counting semaphore back in 2008
      which didn't place the wakeups consistently w.r.t. to the relevant
      spin locks.
      
      [dchinner: Also fix a similar issue in the shutdown path on
      xc_commit_wait. Update commit log with more details of the issue.]
      
      Fixes: d748c623 ("[XFS] Convert l_flushsema to a sv_t")
      Reported-by: NChris Mason <clm@fb.com>
      Signed-off-by: NRik van Riel <riel@surriel.com>
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      cdea5459
    • D
      xfs: push the AIL in xlog_grant_head_wake · 7c107afb
      Dave Chinner 提交于
      In the situation where the log is full and the CIL has not recently
      flushed, the AIL push threshold is throttled back to the where the
      last write of the head of the log was completed. This is stored in
      log->l_last_sync_lsn. Hence if the CIL holds > 25% of the log space
      pinned by flushes and/or aggregation in progress, we can get the
      situation where the head of the log lags a long way behind the
      reservation grant head.
      
      When this happens, the AIL push target is trimmed back from where
      the reservation grant head wants to push the log tail to, back to
      where the head of the log currently is. This means the push target
      doesn't reach far enough into the log to actually move the tail
      before the transaction reservation goes to sleep.
      
      When the CIL push completes, it moves the log head forward such that
      the AIL push target can now be moved, but that has no mechanism for
      puhsing the log tail. Further, if the next tail movement of the log
      is not large enough wake the waiter (i.e. still not enough space for
      it to have a reservation granted), we don't wake anything up, and
      hence we do not update the AIL push target to take into account the
      head of the log moving and allowing the push target to be moved
      forwards.
      
      To avoid this particular condition, if we fail to wake the first
      waiter on the grant head because we don't have enough space,
      push on the AIL again. This will pick up any movement of the log
      head and allow the push target to move forward due to completion of
      CIL pushing.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      7c107afb
  11. 27 8月, 2019 2 次提交
    • D
      xfs: add kmem_alloc_io() · f8f9ee47
      Dave Chinner 提交于
      Memory we use to submit for IO needs strict alignment to the
      underlying driver contraints. Worst case, this is 512 bytes. Given
      that all allocations for IO are always a power of 2 multiple of 512
      bytes, the kernel heap provides natural alignment for objects of
      these sizes and that suffices.
      
      Until, of course, memory debugging of some kind is turned on (e.g.
      red zones, poisoning, KASAN) and then the alignment of the heap
      objects is thrown out the window. Then we get weird IO errors and
      data corruption problems because drivers don't validate alignment
      and do the wrong thing when passed unaligned memory buffers in bios.
      
      TO fix this, introduce kmem_alloc_io(), which will guaranteeat least
      512 byte alignment of buffers for IO, even if memory debugging
      options are turned on. It is assumed that the minimum allocation
      size will be 512 bytes, and that sizes will be power of 2 mulitples
      of 512 bytes.
      
      Use this everywhere we allocate buffers for IO.
      
      This no longer fails with log recovery errors when KASAN is enabled
      due to the brd driver not handling unaligned memory buffers:
      
      # mkfs.xfs -f /dev/ram0 ; mount /dev/ram0 /mnt/test
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      f8f9ee47
    • T
      fs: xfs: Remove KM_NOSLEEP and KM_SLEEP. · 707e0dda
      Tetsuo Handa 提交于
      Since no caller is using KM_NOSLEEP and no callee branches on KM_SLEEP,
      we can remove KM_NOSLEEP and replace KM_SLEEP with 0.
      Signed-off-by: NTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      707e0dda
  12. 04 8月, 2019 1 次提交
    • T
      fs: xfs: xfs_log: Don't use KM_MAYFAIL at xfs_log_reserve(). · 294fc7a4
      Tetsuo Handa 提交于
      When the system is close-to-OOM, fsync() may fail due to -ENOMEM because
      xfs_log_reserve() is using KM_MAYFAIL. It is a bad thing to fail writeback
      operation due to user-triggerable OOM condition. Since we are not using
      KM_MAYFAIL at xfs_trans_alloc() before calling xfs_log_reserve(), let's
      use the same flags at xfs_log_reserve().
      
        oom-torture: page allocation failure: order:0, mode:0x46c40(GFP_NOFS|__GFP_NOWARN|__GFP_RETRY_MAYFAIL|__GFP_COMP), nodemask=(null)
        CPU: 7 PID: 1662 Comm: oom-torture Kdump: loaded Not tainted 5.3.0-rc2+ #925
        Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00
        Call Trace:
         dump_stack+0x67/0x95
         warn_alloc+0xa9/0x140
         __alloc_pages_slowpath+0x9a8/0xbce
         __alloc_pages_nodemask+0x372/0x3b0
         alloc_slab_page+0x3a/0x8d0
         new_slab+0x330/0x420
         ___slab_alloc.constprop.94+0x879/0xb00
         __slab_alloc.isra.89.constprop.93+0x43/0x6f
         kmem_cache_alloc+0x331/0x390
         kmem_zone_alloc+0x9f/0x110 [xfs]
         kmem_zone_alloc+0x9f/0x110 [xfs]
         xlog_ticket_alloc+0x33/0xd0 [xfs]
         xfs_log_reserve+0xb4/0x410 [xfs]
         xfs_trans_reserve+0x1d1/0x2b0 [xfs]
         xfs_trans_alloc+0xc9/0x250 [xfs]
         xfs_setfilesize_trans_alloc.isra.27+0x44/0xc0 [xfs]
         xfs_submit_ioend.isra.28+0xa5/0x180 [xfs]
         xfs_vm_writepages+0x76/0xa0 [xfs]
         do_writepages+0x17/0x80
         __filemap_fdatawrite_range+0xc1/0xf0
         file_write_and_wait_range+0x53/0xa0
         xfs_file_fsync+0x87/0x290 [xfs]
         vfs_fsync_range+0x37/0x80
         do_fsync+0x38/0x60
         __x64_sys_fsync+0xf/0x20
         do_syscall_64+0x4a/0x1c0
         entry_SYSCALL_64_after_hwframe+0x49/0xbe
      
      Fixes: eb01c9cd ("[XFS] Remove the xlog_ticket allocator")
      Signed-off-by: NTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      294fc7a4
  13. 03 7月, 2019 1 次提交
  14. 29 6月, 2019 6 次提交