1. 15 3月, 2010 1 次提交
    • J
      Btrfs: cache the extent state everywhere we possibly can V2 · 2ac55d41
      Josef Bacik 提交于
      This patch just goes through and fixes everybody that does
      
      lock_extent()
      blah
      unlock_extent()
      
      to use
      
      lock_extent_bits()
      blah
      unlock_extent_cached()
      
      and pass around a extent_state so we only have to do the searches once per
      function.  This gives me about a 3 mb/s boots on my random write test.  I have
      not converted some things, like the relocation and ioctl's, since they aren't
      heavily used and the relocation stuff is in the middle of being re-written.  I
      also changed the clear_extent_bit() to only unset the cached state if we are
      clearing EXTENT_LOCKED and related stuff, so we can do things like this
      
      lock_extent_bits()
      clear delalloc bits
      unlock_extent_cached()
      
      without losing our cached state.  I tested this thoroughly and turned on
      LEAK_DEBUG to make sure we weren't leaking extent states, everything worked out
      fine.
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      2ac55d41
  2. 05 2月, 2010 1 次提交
  3. 18 1月, 2010 1 次提交
    • J
      Btrfs: fix possible panic on unmount · 11dfe35a
      Josef Bacik 提交于
      We can race with the unmount of an fs and the stopping of a kthread where we
      will free the block group before we're done using it.  The reason for this is
      because we do not hold a reference on the block group while its caching, since
      the allocator drops its reference once it exits or moves on to the next block
      group.  This patch fixes the problem by taking a reference to the block group
      before we start caching and dropping it when we're done to make sure all
      accesses to the block group are safe.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      11dfe35a
  4. 18 12月, 2009 4 次提交
  5. 16 12月, 2009 1 次提交
  6. 12 11月, 2009 2 次提交
    • C
      Btrfs: allow more metadata chunk preallocation · 33b25808
      Chris Mason 提交于
      On an FS where all of the space has not been allocated into chunks yet,
      the enospc can return enospc just because the existing metadata chunks
      are full.
      
      We get around this by allowing more metadata chunks to be allocated up
      to a certain limit, and finding the right limit is a little fuzzy.  The
      problem is the reservations for delalloc would preallocate way too much
      of the FS as metadata.  We need to start saying no and just force some
      IO to happen.
      
      But we also need to let a reasonable amount of the FS become metadata.
      This bumps the hard limit up, later releases will have a better system.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      33b25808
    • J
      Btrfs: find ideal block group for caching · ccf0e725
      Josef Bacik 提交于
      This patch changes a few things.  Hopefully the comments are helpfull, but
      I'll try and be as verbose here.
      
      Problem:
      
      My fedora box was taking 1 minute and 21 seconds to boot with btrfs as root.
      Part of this problem was we pick the first block group we can find and start
      caching it, even if it may not have enough free space.  The other problem is
      we only search for cached block groups the first time around, which we won't
      find any cached block groups because this is a newly mounted fs, so we end up
      caching several block groups during bootup, which with alot of fragmentation
      takes around 30-45 seconds to complete, which bogs down the system.  So
      
      Solution:
      
      1) Don't cache block groups willy-nilly at first.  Instead try and figure out
      which block group has the most free, and therefore will take the least amount
      of time to cache.
      
      2) Don't be so picky about cached block groups.  The other problem is once
      we've filled up a cluster, if the block group isn't finished caching the next
      time we try and do the allocation we'll completely ignore the cluster and
      start searching from the beginning of the space, which makes us cache more
      block groups, which slows us down even more.  So instead of skipping block
      groups that are not finished caching when we have a hint, only skip the block
      group if it hasn't started caching yet.
      
      There is one other tweak in here.  Before if we allocated a chunk and still
      couldn't find new space, we'd end up switching the space info to force another
      chunk allocation.  This could make us end up with way too many chunks, so keep
      track of this particular case.
      
      With this patch and my previous cluster fixes my fedora box now boots in 43
      seconds, and according to the bootchart is not held up by our block group
      caching at all.
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      ccf0e725
  7. 14 10月, 2009 3 次提交
  8. 09 10月, 2009 3 次提交
    • Y
      Btrfs: optimize back reference update during btrfs_drop_snapshot · 94fcca9f
      Yan, Zheng 提交于
      This patch reading level 0 tree blocks that already use full backrefs.
      Signed-off-by: NYan Zheng <zheng.yan@oracle.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      94fcca9f
    • J
      Btrfs: async delalloc flushing under space pressure · e3ccfa98
      Josef Bacik 提交于
      This patch moves the delalloc flushing that occurs when we are under space
      pressure off to a async thread pool.  This helps since we only free up
      metadata space when we actually insert the extent item, which means it takes
      quite a while for space to be free'ed up if we wait on all ordered extents.
      However, if space is freed up due to inline extents being inserted, we can
      wake people who are waiting up early, and they can finish their work.
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      e3ccfa98
    • J
      Btrfs: release delalloc reservations on extent item insertion · 32c00aff
      Josef Bacik 提交于
      This patch fixes an issue with the delalloc metadata space reservation
      code.  The problem is we used to free the reservation as soon as we
      allocated the delalloc region.  The problem with this is if we are not
      inserting an inline extent, we don't actually insert the extent item until
      after the ordered extent is written out.  This patch does 3 things,
      
      1) It moves the reservation clearing stuff into the ordered code, so when
      we remove the ordered extent we remove the reservation.
      2) It adds a EXTENT_DO_ACCOUNTING flag that gets passed when we clear
      delalloc bits in the cases where we want to clear the metadata reservation
      when we clear the delalloc extent, in the case that we do an inline extent
      or we invalidate the page.
      3) It adds another waitqueue to the space info so that when we start a fs
      wide delalloc flush, anybody else who also hits that area will simply wait
      for the flush to finish and then try to make their allocation.
      
      This has been tested thoroughly to make sure we did not regress on
      performance.
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      32c00aff
  9. 06 10月, 2009 1 次提交
    • J
      Btrfs: fix possible softlockup in the allocator · 1cdda9b8
      Josef Bacik 提交于
      Like the cluster allocating stuff, we can lockup the box with the normal
      allocation path.  This happens when we
      
      1) Start to cache a block group that is severely fragmented, but has a decent
      amount of free space.
      2) Start to commit a transaction
      3) Have the commit try and empty out some of the delalloc inodes with extents
      that are relatively large.
      
      The inodes will not be able to make the allocations because they will ask for
      allocations larger than a contiguous area in the free space cache.  So we will
      wait for more progress to be made on the block group, but since we're in a
      commit the caching kthread won't make any more progress and it already has
      enough free space that wait_block_group_cache_progress will just return.  So,
      if we wait and fail to make the allocation the next time around, just loop and
      go to the next block group.  This keeps us from getting stuck in a softlockup.
      Thanks,
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      1cdda9b8
  10. 30 9月, 2009 1 次提交
  11. 29 9月, 2009 1 次提交
    • J
      Btrfs: proper -ENOSPC handling · 9ed74f2d
      Josef Bacik 提交于
      At the start of a transaction we do a btrfs_reserve_metadata_space() and
      specify how many items we plan on modifying.  Then once we've done our
      modifications and such, just call btrfs_unreserve_metadata_space() for
      the same number of items we reserved.
      
      For keeping track of metadata needed for data I've had to add an extent_io op
      for when we merge extents.  This lets us track space properly when we are doing
      sequential writes, so we don't end up reserving way more metadata space than
      what we need.
      
      The only place where the metadata space accounting is not done is in the
      relocation code.  This is because Yan is going to be reworking that code in the
      near future, so running btrfs-vol -b could still possibly result in a ENOSPC
      related panic.  This patch also turns off the metadata_ratio stuff in order to
      allow users to more efficiently use their disk space.
      
      This patch makes it so we track how much metadata we need for an inode's
      delayed allocation extents by tracking how many extents are currently
      waiting for allocation.  It introduces two new callbacks for the
      extent_io tree's, merge_extent_hook and split_extent_hook.  These help
      us keep track of when we merge delalloc extents together and split them
      up.  Reservations are handled prior to any actually dirty'ing occurs,
      and then we unreserve after we dirty.
      
      btrfs_unreserve_metadata_for_delalloc() will make the appropriate
      unreservations as needed based on the number of reservations we
      currently have and the number of extents we currently have.  Doing the
      reservation outside of doing any of the actual dirty'ing lets us do
      things like filemap_flush() the inode to try and force delalloc to
      happen, or as a last resort actually start allocation on all delalloc
      inodes in the fs.  This has survived dbench, fs_mark and an fsx torture
      test.
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      9ed74f2d
  12. 23 9月, 2009 2 次提交
    • C
      Btrfs: fix early enospc during balancing · 7ce618db
      Chris Mason 提交于
      We now do extra checks before a balance to make sure
      there is room for the balance to take place.  One of
      the checks was testing to see if we were trying to
      balance away the last block group of a given type.
      
      If there is no space available for new chunks, we
      should not try and balance away the last block group
      of a give type.  But, the code wasn't checking for
      available chunk space, and so it was exiting too soon.
      
      The fix here is to combine some of the checks and make
      sure we try to allocate new chunks when we're balancing
      the last block group.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      7ce618db
    • C
      Btrfs: deal with NULL space info · 33b4d47f
      Chris Mason 提交于
      After a balance it is briefly possible for the space info
      field in the inode to be NULL.  This adds some checks
      to make sure things properly deal with the NULL value.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      33b4d47f
  13. 22 9月, 2009 6 次提交
    • J
      Btrfs: account for space used by the super mirrors · 1b2da372
      Josef Bacik 提交于
      As we get closer to proper -ENOSPC handling in btrfs, we need more accurate
      space accounting for the space info's.  Currently we exclude the free space for
      the super mirrors, but the space they take up isn't accounted for in any of the
      counters.  This patch introduces bytes_super, which keeps track of the amount
      of bytes used for a super mirror in the block group cache and space info.  This
      makes sure that our free space caclucations will be completely accurate.
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      1b2da372
    • J
      Btrfs: remove dead code · f61408b8
      Josef Bacik 提交于
      This patch removes a bunch of dead code from the snapshot removal stuff.  It
      was confusing me when doing the metadata ENOSPC stuff so I killed it.
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      f61408b8
    • J
      Btrfs: don't keep retrying a block group if we fail to allocate a cluster · 0a24325e
      Josef Bacik 提交于
      The box can get locked up in the allocator if we happen upon a block group
      under these conditions:
      
      1) During a commit, so caching threads cannot make progress
      2) Our block group currently is in the middle of being cached
      3) Our block group currently has plenty of free space in it
      4) Our block group is so fragmented that it ends up having no free space chunks
      larger than min_bytes calculated by btrfs_find_space_cluster.
      
      What happens is we try and do btrfs_find_space_cluster, which fails because it
      is unable to find enough free space chunks that are large than min_bytes and
      are close enough together.  Since the block group is not cached we do a
      wait_block_group_cache_progress, which waits for the number of bytes we need,
      except the block group already has _plenty_ of free space, its just severely
      fragmented, so we loop and try again, ad infinitum.  This patch keeps us from
      waiting on the block group to finish caching if we failed to find a free space
      cluster before.  It also makes sure that we don't even try to find a free space
      cluster if we are on our last loop in the allocator, since we will have tried
      everything at this point at it is futile.
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      0a24325e
    • J
      Btrfs: make balance code choose more wisely when relocating · ba1bf481
      Josef Bacik 提交于
      Currently, we can panic the box if the first block group we go to move is of a
      type where there is no space left to move those extents.  For example, if we
      fill the disk up with data, and then we try to balance and we have no room to
      move the data nor room to allocate new chunks, we will panic.  Change this by
      checking to see if we have room to move this chunk around, and if not, return
      -ENOSPC and move on to the next chunk.  This will make sure we remove block
      groups that are moveable, like if we have alot of empty metadata block groups,
      and then that way we make room to be able to balance our data chunks as well.
      Tested this with an fs that would panic on btrfs-vol -b normally, but no longer
      panics with this patch.
      
      V1->V2:
      -actually search for a free extent on the device to make sure we can allocate a
      chunk if need be.
      
      -fix btrfs_shrink_device to make sure we actually try to relocate all the
      chunks, and then if we can't return -ENOSPC so if we are doing a btrfs-vol -r
      we don't remove the device with data still on it.
      
      -check to make sure the block group we are going to relocate isn't the last one
      in that particular space
      
      -fix a bug in btrfs_shrink_device where we would change the device's size and
      not fix it if we fail to do our relocate
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      ba1bf481
    • Y
      Btrfs: add snapshot/subvolume destroy ioctl · 76dda93c
      Yan, Zheng 提交于
      This patch adds snapshot/subvolume destroy ioctl.  A subvolume that isn't being
      used and doesn't contains links to other subvolumes can be destroyed.
      Signed-off-by: NYan Zheng <zheng.yan@oracle.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      76dda93c
    • Y
      Btrfs: speed up snapshot dropping · 1c4850e2
      Yan, Zheng 提交于
      This patch contains two changes to avoid unnecessary tree block reads during
      snapshot dropping.
      
      First, check tree block's reference count and flags before reading the tree
      block. if reference count > 1 and there is no need to update backrefs, we can
      avoid reading the tree block.
      
      Second, save when snapshot was created in root_key.offset. we can compare block
      pointer's generation with snapshot's creation generation during updating
      backrefs. If a given block was created before snapshot was created, the
      snapshot can't be the tree block's owner. So we can avoid reading the block.
      Signed-off-by: NYan Zheng <zheng.yan@oracle.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      1c4850e2
  14. 18 9月, 2009 1 次提交
    • Y
      Btrfs: improve async block group caching · 11833d66
      Yan Zheng 提交于
      This patch gets rid of two limitations of async block group caching.
      The old code delays handling pinned extents when block group is in
      caching. To allocate logged file extents, the old code need wait
      until block group is fully cached. To get rid of the limitations,
      This patch introduces a data structure to track the progress of
      caching. Base on the caching progress, we know which extents should
      be added to the free space cache when handling the pinned extents.
      The logged file extents are also handled in a similar way.
      
      This patch also changes how pinned extents are tracked. The old
      code uses one tree to track pinned extents, and copy the pinned
      extents tree at transaction commit time. This patch makes it use
      two trees to track pinned extents. One tree for extents that are
      pinned in the running transaction, one tree for extents that can
      be unpinned. At transaction commit time, we swap the two trees.
      Signed-off-by: NYan Zheng <zheng.yan@oracle.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      11833d66
  15. 14 9月, 2009 1 次提交
    • C
      block: use blkdev_issue_discard in blk_ioctl_discard · 746cd1e7
      Christoph Hellwig 提交于
      blk_ioctl_discard duplicates large amounts of code from blkdev_issue_discard,
      the only difference between the two is that blkdev_issue_discard needs to
      send a barrier discard request and blk_ioctl_discard a non-barrier one,
      and blk_ioctl_discard needs to wait on the request.  To facilitates this
      add a flags argument to blkdev_issue_discard to control both aspects of the
      behaviour.  This will be very useful later on for using the waiting
      funcitonality for other callers.
      
      Based on an earlier patch from Matthew Wilcox <matthew@wil.cx>.
      Signed-off-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NJens Axboe <jens.axboe@oracle.com>
      746cd1e7
  16. 12 9月, 2009 1 次提交
    • C
      Btrfs: switch extent_map to a rw lock · 890871be
      Chris Mason 提交于
      There are two main users of the extent_map tree.  The
      first is regular file inodes, where it is evenly spread
      between readers and writers.
      
      The second is the chunk allocation tree, which maps blocks from
      logical addresses to phyiscal ones, and it is 99.99% reads.
      
      The mapping tree is a point of lock contention during heavy IO
      workloads, so this commit switches things to a rw lock.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      890871be
  17. 01 8月, 2009 1 次提交
    • C
      Btrfs: make sure the async caching thread advances the key · 013f1b12
      Chris Mason 提交于
      The async caching thread can end up looping forever if a given
      search puts it at the last key in a leaf.  It will end up calling
      btrfs_next_leaf and then checking if it needs to politely drop
      the read semaphore.
      
      Most of the time this looping isn't noticed because it is able to
      make progress the next time around.  But, during log replay,
      we wait on the async caching thread to finish, and the async thread
      is waiting on the commit, and no progress is really made.
      
      The fix used here is to copy the key out of the next leaf,
      that way our search lands there properly.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      013f1b12
  18. 30 7月, 2009 2 次提交
    • C
      Btrfs: be more polite in the async caching threads · f36f3042
      Chris Mason 提交于
      The semaphore used by the async caching threads can prevent a
      transaction commit, which can make the FS appear to stall.  This
      releases the semaphore more often when a transaction commit is
      in progress.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      f36f3042
    • Y
      Btrfs: preserve commit_root for async caching · 276e680d
      Yan Zheng 提交于
      The async block group caching code uses the commit_root pointer
      to get a stable version of the extent allocation tree for scanning.
      This copy of the tree root isn't going to change and it significantly
      reduces the complexity of the scanning code.
      
      During a commit, we have a loop where we update the extent allocation
      tree root.  We need to loop because updating the root pointer in
      the tree of tree roots may allocate blocks which may change the
      extent allocation tree.
      
      Right now the commit_root pointer is changed inside this loop.  It
      is more correct to change the commit_root pointer only after all the
      looping is done.
      Signed-off-by: NYan Zheng <zheng.yan@oracle.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      276e680d
  19. 28 7月, 2009 2 次提交
    • Y
      Btrfs: Fix async caching interaction with unmount · f25784b3
      Yan Zheng 提交于
      - don't stop the caching thread until btrfs_commit_super return.
      
      - if caching is interrupted by umount, set last to (u64)-1.
        otherwise the un-scanned range of block group will be considered
        as free extent.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      f25784b3
    • J
      Btrfs: change how we unpin extents · 68b38550
      Josef Bacik 提交于
      We are racy with async block caching and unpinning extents.  This patch makes
      things much less complicated by only unpinning the extent if the block group is
      cached.  We check the block_group->cached var under the block_group->lock spin
      lock.  If it is set to BTRFS_CACHE_FINISHED then we update the pinned counters,
      and unpin the extent and add the free space back.  If it is not set to this, we
      start the caching of the block group so the next time we unpin extents we can
      unpin the extent.  This keeps us from racing with the async caching threads,
      lets us kill the fs wide async thread counter, and keeps us from having to set
      DELALLOC bits for every extent we hit if there are caching kthreads going.
      
      One thing that needed to be changed was btrfs_free_super_mirror_extents.  Now
      instead of just looking for LOCKED extents, we also look for DIRTY extents,
      since we could have left some extents pinned in the previous transaction that
      will never get freed now that we are unmounting, which would cause us to leak
      memory.  So btrfs_free_super_mirror_extents has been changed to
      btrfs_free_pinned_extents, and it will clear the extents locked for the super
      mirror, and any remaining pinned extents that may be present.  Thank you,
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      68b38550
  20. 25 7月, 2009 1 次提交
    • C
      Btrfs: clear all space_info->full after removing a block group · 283bb197
      Chris Mason 提交于
      Btrfs allocates individual extents from block groups, and each
      block group has a specific type.  It may hold metadata, data
      mirrored or striped etc.
      
      When we balance space (btrfs-vol -b) or remove a drive (btrfs-vol -r)
      we free block groups.  Once a block group is freed, the space it was
      using on the device may be available for use by new block groups.
      
      btrfs_remove_block_group was clearing the flag that said
      'our devices are full, don't even try to allocate new block groups',
      but it was only clearing that flag for a specific type of block group.
      
      This commit clears the full flag for all of the types of block groups,
      making it much more likely that we'll be able to balance space when
      the drive is close to full.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      283bb197
  21. 24 7月, 2009 2 次提交
    • J
      Btrfs: async block group caching · 817d52f8
      Josef Bacik 提交于
      This patch moves the caching of the block group off to a kthread in order to
      allow people to allocate sooner.  Instead of blocking up behind the caching
      mutex, we instead kick of the caching kthread, and then attempt to make an
      allocation.  If we cannot, we wait on the block groups caching waitqueue, which
      the caching kthread will wake the waiting threads up everytime it finds 2 meg
      worth of space, and then again when its finished caching.  This is how I tested
      the speedup from this
      
      mkfs the disk
      mount the disk
      fill the disk up with fs_mark
      unmount the disk
      mount the disk
      time touch /mnt/foo
      
      Without my changes this took 11 seconds on my box, with these changes it now
      takes 1 second.
      
      Another change thats been put in place is we lock the super mirror's in the
      pinned extent map in order to keep us from adding that stuff as free space when
      caching the block group.  This doesn't really change anything else as far as the
      pinned extent map is concerned, since for actual pinned extents we use
      EXTENT_DIRTY, but it does mean that when we unmount we have to go in and unlock
      those extents to keep from leaking memory.
      
      I've also added a check where when we are reading block groups from disk, if the
      amount of space used == the size of the block group, we go ahead and mark the
      block group as cached.  This drastically reduces the amount of time it takes to
      cache the block groups.  Using the same test as above, except doing a dd to a
      file and then unmounting, it used to take 33 seconds to umount, now it takes 3
      seconds.
      
      This version uses the commit_root in the caching kthread, and then keeps track
      of how many async caching threads are running at any given time so if one of the
      async threads is still running as we cross transactions we can wait until its
      finished before handling the pinned extents.  Thank you,
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      817d52f8
    • J
      Btrfs: use hybrid extents+bitmap rb tree for free space · 96303081
      Josef Bacik 提交于
      Currently btrfs has a problem where it can use a ridiculous amount of RAM simply
      tracking free space.  As free space gets fragmented, we end up with thousands of
      entries on an rb-tree per block group, which usually spans 1 gig of area.  Since
      we currently don't ever flush free space cache back to disk this gets to be a
      bit unweildly on large fs's with lots of fragmentation.
      
      This patch solves this problem by using PAGE_SIZE bitmaps for parts of the free
      space cache.  Initially we calculate a threshold of extent entries we can
      handle, which is however many extent entries we can cram into 16k of ram.  The
      maximum amount of RAM that should ever be used to track 1 gigabyte of diskspace
      will be 32k of RAM, which scales much better than we did before.
      
      Once we pass the extent threshold, we start adding bitmaps and using those
      instead for tracking the free space.  This patch also makes it so that any free
      space thats less than 4 * sectorsize we go ahead and put into a bitmap.  This is
      nice since we try and allocate out of the front of a block group, so if the
      front of a block group is heavily fragmented and then has a huge chunk of free
      space at the end, we go ahead and add the fragmented areas to bitmaps and use a
      normal extent entry to track the big chunk at the back of the block group.
      
      I've also taken the opportunity to revamp how we search for free space.
      Previously we indexed free space via an offset indexed rb tree and a bytes
      indexed rb tree.  I've dropped the bytes indexed rb tree and use only the offset
      indexed rb tree.  This cuts the number of tree operations we were doing
      previously down by half, and gives us a little bit of a better allocation
      pattern since we will always start from a specific offset and search forward
      from there, instead of searching for the size we need and try and get it as
      close as possible to the offset we want.
      
      I've given this a healthy amount of testing pre-new format stuff, as well as
      post-new format stuff.  I've booted up my fedora box which is installed on btrfs
      with this patch and ran with it for a few days without issues.  I've not seen
      any performance regressions in any of my tests.
      
      Since the last patch Yan Zheng fixed a problem where we could have overlapping
      entries, so updating their offset inline would cause problems.  Thanks,
      Signed-off-by: NJosef Bacik <jbacik@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      96303081
  22. 22 7月, 2009 1 次提交
    • Y
      Btrfs: make sure all dirty blocks are written at commit time · 4a8c9a62
      Yan Zheng 提交于
      Write dirty block groups may allocate new block, and so may add new delayed
      back ref. btrfs_run_delayed_refs may make some block groups dirty.
      
      commit_cowonly_roots does not handle the recursion properly, and some dirty
      blocks can be left unwritten at commit time. This patch moves
      btrfs_run_delayed_refs into the loop that writes dirty block groups, and makes
      the code not break out of the loop until there are no dirty block groups or
      delayed back refs.
      Signed-off-by: NYan Zheng <zheng.yan@oracle.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      4a8c9a62
  23. 03 7月, 2009 1 次提交