1. 21 6月, 2012 1 次提交
    • A
      xfs: xfs_vm_writepage clear iomap_valid when !buffer_uptodate (REV2) · 66f93113
      Alain Renaud 提交于
      On filesytems with a block size smaller than PAGE_SIZE we currently have
      a problem with unwritten extents.  If a we have multi-block page for
      which an unwritten extent has been allocated, and only some of the
      buffers have been written to, and they are not contiguous, we can expose
      stale data from disk in the blocks between the writes after extent
      conversion.
      
      Example of a page with unwritten and real data.
      buffer  content
      0       empty  b_state = 0
      1       DATA   b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
      2       DATA   b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
      3       empty  b_state = 0
      4       empty  b_state = 0
      5       DATA   b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
      6       DATA   b_state = 0x1023 Uptodate,Dirty,Mapped,Unwritten
      7       empty  b_state = 0
      
      Buffers 1, 2, 5, and 6 have been written to, leaving 0, 3, 4, and 7
      empty.  Currently buffers 1, 2, 5, and 6 are added to a single ioend,
      and when IO has completed, extent conversion creates a real extent from
      block 1 through block 6, leaving 0 and 7 unwritten.  However buffers 3
      and 4 were not written to disk, so stale data is exposed from those
      blocks on a subsequent read.
      
      Fix this by setting iomap_valid = 0 when we find a buffer that is not
      Uptodate.  This ensures that buffers 5 and 6 are not added to the same
      ioend as buffers 1 and 2.  Later these blocks will be converted into two
      separate real extents, leaving the blocks in between unwritten.
      Signed-off-by: NAlain Renaud <arenaud@sgi.com>
      Reviewed-by: NDave Chinner <dchinner@redhat.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      66f93113
  2. 15 5月, 2012 8 次提交
    • D
      xfs: clean up xfs_bit.h includes · ad1e95c5
      Dave Chinner 提交于
      With the removal of xfs_rw.h and other changes over time, xfs_bit.h
      is being included in many files that don't actually need it. Clean
      up the includes as necessary.
      
      Also move the only-used-once xfs_ialloc_find_free() static inline
      function out of a header file that is widely included to reduce
      the number of needless dependencies on xfs_bit.h.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      ad1e95c5
    • D
      xfs: move xfs_get_extsz_hint() and kill xfs_rw.h · 2a0ec1d9
      Dave Chinner 提交于
      The only thing left in xfs_rw.h is a function prototype for an inode
      function.  Move that to xfs_inode.h, and kill xfs_rw.h.
      
      Also move the function implementing the prototype from xfs_rw.c to
      xfs_inode.c so we only have one function left in xfs_rw.c
      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>
      2a0ec1d9
    • D
      xfs: move xfsagino_t to xfs_types.h · 60a34607
      Dave Chinner 提交于
      Untangle the header file includes a bit by moving the definition of
      xfs_agino_t to xfs_types.h. This removes the dependency that xfs_ag.h has on
      xfs_inum.h, meaning we don't need to include xfs_inum.h everywhere we include
      xfs_ag.h.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      60a34607
    • D
      xfs: Use preallocation for inodes with extsz hints · aff3a9ed
      Dave Chinner 提交于
      xfstest 229 exposes a problem with buffered IO, delayed allocation
      and extent size hints. That is when we do delayed allocation during
      buffered IO, we reserve space for the extent size hint alignment and
      allocate the physical space to align the extent, but we do not zero
      the regions of the extent that aren't written by the write(2)
      syscall. The result is that we expose stale data in unwritten
      regions of the extent size hints.
      
      There are two ways to fix this. The first is to detect that we are
      doing unaligned writes, check if there is already a mapping or data
      over the extent size hint range, and if not zero the page cache
      first before then doing the real write. This can be very expensive
      for large extent size hints, especially if the subsequent writes
      fill then entire extent size before the data is written to disk.
      
      The second, and simpler way, is simply to turn off delayed
      allocation when the extent size hint is set and use preallocation
      instead. This results in unwritten extents being laid down on disk
      and so only the written portions will be converted. This matches the
      behaviour for direct IO, and will also work for the real time
      device. The disadvantage of this approach is that for small extent
      size hints we can get file fragmentation, but in general extent size
      hints are fairly large (e.g. stripe width sized) so this isn't a big
      deal.
      
      Implement the second approach as it is simple and effective.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      aff3a9ed
    • D
      xfs: punch new delalloc blocks out of failed writes inside EOF. · d3bc815a
      Dave Chinner 提交于
      When a partial write inside EOF fails, it can leave delayed
      allocation blocks lying around because they don't get punched back
      out. This leads to assert failures like:
      
      XFS: Assertion failed: XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0, file: fs/xfs/xfs_super.c, line: 847
      
      when evicting inodes from the cache. This can be trivially triggered
      by xfstests 083, which takes between 5 and 15 executions on a 512
      byte block size filesystem to trip over this. Debugging shows a
      failed write due to ENOSPC calling xfs_vm_write_failed such as:
      
      [ 5012.329024] ino 0xa0026: vwf to 0x17000, sze 0x1c85ae
      
      and no action is taken on it. This leaves behind a delayed
      allocation extent that has no page covering it and no data in it:
      
      [ 5015.867162] ino 0xa0026: blks: 0x83 delay blocks 0x1, size 0x2538c0
      [ 5015.868293] ext 0: off 0x4a, fsb 0x50306, len 0x1
      [ 5015.869095] ext 1: off 0x4b, fsb 0x7899, len 0x6b
      [ 5015.869900] ext 2: off 0xb6, fsb 0xffffffffe0008, len 0x1
                                          ^^^^^^^^^^^^^^^
      [ 5015.871027] ext 3: off 0x36e, fsb 0x7a27, len 0xd
      [ 5015.872206] ext 4: off 0x4cf, fsb 0x7a1d, len 0xa
      
      So the delayed allocation extent is one block long at offset
      0x16c00. Tracing shows that a bigger write:
      
      xfs_file_buffered_write: size 0x1c85ae offset 0x959d count 0x1ca3f ioflags
      
      allocates the block, and then fails with ENOSPC trying to allocate
      the last block on the page, leading to a failed write with stale
      delalloc blocks on it.
      
      Because we've had an ENOSPC when trying to allocate 0x16e00, it
      means that we are never goinge to call ->write_end on the page and
      so the allocated new buffer will not get marked dirty or have the
      buffer_new state cleared. In other works, what the above write is
      supposed to end up with is this mapping for the page:
      
          +------+------+------+------+------+------+------+------+
            UMA    UMA    UMA    UMA    UMA    UMA    UND    FAIL
      
      where:  U = uptodate
              M = mapped
              N = new
              A = allocated
              D = delalloc
              FAIL = block we ENOSPC'd on.
      
      and the key point being the buffer_new() state for the newly
      allocated delayed allocation block. Except it doesn't - we're not
      marking buffers new correctly.
      
      That buffer_new() problem goes back to the xfs_iomap removal days,
      where xfs_iomap() used to return a "new" status for any map with
      newly allocated blocks, so that __xfs_get_blocks() could call
      set_buffer_new() on it. We still have the "new" variable and the
      check for it in the set_buffer_new() logic - except we never set it
      now!
      
      Hence that newly allocated delalloc block doesn't have the new flag
      set on it, so when the write fails we cannot tell which blocks we
      are supposed to punch out. WHy do we need the buffer_new flag? Well,
      that's because we can have this case:
      
          +------+------+------+------+------+------+------+------+
            UMD    UMD    UMD    UMD    UMD    UMD    UND    FAIL
      
      where all the UMD buffers contain valid data from a previously
      successful write() system call. We only want to punch the UND buffer
      because that's the only one that we added in this write and it was
      only this write that failed.
      
      That implies that even the old buffer_new() logic was wrong -
      because it would result in all those UMD buffers on the page having
      set_buffer_new() called on them even though they aren't new. Hence
      we shoul donly be calling set_buffer_new() for delalloc buffers that
      were allocated (i.e. were a hole before xfs_iomap_write_delay() was
      called).
      
      So, fix this set_buffer_new logic according to how we need it to
      work for handling failed writes correctly. Also, restore the new
      buffer logic handling for blocks allocated via
      xfs_iomap_write_direct(), because it should still set the buffer_new
      flag appropriately for newly allocated blocks, too.
      
      SO, now we have the buffer_new() being set appropriately in
      __xfs_get_blocks(), we can detect the exact delalloc ranges that
      we allocated in a failed write, and hence can now do a walk of the
      buffers on a page to find them.
      
      Except, it's not that easy. When block_write_begin() fails, it
      unlocks and releases the page that we just had an error on, so we
      can't use that page to handle errors anymore. We have to get access
      to the page while it is still locked to walk the buffers. Hence we
      have to open code block_write_begin() in xfs_vm_write_begin() to be
      able to insert xfs_vm_write_failed() is the right place.
      
      With that, we can pass the page and write range to
      xfs_vm_write_failed() and walk the buffers on the page, looking for
      delalloc buffers that are either new or beyond EOF and punch them
      out. Handling buffers beyond EOF ensures we still handle the
      existing case that xfs_vm_write_failed() handles.
      
      Of special note is the truncate_pagecache() handling - that only
      should be done for pages outside EOF - pages within EOF can still
      contain valid, dirty data so we must not punch them out of the
      cache.
      
      That just leaves the xfs_vm_write_end() failure handling.
      The only failure case here is that we didn't copy the entire range,
      and generic_write_end() handles that by zeroing the region of the
      page that wasn't copied, we don't have to punch out blocks within
      the file because they are guaranteed to contain zeros. Hence we only
      have to handle the existing "beyond EOF" case and don't need access
      to the buffers on the page. Hence it remains largely unchanged.
      
      Note that xfs_getbmap() can still trip over delalloc blocks beyond
      EOF that are left there by speculative delayed allocation. Hence
      this bug fix does not solve all known issues with bmap vs delalloc,
      but it does fix all the the known accidental occurances of the
      problem.
      Signed-off-by: NDave Chinner <david@fromorbit.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      d3bc815a
    • D
      xfs: page type check in writeback only checks last buffer · 6ffc4db5
      Dave Chinner 提交于
      xfs_is_delayed_page() checks to see if a page has buffers matching
      the given IO type passed in. It does so by walking the buffer heads
      on the page and checking if the state flags match the IO type.
      
      However, the "acceptable" variable that is calculated is overwritten
      every time a new buffer is checked. Hence if the first buffer on the
      page is of the right type, this state is lost if the second buffer
      is not of the correct type. This means that xfs_aops_discard_page()
      may not discard delalloc regions when it is supposed to, and
      xfs_convert_page() may not cluster IO as efficiently as possible.
      
      This problem only occurs on filesystems with a block size smaller
      than page size.
      
      Also, rename xfs_is_delayed_page() to xfs_check_page_type() to
      better describe what it is doing - it is not delalloc specific
      anymore.
      
      The problem was first noticed by Peter Watkins.
      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>
      6ffc4db5
    • D
      xfs: punch all delalloc blocks beyond EOF on write failure. · 01c84d2d
      Dave Chinner 提交于
      I've been seeing regular ASSERT failures in xfstests when running
      fsstress based tests over the past month. xfs_getbmap() has been
      failing this test:
      
      XFS: Assertion failed: ((iflags & BMV_IF_DELALLOC) != 0) ||
      (map[i].br_startblock != DELAYSTARTBLOCK), file: fs/xfs/xfs_bmap.c,
      line: 5650
      
      where it is encountering a delayed allocation extent after writing
      all the dirty data to disk and then walking the extent map
      atomically by holding the XFS_IOLOCK_SHARED to prevent new delayed
      allocation extents from being created.
      
      Test 083 on a 512 byte block size filesystem was used to reproduce
      the problem, because it only had a 5s run timeand would usually fail
      every 3-4 runs. This test is exercising ENOSPC behaviour by running
      fsstress on a nearly full filesystem. The following trace extract
      shows the final few events on the inode that tripped the assert:
      
       xfs_ilock:             flags ILOCK_EXCL caller xfs_setfilesize
       xfs_setfilesize:       isize 0x180000 disize 0x12d400 offset 0x17e200 count 7680
      
      file size updated to 0x180000 by IO completion
      
       xfs_ilock:             flags ILOCK_EXCL caller xfs_iomap_write_delay
       xfs_iext_insert:       state  idx 3 offset 3072 block 4503599627239432 count 1 flag 0 caller xfs_bmap_add_extent_hole_delay
       xfs_get_blocks_alloc:  size 0x180000 offset 0x180000 count 512 type  startoff 0xc00 startblock -1 blockcount 0x1
       xfs_ilock:             flags ILOCK_EXCL caller __xfs_get_blocks
      
      delalloc write, adding a single block at offset 0x180000
      
       xfs_delalloc_enospc:   isize 0x180000 disize 0x180000 offset 0x180200 count 512
      
      ENOSPC trying to allocate a dellalloc block at offset 0x180200
      
       xfs_ilock:             flags ILOCK_EXCL caller xfs_iomap_write_delay
       xfs_get_blocks_alloc:  size 0x180000 offset 0x180200 count 512 type  startoff 0xc00 startblock -1 blockcount 0x2
      
      And succeeding on retry after flushing dirty inodes.
      
       xfs_ilock:             flags ILOCK_EXCL caller __xfs_get_blocks
       xfs_delalloc_enospc:   isize 0x180000 disize 0x180000 offset 0x180400 count 512
      
      ENOSPC trying to allocate a dellalloc block at offset 0x180400
      
       xfs_ilock:             flags ILOCK_EXCL caller xfs_iomap_write_delay
       xfs_delalloc_enospc:   isize 0x180000 disize 0x180000 offset 0x180400 count 512
      
      And failing the retry, giving a real ENOSPC error.
      
       xfs_ilock:             flags ILOCK_EXCL caller xfs_vm_write_failed
                                                      ^^^^^^^^^^^^^^^^^^^
      The smoking gun - the write being failed and cleaning up delalloc
      blocks beyond EOF allocated by the failed write.
      
       xfs_getattr:
       xfs_ilock:             flags IOLOCK_SHARED caller xfs_getbmap
       xfs_ilock:             flags ILOCK_SHARED caller xfs_ilock_map_shared
      
      And that's where we died almost immediately afterwards.
      xfs_bmapi_read() found delalloc extent beyond current file in memory
      file size. Some debug I added to xfs_getbmap() showed the state just
      before the assert failure:
      
       ino 0x80e48: off 0xc00, fsb 0xffffffffffffffff, len 0x1, size 0x180000
       start_fsb 0x106, end_fsb 0x638
       ino flags 0x2 nex 0xd bmvcnt 0x555, len 0x3c58a6f23c0bf1, start 0xc00
       ext 0: off 0x1fc, fsb 0x24782, len 0x254
       ext 1: off 0x450, fsb 0x40851, len 0x30
       ext 2: off 0x480, fsb 0xd99, len 0x1b8
       ext 3: off 0x92f, fsb 0x4099a, len 0x3b
       ext 4: off 0x96d, fsb 0x41844, len 0x98
       ext 5: off 0xbf1, fsb 0x408ab, len 0xf
      
      which shows that we found a single delalloc block beyond EOF (first
      line of output) when we were returning the map for a length
      somewhere around 10^16 bytes long (second line), and the on-disk
      extents showed they didn't go past EOF (last lines).
      
      Further debug added to xfs_vm_write_failed() showed this happened
      when punching out delalloc blocks beyond the end of the file after
      the failed write:
      
      [  132.606693] ino 0x80e48: vwf to 0x181000, sze 0x180000
      [  132.609573] start_fsb 0xc01, end_fsb 0xc08
      
      It punched the range 0xc01 -> 0xc08, but the range we really need to
      punch is 0xc00 -> 0xc07 (8 blocks from 0xc00) as this testing was
      run on a 512 byte block size filesystem (8 blocks per page).
      the punch from is 0xc00. So end_fsb is correct, but start_fsb is
      wrong as we punch from start_fsb for (end_fsb - start_fsb) blocks.
      Hence we are not punching the delalloc block beyond EOF in the case.
      
      The fix is simple - it's a silly off-by-one mistake in calculating
      the range. It's especially silly because the macro used to calculate
      the start_fsb already takes into account the case where the inode
      size is an exact multiple of the filesystem block size...
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NEric Sandeen <sandeen@redhat.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      01c84d2d
    • D
      xfs: use shared ilock mode for direct IO writes by default · 507630b2
      Dave Chinner 提交于
      For the direct IO write path, we only really need the ilock to be taken in
      exclusive mode during IO submission if we need to do extent allocation
      instead of all the time.
      
      Change the block mapping code to take the ilock in shared mode for the
      initial block mapping, and only retake it exclusively when we actually
      have to perform extent allocations.  We were already dropping the ilock
      for the transaction allocation, so this doesn't introduce new race windows.
      
      Based on an earlier patch from Dave Chinner.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NMark Tinguely <tinguely@sgi.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      507630b2
  3. 14 3月, 2012 1 次提交
  4. 06 3月, 2012 3 次提交
  5. 18 1月, 2012 2 次提交
    • C
      xfs: remove the i_new_size field in struct xfs_inode · 2813d682
      Christoph Hellwig 提交于
      Now that we use the VFS i_size field throughout XFS there is no need for the
      i_new_size field any more given that the VFS i_size field gets updated
      in ->write_end before unlocking the page, and thus is always uptodate when
      writeback could see a page.  Removing i_new_size also has the advantage that
      we will never have to trim back di_size during a failed buffered write,
      given that it never gets updated past i_size.
      
      Note that currently the generic direct I/O code only updates i_size after
      calling our end_io handler, which requires a small workaround to make
      sure di_size actually makes it to disk.  I hope to fix this properly in
      the generic code.
      
      A downside is that we lose the support for parallel non-overlapping O_DIRECT
      appending writes that recently was added.  I don't think keeping the complex
      and fragile i_new_size infrastructure for this is a good tradeoff - if we
      really care about parallel appending writers we should investigate turning
      the iolock into a range lock, which would also allow for parallel
      non-overlapping buffered writers.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Reviewed-by: NDave Chinner <dchinner@redhat.com>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      2813d682
    • C
      xfs: remove the i_size field in struct xfs_inode · ce7ae151
      Christoph Hellwig 提交于
      There is no fundamental need to keep an in-memory inode size copy in the XFS
      inode.  We already have the on-disk value in the dinode, and the separate
      in-memory copy that we need for regular files only in the XFS inode.
      
      Remove the xfs_inode i_size field and change the XFS_ISIZE macro to use the
      VFS inode i_size field for regular files.  Switch code that was directly
      accessing the i_size field in the xfs_inode to XFS_ISIZE, or in cases where
      we are limited to regular files direct access of the VFS inode i_size field.
      
      This also allows dropping some fairly complicated code in the write path
      which dealt with keeping the xfs_inode i_size uptodate with the VFS i_size
      that is getting updated inside ->write_end.
      
      Note that we do not bother resetting the VFS i_size when truncating a file
      that gets freed to zero as there is no point in doing so because the VFS inode
      is no longer in use at this point.  Just relax the assert in xfs_ifree to
      only check the on-disk size instead.
      Reviewed-by: NDave Chinner <dchinner@redhat.com>
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NBen Myers <bpm@sgi.com>
      ce7ae151
  6. 09 11月, 2011 1 次提交
  7. 01 11月, 2011 1 次提交
    • M
      xfs: warn if direct reclaim tries to writeback pages · 94054fa3
      Mel Gorman 提交于
      Direct reclaim should never writeback pages.  For now, handle the
      situation and warn about it.  Ultimately, this will be a BUG_ON.
      Signed-off-by: NMel Gorman <mgorman@suse.de>
      Cc: Dave Chinner <david@fromorbit.com>
      Cc: Christoph Hellwig <hch@infradead.org>
      Cc: Johannes Weiner <jweiner@redhat.com>
      Cc: Wu Fengguang <fengguang.wu@intel.com>
      Cc: Jan Kara <jack@suse.cz>
      Cc: Minchan Kim <minchan.kim@gmail.com>
      Cc: Rik van Riel <riel@redhat.com>
      Cc: Mel Gorman <mgorman@suse.de>
      Cc: Alex Elder <aelder@sgi.com>
      Cc: Theodore Ts'o <tytso@mit.edu>
      Cc: Chris Mason <chris.mason@oracle.com>
      Cc: Dave Hansen <dave@linux.vnet.ibm.com>
      Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      94054fa3
  8. 12 10月, 2011 6 次提交
  9. 14 9月, 2011 1 次提交
  10. 13 8月, 2011 1 次提交
    • C
      xfs: remove subdirectories · c59d87c4
      Christoph Hellwig 提交于
      Use the move from Linux 2.6 to Linux 3.x as an excuse to kill the
      annoying subdirectories in the XFS source code.  Besides the large
      amount of file rename the only changes are to the Makefile, a few
      files including headers with the subdirectory prefix, and the binary
      sysctl compat code that includes a header under fs/xfs/ from
      kernel/.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NAlex Elder <aelder@sgi.com>
      c59d87c4
  11. 21 7月, 2011 2 次提交
  12. 08 7月, 2011 2 次提交
  13. 08 6月, 2011 1 次提交
  14. 31 3月, 2011 1 次提交
  15. 10 3月, 2011 2 次提交
    • J
      block: kill off REQ_UNPLUG · 721a9602
      Jens Axboe 提交于
      With the plugging now being explicitly controlled by the
      submitter, callers need not pass down unplugging hints
      to the block layer. If they want to unplug, it's because they
      manually plugged on their own - in which case, they should just
      unplug at will.
      Signed-off-by: NJens Axboe <jaxboe@fusionio.com>
      721a9602
    • J
      block: remove per-queue plugging · 7eaceacc
      Jens Axboe 提交于
      Code has been converted over to the new explicit on-stack plugging,
      and delay users have been converted to use the new API for that.
      So lets kill off the old plugging along with aops->sync_page().
      Signed-off-by: NJens Axboe <jaxboe@fusionio.com>
      7eaceacc
  16. 07 3月, 2011 1 次提交
  17. 01 12月, 2010 1 次提交
    • D
      xfs: fix failed write truncation handling. · c726de44
      Dave Chinner 提交于
      Since the move to the new truncate sequence we call xfs_setattr to
      truncate down excessively instanciated blocks.  As shown by the testcase
      in kernel.org BZ #22452 that doesn't work too well.  Due to the confusion
      of the internal inode size, and the VFS inode i_size it zeroes data that
      it shouldn't.
      
      But full blown truncate seems like overkill here.  We only instanciate
      delayed allocations in the write path, and given that we never released
      the iolock we can't have converted them to real allocations yet either.
      
      The only nasty case is pre-existing preallocation which we need to skip.
      We already do this for page discard during writeback, so make the delayed
      allocation block punching a generic function and call it from the failed
      write path as well as xfs_aops_discard_page. The callers are
      responsible for ensuring that partial blocks are not truncated away,
      and that they hold the ilock.
      
      Based on a fix originally from Christoph Hellwig. This version used
      filesystem blocks as the range unit.
      Signed-off-by: NDave Chinner <dchinner@redhat.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      c726de44
  18. 17 12月, 2010 5 次提交