1. 29 1月, 2010 3 次提交
  2. 18 1月, 2010 1 次提交
  3. 18 12月, 2009 1 次提交
    • J
      Btrfs: make metadata chunks smaller · 83d3c969
      Josef Bacik 提交于
      This patch makes us a bit less zealous about making sure we have enough free
      metadata space by pearing down the size of new metadata chunks to 256mb instead
      of 1gb.  Also, we used to try an allocate metadata chunks when allocating data,
      but that sort of thing is done elsewhere now so we can just remove it.  With my
      -ENOSPC test I used to have 3gb reserved for metadata out of 75gb, now I have
      1.7gb.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      83d3c969
  4. 30 9月, 2009 1 次提交
    • J
      Btrfs: introduce missing kfree · fd2696f3
      Julia Lawall 提交于
      Error handling code following a kzalloc should free the allocated data.
      
      The semantic match that finds the problem is as follows:
      (http://www.emn.fr/x-info/coccinelle/)
      
      // <smpl>
      @r exists@
      local idexpression x;
      statement S;
      expression E;
      identifier f,f1,l;
      position p1,p2;
      expression *ptr != NULL;
      @@
      
      x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
      ...
      if (x == NULL) S
      <... when != x
           when != if (...) { <+...x...+> }
      (
      x->f1 = E
      |
       (x->f1 == NULL || ...)
      |
       f(...,x->f1,...)
      )
      ...>
      (
       return \(0\|<+...x...+>\|ptr\);
      |
       return@p2 ...;
      )
      
      @script:python@
      p1 << r.p1;
      p2 << r.p2;
      @@
      
      print "* file: %s kmalloc %s return %s" % (p1[0].file,p1[0].line,p2[0].line)
      // </smpl>
      Signed-off-by: NJulia Lawall <julia@diku.dk>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      fd2696f3
  5. 22 9月, 2009 1 次提交
    • 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
  6. 12 9月, 2009 2 次提交
    • 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
    • C
      Btrfs: tweak congestion backoff · 57fd5a5f
      Chris Mason 提交于
      The btrfs io submission thread tries to back off congested devices in
      favor of rotating off to another disk.
      
      But, it tries to make sure it submits at least some IO before rotating
      on (the others may be congested too), and so it has a magic number of
      requests it tries to write before it hops.
      
      This makes the magic number smaller.  Testing shows that we're spending
      too much time on congested devices and leaving the other devices idle.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      57fd5a5f
  7. 11 9月, 2009 1 次提交
  8. 25 7月, 2009 1 次提交
    • C
      Btrfs: find smallest available device extent during chunk allocation · 9779b72f
      Chris Mason 提交于
      Allocating new block group is easy when the disk has plenty of space.
      But things get difficult as the disk fills up, especially if
      the FS has been run through btrfs-vol -b.  The balance operation
      is likely to make the total bytes available on the device greater
      than the largest extent we'll actually be able to allocate.
      
      But the device extent allocation code incorrectly assumes that a device
      with 5G free will be able to allocate a 5G extent.  It isn't normally a
      problem because device extents don't get freed unless btrfs-vol -b
      is run.
      
      This fixes the device extent allocator to remember the largest free
      extent it can find, and then uses that value as a fallback.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      9779b72f
  9. 24 7月, 2009 1 次提交
  10. 23 7月, 2009 1 次提交
    • D
      Btrfs: Remove broken sanity check from btrfs_rmap_block() · 3acada49
      David Woodhouse 提交于
      It was never actually doing anything anyway (see the loop condition),
      and it would be difficult to make it work for RAID[56].
      
      Even if it was actually working, it's checking for the wrong thing
      anyway. Instead of checking whether we list a block which _doesn't_ land
      at the relevant physical location, it should be checking that we _have_
      listed all the logical blocks which refer to the required physical
      location on all devices.
      
      This function is only called from remove_sb_from_cache() to ensure that
      we reserve the logical blocks which would reside at the same physical
      location as the superblock copies. So listing more blocks than we need
      is actually OK.
      
      With RAID[56] we're going to throw away an entire stripe for each block
      we have to ignore, so we _are_ going to list blocks other than the
      ones which actually contain the superblock.
      Signed-off-by: NDavid Woodhouse <David.Woodhouse@intel.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      3acada49
  11. 22 7月, 2009 1 次提交
  12. 11 6月, 2009 1 次提交
    • C
      Btrfs: avoid races between super writeout and device list updates · e5e9a520
      Chris Mason 提交于
      On multi-device filesystems, btrfs writes supers to all of the devices
      before considering a sync complete.  There wasn't any additional
      locking between super writeout and the device list management code
      because device management was done inside a transaction and
      super writeout only happened  with no transation writers running.
      
      With the btrfs fsync log and other async transaction updates, this
      has been racey for some time.  This adds a mutex to protect
      the device list.  The existing volume mutex could not be reused due to
      transaction lock ordering requirements.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      e5e9a520
  13. 10 6月, 2009 4 次提交
    • C
      Btrfs: autodetect SSD devices · c289811c
      Chris Mason 提交于
      During mount, btrfs will check the queue nonrot flag
      for all the devices found in the FS.  If they are all
      non-rotating, SSD mode is enabled by default.
      
      If the FS was mounted with -o nossd, the non-rotating
      flag is ignored.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      c289811c
    • C
      Btrfs: avoid IO stalls behind congested devices in a multi-device FS · d644d8a1
      Chris Mason 提交于
      The btrfs IO submission threads try to service a bunch of devices with a small
      number of threads.  They do a congestion check to try and avoid waiting
      on requests for a busy device.
      
      The checks make sure we've sent a few requests down to a given device just so
      that we aren't bouncing between busy devices without actually sending down
      any IO.  The counter used to decide if we can switch to the next device
      is somewhat overloaded.  It is also being used to decide if we've done
      a good batch of requests between the WRITE_SYNC or regular priority lists.
      It may get reset to zero often, leaving us hammering on a busy device
      instead of moving on to another disk.
      
      This commit adds a new counter for the number of bios sent while
      servicing a device.  It doesn't get reset or fiddled with.  On
      multi-device filesystems, this fixes IO stalls in streaming
      write workloads.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      d644d8a1
    • C
      Btrfs: don't allow WRITE_SYNC bios to starve out regular writes · d84275c9
      Chris Mason 提交于
      Btrfs uses dedicated threads to submit bios when checksumming is on,
      which allows us to make sure the threads dedicated to checksumming don't get
      stuck waiting for requests.  For each btrfs device, there are
      two lists of bios.  One list is for WRITE_SYNC bios and the other
      is for regular priority bios.
      
      The IO submission threads used to process all of the WRITE_SYNC bios first and
      then switch to the regular bios.  This commit makes sure we don't completely
      starve the regular bios by rotating between the two lists.
      
      WRITE_SYNC bios are still favored 2:1 over the regular bios, and this tries
      to run in batches to avoid seeking.  Benchmarking shows this eliminates
      stalls during streaming buffered writes on both multi-device and
      single device filesystems.
      
      If the regular bios starve, the system can end up with a large amount of ram
      pinned down in writeback pages.  If we are a little more fair between the two
      classes, we're able to keep throughput up and make progress on the bulk of
      our dirty ram.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      d84275c9
    • Y
      Btrfs: Mixed back reference (FORWARD ROLLING FORMAT CHANGE) · 5d4f98a2
      Yan Zheng 提交于
      This commit introduces a new kind of back reference for btrfs metadata.
      Once a filesystem has been mounted with this commit, IT WILL NO LONGER
      BE MOUNTABLE BY OLDER KERNELS.
      
      When a tree block in subvolume tree is cow'd, the reference counts of all
      extents it points to are increased by one.  At transaction commit time,
      the old root of the subvolume is recorded in a "dead root" data structure,
      and the btree it points to is later walked, dropping reference counts
      and freeing any blocks where the reference count goes to 0.
      
      The increments done during cow and decrements done after commit cancel out,
      and the walk is a very expensive way to go about freeing the blocks that
      are no longer referenced by the new btree root.  This commit reduces the
      transaction overhead by avoiding the need for dead root records.
      
      When a non-shared tree block is cow'd, we free the old block at once, and the
      new block inherits old block's references. When a tree block with reference
      count > 1 is cow'd, we increase the reference counts of all extents
      the new block points to by one, and decrease the old block's reference count by
      one.
      
      This dead tree avoidance code removes the need to modify the reference
      counts of lower level extents when a non-shared tree block is cow'd.
      But we still need to update back ref for all pointers in the block.
      This is because the location of the block is recorded in the back ref
      item.
      
      We can solve this by introducing a new type of back ref. The new
      back ref provides information about pointer's key, level and in which
      tree the pointer lives. This information allow us to find the pointer
      by searching the tree. The shortcoming of the new back ref is that it
      only works for pointers in tree blocks referenced by their owner trees.
      
      This is mostly a problem for snapshots, where resolving one of these
      fuzzy back references would be O(number_of_snapshots) and quite slow.
      The solution used here is to use the fuzzy back references in the common
      case where a given tree block is only referenced by one root,
      and use the full back references when multiple roots have a reference
      on a given block.
      
      This commit adds per subvolume red-black tree to keep trace of cached
      inodes. The red-black tree helps the balancing code to find cached
      inodes whose inode numbers within a given range.
      
      This commit improves the balancing code by introducing several data
      structures to keep the state of balancing. The most important one
      is the back ref cache. It caches how the upper level tree blocks are
      referenced. This greatly reduce the overhead of checking back ref.
      
      The improved balancing code scales significantly better with a large
      number of snapshots.
      
      This is a very large commit and was written in a number of
      pieces.  But, they depend heavily on the disk format change and were
      squashed together to make sure git bisect didn't end up in a
      bad state wrt space balancing or the format change.
      Signed-off-by: NYan Zheng <zheng.yan@oracle.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      5d4f98a2
  14. 04 6月, 2009 1 次提交
  15. 27 4月, 2009 1 次提交
  16. 21 4月, 2009 1 次提交
    • C
      Btrfs: use WRITE_SYNC for synchronous writes · ffbd517d
      Chris Mason 提交于
      Part of reducing fsync/O_SYNC/O_DIRECT latencies is using WRITE_SYNC for
      writes we plan on waiting on in the near future.  This patch
      mirrors recent changes in other filesystems and the generic code to
      use WRITE_SYNC when WB_SYNC_ALL is passed and to use WRITE_SYNC for
      other latency critical writes.
      
      Btrfs uses async worker threads for checksumming before the write is done,
      and then again to actually submit the bios.  The bio submission code just
      runs a per-device list of bios that need to be sent down the pipe.
      
      This list is split into low priority and high priority lists so the
      WRITE_SYNC IO happens first.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      ffbd517d
  17. 03 4月, 2009 2 次提交
    • C
      Btrfs: unplug in the async bio submission threads · bedf762b
      Chris Mason 提交于
      Btrfs pages being written get set to writeback, and then may go through
      a number of steps before they hit the block layer.  This includes compression,
      checksumming and async bio submission.
      
      The end result is that someone who writes a page and then does
      wait_on_page_writeback is likely to unplug the queue before the bio they
      cared about got there.
      
      We could fix this by marking bios sync, or by doing more frequent unplugs,
      but this commit just changes the async bio submission code to unplug
      after it has processed all the bios for a device.  The async bio submission
      does a fair job of collection bios, so this shouldn't be a huge problem
      for reducing merging at the elevator.
      
      For streaming O_DIRECT writes on a 5 drive array, it boosts performance
      from 386MB/s to 460MB/s.
      
      Thanks to Hisashi Hifumi for helping with this work.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      bedf762b
    • C
      Btrfs: keep processing bios for a given bdev if our proc is batching · b765ead5
      Chris Mason 提交于
      Btrfs uses async helper threads to submit write bios so the checksumming
      helper threads don't block on the disk.
      
      The submit bio threads may process bios for more than one block device,
      so when they find one device congested they try to move on to other
      devices instead of blocking in get_request_wait for one device.
      
      This does a pretty good job of keeping multiple devices busy, but the
      congested flag has a number of problems.  A congested device may still
      give you a request, and other procs that aren't backing off the congested
      device may starve you out.
      
      This commit uses the io_context stored in current to decide if our process
      has been made a batching process by the block layer.  If so, it keeps
      sending IO down for at least one batch.  This helps make sure we do
      a good amount of work each time we visit a bdev, and avoids large IO
      stalls in multi-device workloads.
      
      It's also very ugly.  A better solution is in the works with Jens Axboe.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      b765ead5
  18. 11 3月, 2009 2 次提交
    • C
      Btrfs: Clear space_info full when adding new devices · 913d952e
      Chris Mason 提交于
      The full flag on the space info structs tells the allocator not to try
      and allocate more chunks because the devices in the FS are fully allocated.
      
      When more devices are added, we need to clear the full flag so the allocator
      knows it has more space available.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      913d952e
    • C
      Btrfs: Fix locking around adding new space_info · 4184ea7f
      Chris Mason 提交于
      Storage allocated to different raid levels in btrfs is tracked by
      a btrfs_space_info structure, and all of the current space_infos are
      collected into a list_head.
      
      Most filesystems have 3 or 4 of these structs total, and the list is
      only changed when new raid levels are added or at unmount time.
      
      This commit adds rcu locking on the list head, and properly frees
      things at unmount time.  It also clears the space_info->full flag
      whenever new space is added to the FS.
      
      The locking for the space info list goes like this:
      
      reads: protected by rcu_read_lock()
      writes: protected by the chunk_mutex
      
      At unmount time we don't need special locking because all the readers
      are gone.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      4184ea7f
  19. 13 2月, 2009 1 次提交
    • C
      Btrfs: make a lockdep class for the extent buffer locks · 4008c04a
      Chris Mason 提交于
      Btrfs is currently using spin_lock_nested with a nested value based
      on the tree depth of the block.  But, this doesn't quite work because
      the max tree depth is bigger than what spin_lock_nested can deal with,
      and because locks are sometimes taken before the level field is filled in.
      
      The solution here is to use lockdep_set_class_and_name instead, and to
      set the class before unlocking the pages when the block is read from the
      disk and just after init of a freshly allocated tree block.
      
      btrfs_clear_path_blocking is also changed to take the locks in the proper
      order, and it also makes sure all the locks currently held are properly
      set to blocking before it tries to retake the spinlocks.  Otherwise, lockdep
      gets upset about bad lock orderin.
      
      The lockdep magic cam from Peter Zijlstra <peterz@infradead.org>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      4008c04a
  20. 12 2月, 2009 1 次提交
    • J
      Btrfs: fs/btrfs/volumes.c: remove useless kzalloc · 3f3420df
      Julia Lawall 提交于
      The call to kzalloc is followed by a kmalloc whose result is stored in the
      same variable.
      
      The semantic match that finds the problem is as follows:
      (http://www.emn.fr/x-info/coccinelle/)
      
      // <smpl>
      @r exists@
      local idexpression x;
      statement S;
      expression E;
      identifier f,l;
      position p1,p2;
      expression *ptr != NULL;
      @@
      
      (
      if ((x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...)) == NULL) S
      |
      x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
      ...
      if (x == NULL) S
      )
      <... when != x
           when != if (...) { <+...x...+> }
      x->f = E
      ...>
      (
       return \(0\|<+...x...+>\|ptr\);
      |
       return@p2 ...;
      )
      
      @script:python@
      p1 << r.p1;
      p2 << r.p2;
      @@
      
      print "* file: %s kmalloc %s return %s" % (p1[0].file,p1[0].line,p2[0].line)
      // </smpl>
      Signed-off-by: NJulia Lawall <julia@diku.dk>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      3f3420df
  21. 04 2月, 2009 1 次提交
  22. 21 1月, 2009 3 次提交
  23. 17 1月, 2009 1 次提交
    • C
      Btrfs: Clear the device->running_pending flag before bailing on congestion · 1d9e2ae9
      Chris Mason 提交于
      Btrfs maintains a queue of async bio submissions so the checksumming
      threads don't have to wait on get_request_wait.  In order to avoid
      extra wakeups, this code has a running_pending flag that is used
      to tell new submissions they don't need to wake the thread.
      
      When the threads notice congestion on a single device, they
      may decide to requeue the job and move on to other devices.  This
      makes sure the running_pending flag is cleared before the
      job is requeued.
      
      It should help avoid IO stalls by making sure the task is woken up
      when new submissions come in.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      1d9e2ae9
  24. 06 1月, 2009 1 次提交
  25. 12 12月, 2008 1 次提交
  26. 09 12月, 2008 4 次提交
    • C
      Btrfs: Add inode sequence number for NFS and reserved space in a few structs · c3027eb5
      Chris Mason 提交于
      This adds a sequence number to the btrfs inode that is increased on
      every update.  NFS will be able to use that to detect when an inode has
      changed, without relying on inaccurate time fields.
      
      While we're here, this also:
      
      Puts reserved space into the super block and inode
      
      Adds a log root transid to the super so we can pick the newest super
      based on the fsync log as well as the main transaction ID.  For now
      the log root transid is always zero, but that'll get fixed.
      
      Adds a starting offset to the dev_item.  This will let us do better
      alignment calculations if we know the start of a partition on the disk.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      c3027eb5
    • C
      Btrfs: Use map_private_extent_buffer during generic_bin_search · 934d375b
      Chris Mason 提交于
      It is possible that generic_bin_search will be called on a tree block
      that has not been locked.  This happens because cache_block_block skips
      locking on the tree blocks.
      
      Since the tree block isn't locked, we aren't allowed to change
      the extent_buffer->map_token field.  Using map_private_extent_buffer
      avoids any changes to the internal extent buffer fields.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      934d375b
    • Y
      Btrfs: superblock duplication · a512bbf8
      Yan Zheng 提交于
      This patch implements superblock duplication. Superblocks
      are stored at offset 16K, 64M and 256G on every devices.
      Spaces used by superblocks are preserved by the allocator,
      which uses a reverse mapping function to find the logical
      addresses that correspond to superblocks. Thank you,
      Signed-off-by: NYan Zheng <zheng.yan@oracle.com>
      a512bbf8
    • C
      Btrfs: move data checksumming into a dedicated tree · d20f7043
      Chris Mason 提交于
      Btrfs stores checksums for each data block.  Until now, they have
      been stored in the subvolume trees, indexed by the inode that is
      referencing the data block.  This means that when we read the inode,
      we've probably read in at least some checksums as well.
      
      But, this has a few problems:
      
      * The checksums are indexed by logical offset in the file.  When
      compression is on, this means we have to do the expensive checksumming
      on the uncompressed data.  It would be faster if we could checksum
      the compressed data instead.
      
      * If we implement encryption, we'll be checksumming the plain text and
      storing that on disk.  This is significantly less secure.
      
      * For either compression or encryption, we have to get the plain text
      back before we can verify the checksum as correct.  This makes the raid
      layer balancing and extent moving much more expensive.
      
      * It makes the front end caching code more complex, as we have touch
      the subvolume and inodes as we cache extents.
      
      * There is potentitally one copy of the checksum in each subvolume
      referencing an extent.
      
      The solution used here is to store the extent checksums in a dedicated
      tree.  This allows us to index the checksums by phyiscal extent
      start and length.  It means:
      
      * The checksum is against the data stored on disk, after any compression
      or encryption is done.
      
      * The checksum is stored in a central location, and can be verified without
      following back references, or reading inodes.
      
      This makes compression significantly faster by reducing the amount of
      data that needs to be checksummed.  It will also allow much faster
      raid management code in general.
      
      The checksums are indexed by a key with a fixed objectid (a magic value
      in ctree.h) and offset set to the starting byte of the extent.  This
      allows us to copy the checksum items into the fsync log tree directly (or
      any other tree), without having to invent a second format for them.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      d20f7043
  27. 02 12月, 2008 1 次提交