1. 12 Nov, 2013 40 commits
    • Liu Bo's avatar
      Btrfs: kill unused code in btrfs_search_forward · 498456d3
      Liu Bo authored
      After commit de78b51a
      (btrfs: remove cache only arguments from defrag path), @blockptr is no more
      used.
      Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      498456d3
    • Liu Bo's avatar
      Btrfs: cleanup dead code of defragment · 8319bfe1
      Liu Bo authored
      @is_extent is no more needed since we don't defrag extent root.
      Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      8319bfe1
    • Filipe David Borba Manana's avatar
      Btrfs: remove unnecessary key copy when logging inode · efd0c405
      Filipe David Borba Manana authored
      The btrfs_insert_empty_item() function doesn't modify its
      key argument.
      Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
      Reviewed-by: default avatarZach Brown <zab@redhat.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      efd0c405
    • Chandra Seetharaman's avatar
      Btrfs: Simplify the logic in alloc_extent_buffer() for existing extent buffer case · 452c75c3
      Chandra Seetharaman authored
      alloc_extent_buffer() uses radix_tree_lookup() when radix_tree_insert()
      fails with EEXIST. That part of the code is very similar to the code in
      find_extent_buffer(). This patch replaces radix_tree_lookup() and
      surrounding code in alloc_extent_buffer() with find_extent_buffer().
      
      Note that radix_tree_lookup() does not need to be protected by
      tree->buffer_lock. It is protected by eb->refs.
      
      While at it, this patch
        - changes the other usage of radix_tree_lookup() in alloc_extent_buffer()
          with find_extent_buffer() to reduce redundancy.
        - removes the unused argument 'len' to find_extent_buffer().
      Signed-Off-by: default avatarChandra Seetharaman <sekharan@us.ibm.com>
      Reviewed-by: default avatarZach Brown <zab@redhat.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      452c75c3
    • Josef Bacik's avatar
      Btrfs: fix up seek_hole/seek_data handling · 7f4ca37c
      Josef Bacik authored
      Whoever wrote this was braindead.  Also it doesn't work right if you have
      VACANCY's since we assumed you would only have that at the end of the file,
      which won't be the case in the near future.  I tested this with generic/285 and
      generic/286 as well as the btrfs tests that use fssum since it uses
      seek_hole/seek_data to verify things are ok.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      7f4ca37c
    • Josef Bacik's avatar
      Btrfs: add an assert to btrfs_lookup_csums_range for alignment · 4277a9c3
      Josef Bacik authored
      I was hitting weird issues when trying to remove hole extents and it turned out
      it was because I was sending non-aligned offsets down to
      btrfs_lookup_csums_range.  So add an assert for this in case somebody trips over
      this in the future.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      4277a9c3
    • Josef Bacik's avatar
      Btrfs: fix hole check in log_one_extent · ed9e8af8
      Josef Bacik authored
      I added an assert to make sure we were looking up aligned offsets for csums and
      I tripped it when running xfstests.  This is because log_one_extent was checking
      if block_start == 0 for a hole instead of EXTENT_MAP_HOLE.  This worked out fine
      in practice it seems, but it adds a lot of extra work that is uneeded.  With
      this fix I'm no longer tripping my assert.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      ed9e8af8
    • Josef Bacik's avatar
      Btrfs: add a sanity test for a vacant extent at the front of a file · 0e30db86
      Josef Bacik authored
      Btrfs_get_extent was not handling this case properly, add a test to make sure we
      don't regress.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      0e30db86
    • Josef Bacik's avatar
      Btrfs: handle a missing extent for the first file extent · 25a50341
      Josef Bacik authored
      While trying to kill our hole extents I noticed I was seeing problems where we
      seek into a file and then start writing and then try to fiemap that file later.
      This is because we search for offset 0, don't find anything and so back up one
      slot, which puts us at the inode ref or something like that, which means we goto
      not_found and create an extent map for our entire search area.  This isn't quite
      what we want, we want to move forward one slot and see if there is an extent
      there so we can limit our hole extent.  This patch fixes this problem, I will
      add a testcase for this as well.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      25a50341
    • Josef Bacik's avatar
      Btrfs: stop all workers after we free block groups · 96192499
      Josef Bacik authored
      Stefan was hitting a panic in the async worker stuff because we had outstanding
      read bios while we were stopping the worker threads.  You could reproduce this
      easily if you mount -o nospace_cache and ran generic/273.  This is because the
      caching thread stuff is still going and we were stopping all the worker threads.
      We need to stop the workers after this work is done, and the free block groups
      code will wait for all the caching threads to stop first so we don't run into
      this problem.  With this patch we no longer panic.  Thanks,
      
      Cc: stable@vger.kernel.org
      Reported-by: default avatarStefan Behrens <sbehrens@giantdisaster.de>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      96192499
    • Josef Bacik's avatar
      Btrfs: add tests for btrfs_get_extent · aaedb55b
      Josef Bacik authored
      I'm going to be removing hole extents in the near future so I wanted to make a
      sanity test for btrfs_get_extent to make sure I don't break anything in the
      meantime.  This patch just puts btrfs_get_extent through its paces by giving it
      a completely unreasonable mapping to look at and make sure it is giving us back
      maps that make sense.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      aaedb55b
    • Josef Bacik's avatar
      Btrfs: add tests for find_lock_delalloc_range · 294e30fe
      Josef Bacik authored
      So both Liu and I made huge messes of find_lock_delalloc_range trying to fix
      stuff, me first by fixing extent size, then him by fixing something I broke and
      then me again telling him to fix it a different way.  So this is obviously a
      candidate for some testing.  This patch adds a pseudo fs so we can allocate fake
      inodes for tests that need an inode or pages.  Then it addes a bunch of tests to
      make sure find_lock_delalloc_range is acting the way it is supposed to.  With
      this patch and all of our previous patches to find_lock_delalloc_range I am sure
      it is working as expected now.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      294e30fe
    • Josef Bacik's avatar
      Btrfs: free reserved space on error in a few places · 857cc2fc
      Josef Bacik authored
      While trying to track down a reserved space leak I noticed a few places where we
      won't properly clean up reserved space if we have an error, this patch fixes
      those up.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      857cc2fc
    • Josef Bacik's avatar
      Btrfs: fixup reserved trace points · 0be5dc67
      Josef Bacik authored
      In trying to track down where we were leaking reserved space I noticed our
      reserve extent tracepoints are a little off.  First we were saying that the
      reserved space had been alloced in btrfs_reserve_extent, which isn't the case,
      this needs to be triggered when we actually allocate the space when we run the
      delayed ref.  We were also missing a few places where we should have been
      tracing the btrfs_reserve_extent_free tracepoint.  With these in place I was
      able to put together where we were leaking reserved space.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      0be5dc67
    • Josef Bacik's avatar
      Btrfs: free up block groups after everything · 2b1360da
      Josef Bacik authored
      If we abort a transaction we will do the tree log cleanup at unmount, but this
      happens after we free up the block groups.  This makes all the leak detection
      warnings go off because we think we've leaked space but in reality we just
      haven't cleaned it up yet.  So instead do the block group cleanup stuff after
      free'ing the fs roots so we don't get these warnings.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      2b1360da
    • Josef Bacik's avatar
      Btrfs: cleanup reserved space when freeing tree log on error · 681ae509
      Josef Bacik authored
      On error we will wait and free the tree log at unmount without a transaction.
      This means that the actual freeing of the blocks doesn't happen which means we
      complain about space leaks on unmount.  So to fix this just skip the transaction
      specific cleanup part of the tree log free'ing if we don't have a transaction
      and that way we can free up our reserved space and our counters stay happy.
      Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      681ae509
    • Josef Bacik's avatar
      Btrfs: do not free the dirty bytes from the trans block rsv on cleanup · eb58bb37
      Josef Bacik authored
      The transactions should be cleaning up their reservations on failure, this just
      causes us to have warnings on unmount because we go negative by free'ing
      reservations that have already been free'ed.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      eb58bb37
    • Filipe David Borba Manana's avatar
      Btrfs: fix memory leaks on transaction commit failure · 80d94fb3
      Filipe David Borba Manana authored
      Structures of the types tree_mod_elem and qgroup_update are allocated
      during transaction commit but were not being released if the call to
      btrfs_run_delayed_items() returned an error.
      
      Stack trace reported by kmemleak:
      
      unreferenced object 0xffff880679f0b398 (size 128):
        comm "umount", pid 21508, jiffies 4295967793 (age 36718.112s)
        hex dump (first 32 bytes):
          60 b5 f0 79 06 88 ff ff 00 00 00 00 00 00 00 00  `..y............
          00 00 00 00 00 00 00 00 50 1c 00 00 00 00 00 00  ........P.......
        backtrace:
          [<ffffffff81742d26>] kmemleak_alloc+0x26/0x50
          [<ffffffff811889c2>] kmem_cache_alloc_trace+0x112/0x200
          [<ffffffffa046f2d3>] tree_mod_log_insert_key.constprop.45+0x93/0x150 [btrfs]
          [<ffffffffa04720f9>] __btrfs_cow_block+0x299/0x4f0 [btrfs]
          [<ffffffffa0472510>] btrfs_cow_block+0x120/0x1f0 [btrfs]
          [<ffffffffa0476679>] btrfs_search_slot+0x449/0x930 [btrfs]
          [<ffffffffa048eecf>] btrfs_lookup_inode+0x2f/0xa0 [btrfs]
          [<ffffffffa04eb49c>] __btrfs_update_delayed_inode+0x1c/0x1d0 [btrfs]
          [<ffffffffa04eb9e2>] __btrfs_run_delayed_items+0x162/0x1e0 [btrfs]
          [<ffffffffa04eba63>] btrfs_delayed_inode_exit+0x3/0x20 [btrfs]
          [<ffffffffa0499c63>] btrfs_commit_transaction+0x203/0xa50 [btrfs]
          [<ffffffffa046b519>] btrfs_sync_fs+0x69/0x110 [btrfs]
          [<ffffffff811cb210>] __sync_filesystem+0x30/0x60
          [<ffffffff811cb2bb>] sync_filesystem+0x4b/0x70
          [<ffffffff8119ce7b>] generic_shutdown_super+0x3b/0xf0
          [<ffffffff8119cfc6>] kill_anon_super+0x16/0x30
      unreferenced object 0xffff880677e0dd88 (size 32):
        comm "umount", pid 21508, jiffies 4295967793 (age 36718.112s)
        hex dump (first 32 bytes):
          78 75 11 a9 06 88 ff ff 00 c0 e0 77 06 88 ff ff  xu.........w....
          40 c3 a2 70 06 88 ff ff 00 00 00 00 00 00 00 00  @..p............
        backtrace:
          [<ffffffff81742d26>] kmemleak_alloc+0x26/0x50
          [<ffffffff811889c2>] kmem_cache_alloc_trace+0x112/0x200
          [<ffffffffa04fa54f>] btrfs_qgroup_record_ref+0xf/0x90 [btrfs]
          [<ffffffffa04e1914>] btrfs_add_delayed_tree_ref+0xf4/0x170 [btrfs]
          [<ffffffffa048518a>] btrfs_free_tree_block+0x9a/0x220 [btrfs]
          [<ffffffffa0472163>] __btrfs_cow_block+0x303/0x4f0 [btrfs]
          [<ffffffffa0472510>] btrfs_cow_block+0x120/0x1f0 [btrfs]
          [<ffffffffa0476679>] btrfs_search_slot+0x449/0x930 [btrfs]
          [<ffffffffa048eecf>] btrfs_lookup_inode+0x2f/0xa0 [btrfs]
          [<ffffffffa04eb49c>] __btrfs_update_delayed_inode+0x1c/0x1d0 [btrfs]
          [<ffffffffa04eb9e2>] __btrfs_run_delayed_items+0x162/0x1e0 [btrfs]
          [<ffffffffa04eba63>] btrfs_delayed_inode_exit+0x3/0x20 [btrfs]
          [<ffffffffa0499c63>] btrfs_commit_transaction+0x203/0xa50 [btrfs]
          [<ffffffffa046b519>] btrfs_sync_fs+0x69/0x110 [btrfs]
          [<ffffffff811cb210>] __sync_filesystem+0x30/0x60
          [<ffffffff811cb2bb>] sync_filesystem+0x4b/0x70
      Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      80d94fb3
    • Ilya Dryomov's avatar
      Btrfs: fix the dev-replace suspend sequence · 539f358a
      Ilya Dryomov authored
      Replace progresses strictly from lower to higher offsets, and the
      progress is tracked in chunks, by storing the physical offset of the
      dev_extent which is being copied in the cursor_left field of
      btrfs_dev_replace_item.  When we are done copying the chunk,
      left_cursor is updated to point one byte past the dev_extent, so that
      on resume we can skip the dev_extents that have already been copied.
      
      There is a major bug (which goes all the way back to the inception of
      dev-replace in 3.8) in the way left_cursor is bumped: the bump is done
      unconditionally, without any regard to the scrub_chunk return value.
      On suspend (and also on any kind of error) scrub_chunk returns early,
      i.e. without completing the copy.  This leads to us skipping the chunk
      that hasn't been fully copied yet when resuming.
      
      Fix this by doing the cursor_left update only if scrub_chunk ret is 0.
      (On suspend scrub_chunk returns with -ECANCELED, so this fix covers
      both suspend and error cases.)
      
      Cc: Stefan Behrens <sbehrens@giantdisaster.de>
      Signed-off-by: default avatarIlya Dryomov <idryomov@gmail.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      539f358a
    • Filipe David Borba Manana's avatar
      Btrfs: improve inode hash function/inode lookup · 778ba82b
      Filipe David Borba Manana authored
      Currently the hash value used for adding an inode to the VFS's inode
      hash table consists of the plain inode number, which is a 64 bits
      integer. This results in hash table buckets (hlist_head lists) with
      too many elements for at least 2 important scenarios:
      
      1) When we have many subvolumes. Each subvolume has its own btree
         where its files and directories are added to, and each has its
         own objectid (inode number) namespace. This means that if we have
         N subvolumes, and all have inode number X associated to a file or
         directory, the corresponding inodes all map to the same hash table
         entry, resulting in a bucket (hlist_head list) with N elements;
      
      2) On 32 bits machines. Th VFS hash values are unsigned longs, which
         are 32 bits wide on 32 bits machines, and the inode (objectid)
         numbers are 64 bits unsigned integers. We simply cast the inode
         numbers to hash values, which means that for all inodes with the
         same 32 bits lower half, the same hash bucket is used for all of
         them. For example, all inodes with a number (objectid) between
         0x0000_0000_ffff_ffff and 0xffff_ffff_ffff_ffff will end up in
         the same hash table bucket.
      
      This change ensures the inode's hash value depends both on the
      objectid (inode number) and its subvolume's (btree root) objectid.
      For 32 bits machines, this change gives better entropy by making
      the hash value depend on both the upper and lower 32 bits of the
      64 bits hash previously computed.
      Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      778ba82b
    • Filipe David Borba Manana's avatar
      Btrfs: remove unnecessary tree search when logging inode · 3d41d702
      Filipe David Borba Manana authored
      In tree-log.c:btrfs_log_inode(), we keep calling btrfs_search_forward()
      until it returns a key whose objectid is higher than our inode or until
      the key's type is higher than our maximum allowed type.
      
      At the end of the loop, we increment our mininum search key's objectid
      and type regardless of our desired target objectid and maximum desired
      type, which causes another loop iteration that will call again
      btrfs_search_forward() just to figure out we've gone beyond our maximum
      key and exit the loop. Therefore while incrementing our minimum key,
      don't do it blindly and exit the loop immiediately if the next search
      key's objectid or type is beyond what we seek.
      
      Also after incrementing the type, set the key's offset to 0, which was
      missing and could make us loose some of the inode's items.
      Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      3d41d702
    • Filipe David Borba Manana's avatar
      6174d3cb
    • Liu Bo's avatar
      Btrfs: fix memory leak of chunks' extent map · 7d3d1744
      Liu Bo authored
      As we're hold a ref on looking up the extent map, we need to drop the ref
      before returning to callers.
      Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      7d3d1744
    • Miao Xie's avatar
      Btrfs: improve jitter performance of the sequential buffered write · fa7c1494
      Miao Xie authored
      The performance was slowed down sometimes when we ran sysbench to measure
      the performance of the sequential buffered write by 2 or more threads.
      
      It was because the write order of the test threads might be confused
      by the task scheduler, and the coming write would be beyond the end of
      the file, in this case, we need insert dummy file extents and create
      a hole for the area we skip. But in order to avoid the ongoing ordered
      extents which are in the area, we need wait for them. Unfortunately,
      the current code doesn't check if there are ordered extents in the area
      or not, try to find and flush the dirty pages directly, but in fact,
      there is no dirty page in that area, this step of the current code is
      unnecessary, and just wastes time. Sometimes, it would increase
      the contention of some locks, and makes the performance slow down suddenly.
      
      So we remove the ordered extent flush function before the check, and flush
      the dirty pages and wait for the ordered extents only when we find them.
      
      According to my test, we got 1-2 times of the performance regression when
      we ran the test by 10 times before applying this patch. After applying
      this patch, the regression went away.
      
      Test Environment:
       CPU:		1CPU * 4Cores
       Memory:	6GB
       Partition:	20GB
      
      Test Command:
       # sysbench --test=fileio --file-total-size=16G --file-test-mode=seqwr \
       > --num-threads=512 --file-block-size=16384 --max-time=60 --max-requests=0 run
      Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      fa7c1494
    • Miao Xie's avatar
      Btrfs: fix BUG_ON() casued by the reserved space migration · 20dd2cbf
      Miao Xie authored
      When we did space balance and snapshot creation at the same time, we might
      meet the following oops:
       kernel BUG at fs/btrfs/inode.c:3038!
       [SNIP]
       Call Trace:
       [<ffffffffa0411ec7>] btrfs_orphan_cleanup+0x293/0x407 [btrfs]
       [<ffffffffa042dc45>] btrfs_mksubvol.isra.28+0x259/0x373 [btrfs]
       [<ffffffffa042de85>] btrfs_ioctl_snap_create_transid+0x126/0x156 [btrfs]
       [<ffffffffa042dff1>] btrfs_ioctl_snap_create_v2+0xd0/0x121 [btrfs]
       [<ffffffffa0430b2c>] btrfs_ioctl+0x414/0x1854 [btrfs]
       [<ffffffff813b60b7>] ? __do_page_fault+0x305/0x379
       [<ffffffff811215a9>] vfs_ioctl+0x1d/0x39
       [<ffffffff81121d7c>] do_vfs_ioctl+0x32d/0x3e2
       [<ffffffff81057fe7>] ? finish_task_switch+0x80/0xb8
       [<ffffffff81121e88>] SyS_ioctl+0x57/0x83
       [<ffffffff813b39ff>] ? do_device_not_available+0x12/0x14
       [<ffffffff813b99c2>] system_call_fastpath+0x16/0x1b
       [SNIP]
       RIP  [<ffffffffa040da40>] btrfs_orphan_add+0xc3/0x126 [btrfs]
      
      The reason of the problem is that the relocation root creation stole
      the reserved space, which was reserved for orphan item deletion.
      
      There are several ways to fix this problem, one is to increasing
      the reserved space size of the space balace, and then we can use
      that space to create the relocation tree for each fs/file trees.
      But it is hard to calculate the suitable size because we doesn't
      know how many fs/file trees we need relocate.
      
      We fixed this problem by reserving the space for relocation root creation
      actively since the space it need is very small (one tree block, used for
      root node copy), then we use that reserved space to create the
      relocation tree. If we don't reserve space for relocation tree creation,
      we will use the reserved space of the balance.
      Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      20dd2cbf
    • Ross Kirk's avatar
      btrfs: remove unused parameter from btrfs_header_fsid · 0a4e5586
      Ross Kirk authored
      Remove unused parameter, 'eb'. Unused since introduction in
      5f39d397
      
      Updated to be rebased against current upstream and correct diff supplied this time!
      Signed-off-by: default avatarRoss Kirk <ross.kirk@gmail.com>
      Reviewed-by: default avatarEric Sandeen <sandeen@redhat.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      0a4e5586
    • Josef Bacik's avatar
      Btrfs: fix two use-after-free bugs with transaction cleanup · 724e2315
      Josef Bacik authored
      I was noticing the slab redzone stuff going off every once and a while during
      transaction aborts.  This was caused by two things
      
      1) We would walk the pending snapshots and set their error to -ECANCELED.  We
      don't need to do this, the snapshot stuff waits for a transaction commit and if
      there is a problem we just free our pending snapshot object and exit.  Doing
      this was causing us to touch the pending snapshot object after the thing had
      already been freed.
      
      2) We were freeing the transaction manually with wanton disregard for it's
      use_count reference counter.  To fix this I cleaned up the transaction freeing
      loop to either wait for the transaction commit to finish if it was in the middle
      of that (since it will be cleaned and freed up there) or to do the cleanup
      oursevles.
      
      I also moved the global "kill all things dirty everywhere" stuff outside of the
      transaction cleanup loop since that only needs to be done once.  With this patch
      I'm no longer seeing slab corruption because of use after frees.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      724e2315
    • Josef Bacik's avatar
      Btrfs: remove all BUG_ON()'s from commit_cowonly_roots · c16ce190
      Josef Bacik authored
      Noticed this when forcing errors to happen during delayed ref running.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      c16ce190
    • Josef Bacik's avatar
      Btrfs: don't delete ordered roots from list during cleanup · 1de2cfde
      Josef Bacik authored
      During transaction cleanup after an abort we are just removing roots from the
      ordered roots list which is incorrect.  We have a BUG_ON() to make sure that the
      root is still part of the ordered roots list when we put our ordered extent
      which we were tripping in this case.  So do like we do everywhere else and just
      move it to the tail of the ordered roots list and allow the normal cleanup to
      take care of stuff.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      1de2cfde
    • Josef Bacik's avatar
      Btrfs: cleanup transaction on abort · 4e121c06
      Josef Bacik authored
      If we abort not during a transaction commit we won't clean up anything until we
      unmount.  Unfortunately if we abort in the middle of writing out an ordered
      extent we won't clean it up and if somebody is waiting on that ordered extent
      they will wait forever.  To fix this just make the transaction kthread call the
      cleanup transaction stuff if it notices theres an error, and make
      btrfs_end_transaction wake up the transaction kthread if there is an error.
      Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      4e121c06
    • Josef Bacik's avatar
      Btrfs: do not release metadata for space cache inodes · b6d08f06
      Josef Bacik authored
      I've been testing our error paths and I was tripping the BUG_ON() in
      drop_outstanding_extent because our outstanding_extents is 0 for space cache
      inodes.  This is because we don't reserve metadata space for these inodes since
      we depend on the global block reserve for our space.  To fix this we need to
      make sure the DO_ACCOUNTING stuff doesn't actually call release_metadata for
      space cache inodes.  With this patch I'm no longer panicing.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      b6d08f06
    • Josef Bacik's avatar
      Btrfs: reset intwrite on transaction abort · e0228285
      Josef Bacik authored
      If we abort a transaction in the middle of a commit we weren't undoing the
      intwrite locking.  This patch fixes that problem.
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      e0228285
    • Josef Bacik's avatar
      Btrfs: relocate csums properly with prealloc extents · 4577b014
      Josef Bacik authored
      A user reported a problem where they were getting csum errors when running a
      balance and running systemd's journal.  This is because systemd is awesome and
      fallocate()'s its log space and writes into it.  Unfortunately we assume that
      when we read in all the csums for an extent that they are sequential starting at
      the bytenr we care about.  This obviously isn't the case for prealloc extents,
      where we could have written to the middle of the prealloc extent only, which
      means the csum would be for the bytenr in the middle of our range and not the
      front of our range.  Fix this by offsetting the new bytenr we are logging to
      based on the original bytenr the csum was for.  With this patch I no longer see
      the csum errors I was seeing.  Thanks,
      
      Cc: stable@vger.kernel.org
      Reported-by: default avatarChris Murphy <lists@colorremedies.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      4577b014
    • Filipe David Borba Manana's avatar
      Btrfs: don't leak block group on error · e84cc142
      Filipe David Borba Manana authored
      In extent-tree.c:btrfs_write_dirty_block_groups(), if the call to
      write_one_cache_group() failed, we would return without putting
      the block group first.
      Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      e84cc142
    • Filipe David Borba Manana's avatar
      Btrfs: fix sync fs to actually wait for all data to be persisted · 9b199859
      Filipe David Borba Manana authored
      Currently the fs sync function (super.c:btrfs_sync_fs()) doesn't
      wait for delayed work to finish before returning success to the
      caller. This change fixes this, ensuring that there's no data loss
      if a power failure happens right after fs sync returns success to
      the caller and before the next commit happens.
      
      Steps to reproduce the data loss issue:
      
      $ mkfs.btrfs -f /dev/sdb3
      $ mount /dev/sdb3 /mnt/btrfs
      $ perl -e '$d = ("\x41" x 6001); open($f,">","/mnt/btrfs/foobar"); print $f $d; close($f);' && btrfs fi sync /mnt/btrfs
      
      Right after the btrfs fi sync command (a second or 2 for example), power
      off the machine and reboot it. The file will be empty, as it can be verified
      after mounting the filesystem and through btrfs-debug-tree:
      
      $ btrfs-debug-tree /dev/sdb3 | egrep '\(257 INODE_ITEM 0\) itemoff' -B 3 -A 8
              item 3 key (256 DIR_INDEX 2) itemoff 3751 itemsize 36
                      location key (257 INODE_ITEM 0) type FILE
                      namelen 6 datalen 0 name: foobar
              item 4 key (257 INODE_ITEM 0) itemoff 3591 itemsize 160
                      inode generation 7 transid 7 size 0 block group 0 mode 100644 links 1
              item 5 key (257 INODE_REF 256) itemoff 3575 itemsize 16
                      inode ref index 2 namelen 6 name: foobar
      checksum tree key (CSUM_TREE ROOT_ITEM 0)
      leaf 29429760 items 0 free space 3995 generation 7 owner 7
      fs uuid 6192815c-af2a-4b75-b3db-a959ffb6166e
      chunk uuid b529c44b-938c-4d3d-910a-013b4700bcae
      uuid tree key (UUID_TREE ROOT_ITEM 0)
      
      After this patch, the data loss no longer happens after a power failure and
      btrfs-debug-tree shows:
      
      $ btrfs-debug-tree /dev/sdb3 | egrep '\(257 INODE_ITEM 0\) itemoff' -B 3 -A 8
      	item 3 key (256 DIR_INDEX 2) itemoff 3751 itemsize 36
      		location key (257 INODE_ITEM 0) type FILE
      		namelen 6 datalen 0 name: foobar
      	item 4 key (257 INODE_ITEM 0) itemoff 3591 itemsize 160
      		inode generation 6 transid 6 size 6001 block group 0 mode 100644 links 1
      	item 5 key (257 INODE_REF 256) itemoff 3575 itemsize 16
      		inode ref index 2 namelen 6 name: foobar
      	item 6 key (257 EXTENT_DATA 0) itemoff 3522 itemsize 53
      		extent data disk byte 12845056 nr 8192
      		extent data offset 0 nr 8192 ram 8192
      		extent compression 0
      checksum tree key (CSUM_TREE ROOT_ITEM 0)
      Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
      Reviewed-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      9b199859
    • Filipe David Borba Manana's avatar
      Btrfs: fix tracking of orphan inode count · 703c88e0
      Filipe David Borba Manana authored
      In inode.c:btrfs_orphan_add() if we failed to insert the orphan
      item, we would return without decrementing the orphan count that
      we just incremented before attempting the insertion, leaving the
      orphan inode count wrong.
      
      In inode.c:btrfs_orphan_del(), we were decrementing the inode
      orphan count if the bit BTRFS_INODE_ORPHAN_META_RESERVED was set,
      which is logically wrong because it should be decremented if the
      bit BTRFS_INODE_HAS_ORPHAN_ITEM was set - after all we increment
      the count when we set the bit BTRFS_INODE_HAS_ORPHAN_ITEM elsewhere.
      Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      703c88e0
    • Liu Bo's avatar
      Btrfs: export btrfs space shared info to userspace · fe09e16c
      Liu Bo authored
      Similar to ocfs2, btrfs also supports that extents can be shared by
      different inodes, and there are some userspace tools requesting
      for this kind of 'space shared infomation'.[1]
      
      ocfs2 uses flag FIEMAP_EXTENT_SHARED, so does btrfs.
      
      [1]: http://thr3ads.net/ocfs2-devel/2010/09/489052-PATCH-3-3-shared-du-using-fiemap-to-figure-up-the-shared-extents-per-file-and-the-footprint-inReviewed-by: default avatarDavid Sterba <dsterba@suse.cz>
      Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      fe09e16c
    • Filipe David Borba Manana's avatar
      Btrfs: remove path arg from btrfs_truncate_free_space_cache · 74514323
      Filipe David Borba Manana authored
      Not used for anything, and removing it avoids caller's need to
      allocate a path structure.
      Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      74514323
    • Filipe David Borba Manana's avatar
      Btrfs: remove duplicated ino cache's inode lookup · 53645a91
      Filipe David Borba Manana authored
      We're doing a unnecessary extra lookup of the ino cache's
      inode when we already have it (and holding a reference)
      during the process of saving the ino cache contents to disk.
      Therefore remove this extra lookup.
      Signed-off-by: default avatarFilipe David Borba Manana <fdmanana@gmail.com>
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      53645a91
    • Josef Bacik's avatar
      Btrfs: do a full search everytime in btrfs_search_old_slot · d4b4087c
      Josef Bacik authored
      While running some snashot aware defrag tests I noticed I was panicing every
      once and a while in key_search.  This is because of the optimization that says
      if we find a key at slot 0 it will be at slot 0 all the way down the rest of the
      tree.  This isn't the case for btrfs_search_old_slot since it will likely replay
      changes to a buffer if something has changed since we took our sequence number.
      So short circuit this optimization by setting prev_cmp to -1 every time we call
      key_search so we will do our normal binary search.  With this patch I am no
      longer seeing the panics I was seeing before.  Thanks,
      Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: default avatarChris Mason <chris.mason@fusionio.com>
      d4b4087c