1. 15 8月, 2014 1 次提交
    • C
      btrfs: disable strict file flushes for renames and truncates · 8d875f95
      Chris Mason 提交于
      Truncates and renames are often used to replace old versions of a file
      with new versions.  Applications often expect this to be an atomic
      replacement, even if they haven't done anything to make sure the new
      version is fully on disk.
      
      Btrfs has strict flushing in place to make sure that renaming over an
      old file with a new file will fully flush out the new file before
      allowing the transaction commit with the rename to complete.
      
      This ordering means the commit code needs to be able to lock file pages,
      and there are a few paths in the filesystem where we will try to end a
      transaction with the page lock held.  It's rare, but these things can
      deadlock.
      
      This patch removes the ordered flushes and switches to a best effort
      filemap_flush like ext4 uses. It's not perfect, but it should fix the
      deadlocks.
      Signed-off-by: NChris Mason <clm@fb.com>
      8d875f95
  2. 20 7月, 2014 1 次提交
    • L
      Btrfs: fix abnormal long waiting in fsync · 98ce2ded
      Liu Bo 提交于
      xfstests generic/127 detected this problem.
      
      With commit 7fc34a62, now fsync will only flush
      data within the passed range.  This is the cause of the above problem,
      -- btrfs's fsync has a stage called 'sync log' which will wait for all the
      ordered extents it've recorded to finish.
      
      In xfstests/generic/127, with mixed operations such as truncate, fallocate,
      punch hole, and mapwrite, we get some pre-allocated extents, and mapwrite will
      mmap, and then msync.  And I find that msync will wait for quite a long time
      (about 20s in my case), thanks to ftrace, it turns out that the previous
      fallocate calls 'btrfs_wait_ordered_range()' to flush dirty pages, but as the
      range of dirty pages may be larger than 'btrfs_wait_ordered_range()' wants,
      there can be some ordered extents created but not getting corresponding pages
      flushed, then they're left in memory until we fsync which runs into the
      stage 'sync log', and fsync will just wait for the system writeback thread
      to flush those pages and get ordered extents finished, so the latency is
      inevitable.
      
      This adds a flush similar to btrfs_start_ordered_extent() in
      btrfs_wait_logged_extents() to fix that.
      Reviewed-by: NMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: NLiu Bo <bo.li.liu@oracle.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      98ce2ded
  3. 10 6月, 2014 1 次提交
  4. 11 3月, 2014 6 次提交
  5. 29 1月, 2014 2 次提交
    • F
      Btrfs: convert printk to btrfs_ and fix BTRFS prefix · efe120a0
      Frank Holton 提交于
      Convert all applicable cases of printk and pr_* to the btrfs_* macros.
      
      Fix all uses of the BTRFS prefix.
      Signed-off-by: NFrank Holton <fholton@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      efe120a0
    • F
      Btrfs: avoid unnecessary ordered extent cache resets · 1b8e7e45
      Filipe David Borba Manana 提交于
      After an ordered extent completes, don't blindly reset the
      inode's ordered tree last accessed ordered extent pointer.
      
      While running the xfstests I noticed that about 29% of the
      time the ordered extent to which tree->last pointed was not
      the same as our just completed ordered extent. After that I
      ran the following sysbench test (after a prepare phase) and
      noticed that about 68% of the time tree->last pointed to
      a different ordered extent too.
      
      sysbench --test=fileio --file-num=32 --file-total-size=4G \
          --file-test-mode=rndwr --num-threads=512 \
          --file-block-size=32768 --max-time=60 --max-requests=0 run
      
      Therefore reset tree->last on ordered extent removal only if
      it pointed to the ordered extent we're removing from the tree.
      
      Results from 4 runs of the following test before and after
      applying this patch:
      
      $ sysbench --test=fileio --file-num=32 --file-total-size=4G \
        --file-test-mode=seqwr --num-threads=512 \
        --file-block-size=32768 --max-time=60 --file-io-mode=sync prepare
      $ sysbench --test=fileio --file-num=32 --file-total-size=4G \
        --file-test-mode=seqwr --num-threads=512 \
        --file-block-size=32768 --max-time=60 --file-io-mode=sync run
      
      Before this path:
      
      run 1 - 64.049Mb/sec
      run 2 - 63.455Mb/sec
      run 3 - 64.656Mb/sec
      run 4 - 63.833Mb/sec
      
      After this patch:
      
      run 1 - 66.149Mb/sec
      run 2 - 68.459Mb/sec
      run 3 - 66.338Mb/sec
      run 4 - 66.176Mb/sec
      
      With random writes (--file-test-mode=rndwr) I had huge fluctuations
      on the results (+- 35% easily).
      Signed-off-by: NFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: NJosef Bacik <jbacik@fb.com>
      Signed-off-by: NChris Mason <clm@fb.com>
      1b8e7e45
  6. 21 11月, 2013 2 次提交
  7. 12 11月, 2013 4 次提交
  8. 21 9月, 2013 1 次提交
  9. 01 9月, 2013 3 次提交
    • J
      Btrfs: allow partial ordered extent completion · 77cef2ec
      Josef Bacik 提交于
      We currently have this problem where you can truncate pages that have not yet
      been written for an ordered extent.  We do this because the truncate will be
      coming behind to clean us up anyway so what's the harm right?  Well if truncate
      fails for whatever reason we leave an orphan item around for the file to be
      cleaned up later.  But if the user goes and truncates up the file and tries to
      read from the area that had been discarded previously they will get a csum error
      because we never actually wrote that data out.
      
      This patch fixes this by allowing us to either discard the ordered extent
      completely, by which I mean we just free up the space we had allocated and not
      add the file extent, or adjust the length of the file extent we write.  We do
      this by setting the length we truncated down to in the ordered extent, and then
      we set the file extent length and ram bytes to this length.  The total disk
      space stays unchanged since we may be compressed and we can't just chop off the
      disk space, but at least this way the file extent only points to the valid data.
      Then when the file extent is free'd the extent and csums will be freed normally.
      
      This patch is needed for the next series which will give us more graceful
      recovery of failed truncates.  Thanks,
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: NChris Mason <chris.mason@fusionio.com>
      77cef2ec
    • G
      Btrfs: Remove superfluous casts from u64 to unsigned long long · c1c9ff7c
      Geert Uytterhoeven 提交于
      u64 is "unsigned long long" on all architectures now, so there's no need to
      cast it when formatting it using the "ll" length modifier.
      Signed-off-by: NGeert Uytterhoeven <geert@linux-m68k.org>
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: NChris Mason <chris.mason@fusionio.com>
      c1c9ff7c
    • J
      Btrfs: fix heavy delalloc related deadlock · 9ffba8cd
      Josef Bacik 提交于
      I added a patch where we started taking the ordered operations mutex when we
      waited on ordered extents.  We need this because we splice the list and process
      it, so if a flusher came in during this scenario it would think the list was
      empty and we'd usually get an early ENOSPC.  The problem with this is that this
      lock is used in transaction committing.  So we end up with something like this
      
      Transaction commit
      	-> wait on writers
      
      Delalloc flusher
      	-> run_ordered_operations (holds mutex)
      		->wait for filemap-flush to do its thing
      
      flush task
      	-> cow_file_range
      		->wait on btrfs_join_transaction because we're commiting
      
      some other task
      	-> commit_transaction because we notice trans->transaction->flush is set
      		-> run_ordered_operations (hang on mutex)
      
      We need to disentangle the ordered operations flushing from the delalloc
      flushing, since they are separate things.  This solves the deadlock issue I was
      seeing.  Thanks,
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: NChris Mason <chris.mason@fusionio.com>
      9ffba8cd
  10. 02 7月, 2013 1 次提交
    • M
      Btrfs: remove btrfs_sector_sum structure · f51a4a18
      Miao Xie 提交于
      Using the structure btrfs_sector_sum to keep the checksum value is
      unnecessary, because the extents that btrfs_sector_sum points to are
      continuous, we can find out the expected checksums by btrfs_ordered_sum's
      bytenr and the offset, so we can remove btrfs_sector_sum's bytenr. After
      removing bytenr, there is only one member in the structure, so it makes
      no sense to keep the structure, just remove it, and use a u32 array to
      store the checksum value.
      
      By this change, we don't use the while loop to get the checksums one by
      one. Now, we can get several checksum value at one time, it improved the
      performance by ~74% on my SSD (31MB/s -> 54MB/s).
      
      test command:
       # dd if=/dev/zero of=/mnt/btrfs/file0 bs=1M count=1024 oflag=sync
      Signed-off-by: NMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      f51a4a18
  11. 14 6月, 2013 1 次提交
  12. 07 5月, 2013 1 次提交
  13. 28 3月, 2013 1 次提交
  14. 21 2月, 2013 1 次提交
    • J
      Btrfs: place ordered operations on a per transaction list · 569e0f35
      Josef Bacik 提交于
      Miao made the ordered operations stuff run async, which introduced a
      deadlock where we could get somebody (sync) racing in and committing the
      transaction while a commit was already happening.  The new committer would
      try and flush ordered operations which would hang waiting for the commit to
      finish because it is done asynchronously and no longer inherits the callers
      trans handle.  To fix this we need to make the ordered operations list a per
      transaction list.  We can get new inodes added to the ordered operation list
      by truncating them and then having another process writing to them, so this
      makes it so that anybody trying to add an ordered operation _must_ start a
      transaction in order to add itself to the list, which will keep new inodes
      from getting added to the ordered operations list after we start committing.
      This should fix the deadlock and also keeps us from doing a lot more work
      than we need to during commit.  Thanks,
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      569e0f35
  15. 20 2月, 2013 2 次提交
  16. 06 2月, 2013 2 次提交
    • J
      Btrfs: fix possible stale data exposure · 59fe4f41
      Josef Bacik 提交于
      We specifically do not update the disk i_size if there are ordered extents
      outstanding for any area between the current disk_i_size and our ordered
      extent so that we do not expose stale data.  The problem is the check we
      have only checks if the ordered extent starts at or after the current
      disk_i_size, which doesn't take into account an ordered extent that starts
      before the current disk_i_size and ends past the disk_i_size.  Fix this by
      checking if the extent ends past the disk_i_size.  Thanks,
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      59fe4f41
    • J
      Btrfs: fix missing i_size update · 5d1f4020
      Josef Bacik 提交于
      If we have an ordered extent before the ordered extent we are currently
      completing that is after the current disk_i_size we will put our i_size
      update into that ordered extent so that we do not expose stale data.  The
      problem is that if our disk i_size is updated past the previous ordered
      extent we won't update the i_size with the pending i_size update.  So check
      the pending i_size update and if its above the current disk i_size we need
      to go ahead and try to update.  Thanks,
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      5d1f4020
  17. 13 12月, 2012 1 次提交
  18. 12 12月, 2012 2 次提交
  19. 04 10月, 2012 1 次提交
  20. 02 10月, 2012 2 次提交
    • M
      Btrfs: use a slab for ordered extents allocation · 6352b91d
      Miao Xie 提交于
      The ordered extent allocation is in the fast path of the IO, so use a slab
      to improve the speed of the allocation.
      
       "Size of the struct is 280, so this will fall into the size-512 bucket,
        giving 8 objects per page, while own slab will pack 14 objects into a page.
      
        Another benefit I see is to check for leaked objects when the module is
        removed (and the cache destroy takes place)."
      						-- David Sterba
      Signed-off-by: NMiao Xie <miaox@cn.fujitsu.com>
      6352b91d
    • M
      Btrfs: fix file extent discount problem in the, snapshot · b9a8cc5b
      Miao Xie 提交于
      If a snapshot is created while we are writing some data into the file,
      the i_size of the corresponding file in the snapshot will be wrong, it will
      be beyond the end of the last file extent. And btrfsck will report:
        root 256 inode 257 errors 100
      
      Steps to reproduce:
       # mkfs.btrfs <partition>
       # mount <partition> <mnt>
       # cd <mnt>
       # dd if=/dev/zero of=tmpfile bs=4M count=1024 &
       # for ((i=0; i<4; i++))
       > do
       > btrfs sub snap . $i
       > done
      
      This because the algorithm of disk_i_size update is wrong. Though there are
      some ordered extents behind the current one which we use to update disk_i_size,
      it doesn't mean those extents will be dealt with in the same transaction. So
      We shouldn't use the offset of those extents to update disk_i_size. Or we will
      get the wrong i_size in the snapshot.
      
      We fix this problem by recording the max real i_size. If we find there is a
      ordered extent which is in front of the current one and doesn't complete, we
      will record the end of the current one into that ordered extent. Surely, if
      the current extent holds the end of other extent(it must be greater than
      the current one because it is behind the current one), we will record the
      number that the current extent holds. In this way, we can exclude the ordered
      extents that may not be dealth with in the same transaction, and be easy to
      know the real disk_i_size.
      Signed-off-by: NMiao Xie <miaox@cn.fujitsu.com>
      b9a8cc5b
  21. 04 8月, 2012 1 次提交
  22. 15 6月, 2012 1 次提交
    • J
      Btrfs: call filemap_fdatawrite twice for compression · 7ddf5a42
      Josef Bacik 提交于
      I removed this in an earlier commit and I was wrong.  Because compression
      can return from filemap_fdatawrite() without having actually set any of it's
      pages as writeback() it can make filemap_fdatawait() do essentially nothing,
      and then we won't find any ordered extents because they may not have been
      created yet.  So not only does this make fsync() completely useless, but it
      will also screw up if you truncate on a non-page aligned offset since we
      zero out the end and then wait on ordered extents and then call drop caches.
      We can drop the cache before the io completes and then we try to unpin the
      extent we just wrote we won't find it and everything goes sideways.  So fix
      this by putting it back and put a giant comment there to keep me from trying
      to remove it in the future.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      7ddf5a42
  23. 30 5月, 2012 2 次提交
    • J
      Btrfs: finish ordered extents in their own thread · 5fd02043
      Josef Bacik 提交于
      We noticed that the ordered extent completion doesn't really rely on having
      a page and that it could be done independantly of ending the writeback on a
      page.  This patch makes us not do the threaded endio stuff for normal
      buffered writes and direct writes so we can end page writeback as soon as
      possible (in irq context) and only start threads to do the ordered work when
      it is actually done.  Compression needs to be reworked some to take
      advantage of this as well, but atm it has to do a find_get_page in its endio
      handler so it must be done in its own thread.  This makes direct writes
      quite a bit faster.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      5fd02043
    • J
      Btrfs: do not check delalloc when updating disk_i_size · 4e899152
      Josef Bacik 提交于
      We are checking delalloc to see if it is ok to update the i_size.  There are
      2 cases it stops us from updating
      
      1) If there is delalloc between our current disk_i_size and this ordered
      extent
      
      2) If there is delalloc between our current ordered extent and the next
      ordered extent
      
      These tests are racy however since we can set delalloc for these ranges at
      any time.  Also for the first case if we notice there is delalloc between
      disk_i_size and our ordered extent we will not update disk_i_size and assume
      that when that delalloc bit gets written out it will update everything
      properly.  However if we crash before that we will have file extents outside
      of our i_size, which is not good, so this test is dangerous as well as racy.
      Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      4e899152