1. 18 10月, 2013 1 次提交
  2. 17 10月, 2013 1 次提交
    • D
      xfs: prevent deadlock trying to cover an active log · 2c6e24ce
      Dave Chinner 提交于
      Recent analysis of a deadlocked XFS filesystem from a kernel
      crash dump indicated that the filesystem was stuck waiting for log
      space. The short story of the hang on the RHEL6 kernel is this:
      
      	- the tail of the log is pinned by an inode
      	- the inode has been pushed by the xfsaild
      	- the inode has been flushed to it's backing buffer and is
      	  currently flush locked and hence waiting for backing
      	  buffer IO to complete and remove it from the AIL
      	- the backing buffer is marked for write - it is on the
      	  delayed write queue
      	- the inode buffer has been modified directly and logged
      	  recently due to unlinked inode list modification
      	- the backing buffer is pinned in memory as it is in the
      	  active CIL context.
      	- the xfsbufd won't start buffer writeback because it is
      	  pinned
      	- xfssyncd won't force the log because it sees the log as
      	  needing to be covered and hence wants to issue a dummy
      	  transaction to move the log covering state machine along.
      
      Hence there is no trigger to force the CIL to the log and hence
      unpin the inode buffer and therefore complete the inode IO, remove
      it from the AIL and hence move the tail of the log along, allowing
      transactions to start again.
      
      Mainline kernels also have the same deadlock, though the signature
      is slightly different - the inode buffer never reaches the delayed
      write lists because xfs_buf_item_push() sees that it is pinned and
      hence never adds it to the delayed write list that the xfsaild
      flushes.
      
      There are two possible solutions here. The first is to simply force
      the log before trying to cover the log and so ensure that the CIL is
      emptied before we try to reserve space for the dummy transaction in
      the xfs_log_worker(). While this might work most of the time, it is
      still racy and is no guarantee that we don't get stuck in
      xfs_trans_reserve waiting for log space to come free. Hence it's not
      the best way to solve the problem.
      
      The second solution is to modify xfs_log_need_covered() to be aware
      of the CIL. We only should be attempting to cover the log if there
      is no current activity in the log - covering the log is the process
      of ensuring that the head and tail in the log on disk are identical
      (i.e. the log is clean and at idle). Hence, by definition, if there
      are items in the CIL then the log is not at idle and so we don't
      need to attempt to cover it.
      
      When we don't need to cover the log because it is active or idle, we
      issue a log force from xfs_log_worker() - if the log is idle, then
      this does nothing.  However, if the log is active due to there being
      items in the CIL, it will force the items in the CIL to the log and
      unpin them.
      
      In the case of the above deadlock scenario, instead of
      xfs_log_worker() getting stuck in xfs_trans_reserve() attempting to
      cover the log, it will instead force the log, thereby unpinning the
      inode buffer, allowing IO to be issued and complete and hence
      removing the inode that was pinning the tail of the log from the
      AIL. At that point, everything will start moving along again. i.e.
      the xfs_log_worker turns back into a watchdog that can alleviate
      deadlocks based around pinned items that prevent the tail of the log
      from being moved...
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NEric Sandeen <sandeen@redhat.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      2c6e24ce
  3. 10 9月, 2013 1 次提交
  4. 21 8月, 2013 2 次提交
  5. 13 8月, 2013 2 次提交
  6. 23 7月, 2013 1 次提交
    • C
      xfs: Fix a deadlock in xfs_log_commit_cil() code path · 297aa637
      Chandra Seetharaman 提交于
      While testing and rearranging pquota/gquota code, I stumbled
      on a xfs_shutdown() during a mount. But the mount just hung.
      
      Debugged and found that there is a deadlock involving
      &log->l_cilp->xc_ctx_lock.
      
      It is in a code path where &log->l_cilp->xc_ctx_lock is first
      acquired in read mode and some levels down the same semaphore
      is being acquired in write mode causing a deadlock.
      
      This is the stack:
      xfs_log_commit_cil -> acquires &log->l_cilp->xc_ctx_lock in read mode
        xlog_print_tic_res
          xfs_force_shutdown
            xfs_log_force_umount
              xlog_cil_force
                xlog_cil_force_lsn
                  xlog_cil_push_foreground
                    xlog_cil_push - tries to acquire same semaphore in write mode
      
      This patch fixes the deadlock by changing the reason code for
      xfs_force_shutdown in xlog_print_tic_res() to SHUTDOWN_LOG_IO_ERROR.
      
      SHUTDOWN_LOG_IO_ERROR is the right reason code to be set since
      we are in the log path.
      
      Thanks to Dave for suggesting this solution.
      Signed-off-by: NChandra Seetharaman <sekharan@us.ibm.com>
      Reviewed-by: NBen Myers <bpm@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      297aa637
  7. 28 6月, 2013 1 次提交
    • D
      xfs: Introduce ordered log vector support · fd63875c
      Dave Chinner 提交于
      And "ordered log vector" is a log vector that is used for
      tracking a log item through the CIL and into the AIL as part of the
      log checkpointing. These ordered log vectors are special in that
      they are not written to to journal in any way, and are not accounted
      to the checkpoint being written.
      
      The reason for this behaviour is to allow operations to attach items
      to transactions and have them follow the normal transactional
      lifecycle without actually having to write them to the journal. This
      allows logging of items that track high level logical changes and
      writing them to the log, while the physical items being modified
      pass through into the AIL and pin the tail of the log (and therefore
      the logical item in the log) until all the modified items are
      physically written to disk.
      
      IOWs, it allows us to write metadata without physically logging
      every individual change but still maintain the full transactional
      integrity guarantees we currently have w.r.t. crash recovery.
      
      This change modifies some of the CIL item insertion loops, as
      ordered log vectors introduce some new constraints as they don't
      track any data. One advantage of this change is that it combines
      two log vector chain walks into a single pass, so there is less
      overhead in the transaction commit pass as well. It also kills some
      unused code in the log vector walk loop when committing the CIL.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      fd63875c
  8. 08 3月, 2013 1 次提交
  9. 19 1月, 2013 1 次提交
  10. 18 1月, 2013 1 次提交
  11. 04 12月, 2012 1 次提交
    • D
      xfs: fix sparse reported log CRC endian issue · f9668a09
      Dave Chinner 提交于
      Not a bug as such, just warning noise from the xlog_cksum()
      returning a __be32 type when it should be returning a __le32 type.
      
      On Wed, Nov 28, 2012 at 08:30:59AM -0500, Christoph Hellwig wrote:
      > But why are we storing the crc field little endian while all other on
      > disk formats are big endian? (And yes I realize it might as well have
      > been me who did that back in the idea, but I still have no idea why)
      
      Because the CRC always returns the calcuation LE format, even on BE
      systems. So rather than always having to byte swap it everywhere and
      have all the force casts and anootations for sparse, it seems simpler to
      just make it a __le32 everywhere....
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NBen Myers <bpm@sgi.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      f9668a09
  12. 30 11月, 2012 1 次提交
    • D
      xfs: fix direct IO nested transaction deadlock. · 437a255a
      Dave Chinner 提交于
      The direct IO path can do a nested transaction reservation when
      writing past the EOF. The first transaction is the append
      transaction for setting the filesize at IO completion, but we can
      also need a transaction for allocation of blocks. If the log is low
      on space due to reservations and small log, the append transaction
      can be granted after wating for space as the only active transaction
      in the system. This then attempts a reservation for an allocation,
      which there isn't space in the log for, and the reservation sleeps.
      The result is that there is nothing left in the system to wake up
      all the processes waiting for log space to come free.
      
      The stack trace that shows this deadlock is relatively innocuous:
      
       xlog_grant_head_wait
       xlog_grant_head_check
       xfs_log_reserve
       xfs_trans_reserve
       xfs_iomap_write_direct
       __xfs_get_blocks
       xfs_get_blocks_direct
       do_blockdev_direct_IO
       __blockdev_direct_IO
       xfs_vm_direct_IO
       generic_file_direct_write
       xfs_file_dio_aio_writ
       xfs_file_aio_write
       do_sync_write
       vfs_write
      
      This was discovered on a filesystem with a log of only 10MB, and a
      log stripe unit of 256k whih increased the base reservations by
      512k. Hence a allocation transaction requires 1.2MB of log space to
      be available instead of only 260k, and so greatly increased the
      chance that there wouldn't be enough log space available for the
      nested transaction to succeed. The key to reproducing it is this
      mkfs command:
      
      mkfs.xfs -f -d agcount=16,su=256k,sw=12 -l su=256k,size=2560b $SCRATCH_DEV
      
      The test case was a 1000 fsstress processes running with random
      freeze and unfreezes every few seconds. Thanks to Eryu Guan
      (eguan@redhat.com) for writing the test that found this on a system
      with a somewhat unique default configuration....
      
      cc: <stable@vger.kernel.org>
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NAndrew Dahl <adahl@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      437a255a
  13. 20 11月, 2012 1 次提交
    • C
      xfs: add CRC checks to the log · 0e446be4
      Christoph Hellwig 提交于
      Implement CRCs for the log buffers.  We re-use a field in
      struct xlog_rec_header that was used for a weak checksum of the
      log buffer payload in debug builds before.
      
      The new checksumming uses the crc32c checksum we will use elsewhere
      in XFS, and also protects the record header and addition cycle data.
      
      Due to this there are some interesting changes in xlog_sync, as we
      need to do the cycle wrapping for the split buffer case much earlier,
      as we would touch the buffer after generating the checksum otherwise.
      
      The CRC calculation is always enabled, even for non-CRC filesystems,
      as adding this CRC does not change the log format. On non-CRC
      filesystems, only issue an alert if a CRC mismatch is found and
      allow recovery to continue - this will act as an indicator that
      log recovery problems are a result of log corruption. On CRC enabled
      filesystems, however, log recovery will fail.
      
      Note that existing debug kernels will write a simple checksum value
      to the log, so the first time this is run on a filesystem taht was
      last used on a debug kernel it will through CRC mismatch warning
      errors. These can be ignored.
      
      Initially based on a patch from Dave Chinner, then modified
      significantly by Christoph Hellwig.  Modified again by Dave Chinner
      to get to this version.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      0e446be4
  14. 16 11月, 2012 1 次提交
    • D
      xfs: make buffer read verication an IO completion function · c3f8fc73
      Dave Chinner 提交于
      Add a verifier function callback capability to the buffer read
      interfaces.  This will be used by the callers to supply a function
      that verifies the contents of the buffer when it is read from disk.
      This patch does not provide callback functions, but simply modifies
      the interfaces to allow them to be called.
      
      The reason for adding this to the read interfaces is that it is very
      difficult to tell fom the outside is a buffer was just read from
      disk or whether we just pulled it out of cache. Supplying a callbck
      allows the buffer cache to use it's internal knowledge of the buffer
      to execute it only when the buffer is read from disk.
      
      It is intended that the verifier functions will mark the buffer with
      an EFSCORRUPTED error when verification fails. This allows the
      reading context to distinguish a verification error from an IO
      error, and potentially take further actions on the buffer (e.g.
      attempt repair) based on the error reported.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NPhil White <pwhite@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      c3f8fc73
  15. 09 11月, 2012 1 次提交
    • D
      xfs: only update the last_sync_lsn when a transaction completes · 7e9620f2
      Dave Chinner 提交于
      The log write code stamps each iclog with the current tail LSN in
      the iclog header so that recovery knows where to find the tail of
      thelog once it has found the head. Normally this is taken from the
      first item on the AIL - the log item that corresponds to the oldest
      active item in the log.
      
      The problem is that when the AIL is empty, the tail lsn is dervied
      from the the l_last_sync_lsn, which is the LSN of the last iclog to
      be written to the log. In most cases this doesn't happen, because
      the AIL is rarely empty on an active filesystem. However, when it
      does, it opens up an interesting case when the transaction being
      committed to the iclog spans multiple iclogs.
      
      That is, the first iclog is stamped with the l_last_sync_lsn, and IO
      is issued. Then the next iclog is setup, the changes copied into the
      iclog (takes some time), and then the l_last_sync_lsn is stamped
      into the header and IO is issued. This is still the same
      transaction, so the tail lsn of both iclogs must be the same for log
      recovery to find the entire transaction to be able to replay it.
      
      The problem arises in that the iclog buffer IO completion updates
      the l_last_sync_lsn with it's own LSN. Therefore, If the first iclog
      completes it's IO before the second iclog is filled and has the tail
      lsn stamped in it, it will stamp the LSN of the first iclog into
      it's tail lsn field. If the system fails at this point, log recovery
      will not see a complete transaction, so the transaction will no be
      replayed.
      
      The fix is simple - the l_last_sync_lsn is updated when a iclog
      buffer IO completes, and this is incorrect. The l_last_sync_lsn
      shoul dbe updated when a transaction is completed by a iclog buffer
      IO. That is, only iclog buffers that have transaction commit
      callbacks attached to them should update the l_last_sync_lsn. This
      means that the last_sync_lsn will only move forward when a commit
      record it written, not in the middle of a large transaction that is
      rolling through multiple iclog buffers.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      7e9620f2
  16. 18 10月, 2012 5 次提交
    • D
      xfs: only update the last_sync_lsn when a transaction completes · d35e88fa
      Dave Chinner 提交于
      The log write code stamps each iclog with the current tail LSN in
      the iclog header so that recovery knows where to find the tail of
      thelog once it has found the head. Normally this is taken from the
      first item on the AIL - the log item that corresponds to the oldest
      active item in the log.
      
      The problem is that when the AIL is empty, the tail lsn is dervied
      from the the l_last_sync_lsn, which is the LSN of the last iclog to
      be written to the log. In most cases this doesn't happen, because
      the AIL is rarely empty on an active filesystem. However, when it
      does, it opens up an interesting case when the transaction being
      committed to the iclog spans multiple iclogs.
      
      That is, the first iclog is stamped with the l_last_sync_lsn, and IO
      is issued. Then the next iclog is setup, the changes copied into the
      iclog (takes some time), and then the l_last_sync_lsn is stamped
      into the header and IO is issued. This is still the same
      transaction, so the tail lsn of both iclogs must be the same for log
      recovery to find the entire transaction to be able to replay it.
      
      The problem arises in that the iclog buffer IO completion updates
      the l_last_sync_lsn with it's own LSN. Therefore, If the first iclog
      completes it's IO before the second iclog is filled and has the tail
      lsn stamped in it, it will stamp the LSN of the first iclog into
      it's tail lsn field. If the system fails at this point, log recovery
      will not see a complete transaction, so the transaction will no be
      replayed.
      
      The fix is simple - the l_last_sync_lsn is updated when a iclog
      buffer IO completes, and this is incorrect. The l_last_sync_lsn
      shoul dbe updated when a transaction is completed by a iclog buffer
      IO. That is, only iclog buffers that have transaction commit
      callbacks attached to them should update the l_last_sync_lsn. This
      means that the last_sync_lsn will only move forward when a commit
      record it written, not in the middle of a large transaction that is
      rolling through multiple iclog buffers.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      d35e88fa
    • D
      xfs: xfs_quiesce_attr() should quiesce the log like unmount · c75921a7
      Dave Chinner 提交于
      xfs_quiesce_attr() is supposed to leave the log empty with an
      unmount record written. Right now it does not wait for the AIL to be
      emptied before writing the unmount record, not does it wait for
      metadata IO completion, either. Fix it to use the same method and
      code as xfs_log_unmount().
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      c75921a7
    • D
      xfs: syncd workqueue is no more · 5889608d
      Dave Chinner 提交于
      With the syncd functions moved to the log and/or removed, the syncd
      workqueue is the only remaining bit left. It is used by the log
      covering/ail pushing work, as well as by the inode reclaim work.
      
      Given how cheap workqueues are these days, give the log and inode
      reclaim work their own work queues and kill the syncd work queue.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      5889608d
    • D
      xfs: Bring some sanity to log unmounting · cf2931db
      Dave Chinner 提交于
      When unmounting the filesystem, there are lots of operations that
      need to be done in a specific order, and they are spread across
      across a couple of functions. We have to drain the AIL before we
      write the unmount record, and we have to shut down the background
      log work before we do either of them.
      
      But this is all split haphazardly across xfs_unmountfs() and
      xfs_log_unmount(). Move all the AIL flushing and log manipulations
      to xfs_log_unmount() so that the responisbilities of each function
      is clear and the operations they perform obvious.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      cf2931db
    • D
      xfs: sync work is now only periodic log work · f661f1e0
      Dave Chinner 提交于
      The only thing the periodic sync work does now is flush the AIL and
      idle the log. These are really functions of the log code, so move
      the work to xfs_log.c and rename it appropriately.
      
      The only wart that this leaves behind is the xfssyncd_centisecs
      sysctl, otherwise the xfssyncd is dead. Clean up any comments that
      related to xfssyncd to reflect it's passing.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      f661f1e0
  17. 22 6月, 2012 5 次提交
  18. 30 5月, 2012 1 次提交
  19. 21 5月, 2012 1 次提交
    • D
      xfs: add trace points for log forces · 14c26c6a
      Dave Chinner 提交于
      To enable easy tracing of the location of log forces and the
      frequency of them via perf, add a pair of trace points to the log
      force functions.  This will help debug where excessive log forces
      are being issued from by simple perf commands like:
      
      # ~/perf/perf top -e xfs:xfs_log_force -G -U
      
      Which gives this sort of output:
      
      Events: 141  xfs:xfs_log_force
      -  100.00%  [kernel]  [k] xfs_log_force
         - xfs_log_force
              87.04% xfsaild
                 kthread
                 kernel_thread_helper
            - 12.87% xfs_buf_lock
                 _xfs_buf_find
                 xfs_buf_get
                 xfs_trans_get_buf
                 xfs_da_do_buf
                 xfs_da_get_buf
                 xfs_dir2_data_init
                 xfs_dir2_leaf_addname
                 xfs_dir_createname
                 xfs_create
                 xfs_vn_mknod
                 xfs_vn_create
                 vfs_create
                 do_last.isra.41
                 path_openat
                 do_filp_open
                 do_sys_open
                 sys_open
                 system_call_fastpath
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Signed-off-by: NBen Myers <bpm@sig.com>
      14c26c6a
  20. 15 5月, 2012 7 次提交
  21. 27 3月, 2012 1 次提交
    • D
      xfs: Account log unmount transaction correctly · 3948659e
      Dave Chinner 提交于
      There have been a few reports of this warning appearing recently:
      
      XFS (dm-4): xlog_space_left: head behind tail
       tail_cycle = 129, tail_bytes = 20163072
       GH   cycle = 129, GH   bytes = 20162880
      
      The common cause appears to be lots of freeze and unfreeze cycles,
      and the output from the warnings indicates that we are leaking
      around 8 bytes of log space per freeze/unfreeze cycle.
      
      When we freeze the filesystem, we write an unmount record and that
      uses xlog_write directly - a special type of transaction,
      effectively. What it doesn't do, however, is correctly account for
      the log space it uses. The unmount record writes an 8 byte structure
      with a special magic number into the log, and the space this
      consumes is not accounted for in the log ticket tracking the
      operation. Hence we leak 8 bytes every unmount record that is
      written.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      3948659e
  22. 23 2月, 2012 3 次提交