1. 08 Apr, 2011 7 commits
    • Josef Bacik's avatar
      Btrfs: reuse the extent_map we found when calling btrfs_get_extent · 16d299ac
      Josef Bacik authored
      In btrfs_get_block_direct we call btrfs_get_extent to lookup the extent for the
      range that we are looking for.  If we don't find an extent, btrfs_get_extent
      will insert a extent_map for that area and mark it as a hole.  So it does the
      job of allocating a new extent map and inserting it into the io tree.  But if
      we're creating a new extent we free it up and redo all of that work.  So instead
      pass the em to btrfs_new_extent_direct(), and if it will work just allocate the
      disk space and set it up properly and bypass the freeing/allocating of a new
      extent map and the expensive operation of inserting the thing into the io_tree.
      Thanks,
      Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
      16d299ac
    • Josef Bacik's avatar
      Btrfs: do not use async submit for small DIO io's · 1ae39938
      Josef Bacik authored
      When looking at our DIO performance Chris said that for small IO's doing the
      async submit stuff tends to be more overhead than it's worth.  With this on top
      of my other fixes I get about a 17-20% speedup doing a sequential dd with 4k
      IO's.  Basically if we don't have to split the bio for the map length it's small
      enough to be directly submitted, otherwise go back to the async submit.  Thanks,
      Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
      1ae39938
    • Josef Bacik's avatar
      Btrfs: don't split dio bios if we don't have to · 02f57c7a
      Josef Bacik authored
      We have been unconditionally allocating a new bio and re-adding all pages from
      our original bio to the new bio.  This is needed if our original bio is larger
      than our stripe size, but if it is smaller than the stripe size then there is no
      need to do this.  So check the map length and if we are under that then go ahead
      and submit the original bio.  Thanks,
      Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
      02f57c7a
    • Josef Bacik's avatar
      Btrfs: do not call btrfs_update_inode in endio if nothing changed · 1ef30be1
      Josef Bacik authored
      In the DIO code we often don't update the i_disk_size because the i_size isn't
      updated until after the DIO is completed, so basically we are allocating a path,
      doing a search, and updating the inode item for no reason since nothing changed.
      btrfs_ordered_update_i_size will return 1 if it didn't update i_disk_size, so
      only run btrfs_update_inode if btrfs_ordered_update_i_size returns 0.  Thanks,
      Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
      1ef30be1
    • Josef Bacik's avatar
      Btrfs: map the inode item when doing fill_inode_item · 12ddb96c
      Josef Bacik authored
      Instead of calling kmap_atomic for every thing we set in the inode item, map the
      entire inode item at the start and unmap it at the end.  This makes a sequential
      dd of 400mb O_DIRECT something like 1% faster.  Thanks,
      Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
      12ddb96c
    • Josef Bacik's avatar
      Btrfs: only retry transaction reservation once · 06d5a589
      Josef Bacik authored
      I saw a lockup where we kept getting into this start transaction->commit
      transaction loop because of enospce.  The fact is if we fail to make our
      reservation, we've tried _everything_ several times, so we only need to try and
      commit the transaction once, and if that doesn't work then we really are out of
      space and need to just exit.  Thanks,
      Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
      06d5a589
    • Josef Bacik's avatar
      Btrfs: deal with the case that we run out of space in the cache · be1a12a0
      Josef Bacik authored
      Currently we don't handle running out of space in the cache, so to fix this we
      keep track of how far in the cache we are.  Then we only dirty the pages if we
      successfully modify all of them, otherwise if we have an error or run out of
      space we can just drop them and not worry about the vm writing them out.
      Thanks,
      
      Tested-by Johannes Hirte <johannes.hirte@fem.tu-ilmenau.de>
      Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
      be1a12a0
  2. 05 Apr, 2011 10 commits
  3. 28 Mar, 2011 23 commits
    • Chris Mason's avatar
      Btrfs: fix __btrfs_map_block on 32 bit machines · d9d04879
      Chris Mason authored
      Recent changes for discard support didn't compile,
      this fixes them not to try and % 64 bit numbers.
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      d9d04879
    • Miao Xie's avatar
      btrfs: fix possible deadlock by clearing __GFP_FS flag · 1561deda
      Miao Xie authored
      Using the GFP_HIGHUSER_MOVABLE flag to allocate the metadata's page may cause
      deadlock.
        Task1
        open()
          ...
          btrfs_search_slot()
            ...
            btrfs_cow_block()
      	...
      	alloc_page()
      	  wait for reclaiming
      					shrink_slab()
      					  ...
      					  shrink_icache_memory()
      					    ...
      					    btrfs_evict_inode()
      					      ...
      					      btrfs_search_slot()
      
      If the path is locked by task1, the deadlock happens.
      
      So the btree's page cache is different with the file's page cache, it can not
      allocate pages by GFP_HIGHUSER_MOVABLE flag, we must clear __GFP_FS flag in
      GFP_HIGHUSER_MOVABLE flag.
      Reported-by: default avatarItaru Kitayama <kitayama@cl.bb4u.ne.jp>
      Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      1561deda
    • Al Viro's avatar
      c055e99e
    • Al Viro's avatar
      btrfs: don't mess with i_nlink of unlocked inode in rename() · 92986796
      Al Viro authored
      old_inode is not locked; it's not safe to play with its link
      count.  Instead of bumping it and calling btrfs_unlink_inode(),
      add a variant of the latter that does not do btrfs_drop_nlink()/
      btrfs_update_inode(), call it instead of btrfs_inc_nlink()/
      btrfs_unlink_inode() and do btrfs_update_inode() ourselves.
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      92986796
    • Tsutomu Itoh's avatar
      Btrfs: check return value of btrfs_alloc_path() · c2db1073
      Tsutomu Itoh authored
      Adding the check on the return value of btrfs_alloc_path() to several places.
      And, some of callers are modified by this change.
      Signed-off-by: default avatarTsutomu Itoh <t-itoh@jp.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      c2db1073
    • liubo's avatar
      Btrfs: fix OOPS of empty filesystem after balance · c59021f8
      liubo authored
      btrfs will remove unused block groups after balance.
      When a empty filesystem is balanced, the block group with tag "DATA" may be
      dropped, and after umount and mount again, it will not find "DATA" space_info
      and lead to OOPS.
      So we initial the necessary space_infos(DATA, SYSTEM, METADATA) to avoid OOPS.
      Reported-by: default avatarDaniel J Blueman <daniel.blueman@gmail.com>
      Signed-off-by: default avatarLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      c59021f8
    • liubo's avatar
      Btrfs: fix memory leak of empty filesystem after balance · 9f7c43c9
      liubo authored
      After Josef's patch(commit 3c14874a),
      btrfs will exclude super bytes when reading block groups(by marking a extent
      state UPTODATE).  However, these bytes do not get freed while balance remove
      unused block groups, and we won't process those removed ones any more, when
      we do umount and unload the btrfs module,  btrfs hits a memory leak.
      
      This patch add the missing free operation.
      
      Reproduce steps:
      $ mkfs.btrfs disk
      $ mount disk /mnt/btrfs -o loop
      $ btrfs filesystem balance /mnt/btrfs
      $ umount /mnt/btrfs
      $ rmmod btrfs
      Signed-off-by: default avatarLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      9f7c43c9
    • liubo's avatar
      Btrfs: fix return value of setflags ioctl · 2d4e6f6a
      liubo authored
      setflags ioctl should return error when any checks fail.
      Signed-off-by: default avatarLiu Bo <liubo2009@cn.fujitsu.com>
      Reviewed-by: default avatarDavid Sterba <dsterba@suse.cz>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      2d4e6f6a
    • Yoshinori Sano's avatar
      Btrfs: fix uncheck memory allocations · dac97e51
      Yoshinori Sano authored
      To make Btrfs code more robust, several return value checks where memory
      allocation can fail are introduced. I use BUG_ON where I don't know how
      to handle the error properly, which increases the number of using the
      notorious BUG_ON, though.
      Signed-off-by: default avatarYoshinori Sano <yoshinori.sano@gmail.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      dac97e51
    • liubo's avatar
      btrfs: make inode ref log recovery faster · c622ae60
      liubo authored
      When we recover from crash via write-ahead log tree and process
      the inode refs, for each btrfs_inode_ref item, we will
      1) check if we already have a perfect match in fs/file tree, if
         we have, then we're done.
      2) search the corresponding back reference in fs/file tree, and
         check all the names in this back reference to see if they are
         also in the log to avoid conflict corners.
      3) recover the logged inode refs to fs/file tree.
      
      In current btrfs, however,
      - for 2)'s check, once is enough, since the checked back reference
        will remain unchanged after processing all the inode refs belonged
        to the key.
      - it has no need to do another 1) between 2) and 3).
      
      I've made a small test to show how it improves,
      
      $dd if=/dev/zero of=foobar bs=4K count=1
      $sync
      $make 100 hard links continuously, like ln foobar link_i
      $fsync foobar
      $echo b > /proc/sysrq-trigger
      after reboot
      $time mount DEV PATH
      
      without patch:
      real    0m0.285s
      user    0m0.001s
      sys     0m0.009s
      
      with patch:
      real    0m0.123s
      user    0m0.000s
      sys     0m0.010s
      
      Changelog v1->v2:
      - fix double free - pointed by David Sterba
      Changelog v2->v3:
      - adjust free order
      Signed-off-by: default avatarLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      c622ae60
    • Li Dongyang's avatar
      Btrfs: add btrfs_trim_fs() to handle FITRIM · f7039b1d
      Li Dongyang authored
      We take an free extent out from allocator, trim it, then put it back,
      but before we trim the block group, we should make sure the block group is
      cached, so plus a little change to make cache_block_group() run without a
      transaction.
      Signed-off-by: default avatarLi Dongyang <lidongyang@novell.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      f7039b1d
    • Li Dongyang's avatar
      Btrfs: adjust btrfs_discard_extent() return errors and trimmed bytes · 5378e607
      Li Dongyang authored
      Callers of btrfs_discard_extent() should check if we are mounted with -o discard,
      as we want to make fitrim to work even the fs is not mounted with -o discard.
      Also we should use REQ_DISCARD to map the free extent to get a full mapping,
      last we only return errors if
      1. the error is not a EOPNOTSUPP
      2. no device supports discard
      Signed-off-by: default avatarLi Dongyang <lidongyang@novell.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      5378e607
    • Li Dongyang's avatar
      Btrfs: make btrfs_map_block() return entire free extent for each device of RAID0/1/10/DUP · fce3bb9a
      Li Dongyang authored
      btrfs_map_block() will only return a single stripe length, but we want the
      full extent be mapped to each disk when we are trimming the extent,
      so we add length to btrfs_bio_stripe and fill it if we are mapping for REQ_DISCARD.
      Signed-off-by: default avatarLi Dongyang <lidongyang@novell.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      fce3bb9a
    • Li Dongyang's avatar
      Btrfs: make update_reserved_bytes() public · b4d00d56
      Li Dongyang authored
      Make the function public as we should update the reserved extents calculations
      after taking out an extent for trimming.
      Signed-off-by: default avatarLi Dongyang <lidongyang@novell.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      b4d00d56
    • Mark Fasheh's avatar
      btrfs: return EXDEV when linking from different subvolumes · 3ab3564f
      Mark Fasheh authored
      btrfs_link returns EPERM if a cross-subvolume link is attempted.
      
      However, in this case I believe EXDEV to be the more appropriate value.
      >From the link(2) man page:
      
      EXDEV  oldpath and newpath are not on the same mounted file system.  (Linux
             permits a file system to be mounted at multiple points, but link()
             does not work across different mount points, even if the same file
             system is mounted on both.)
      
      This matters because an application may have different behaviors based on
      return codes.
      Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      3ab3564f
    • Liu Bo's avatar
      Btrfs: Per file/directory controls for COW and compression · 75e7cb7f
      Liu Bo authored
      Data compression and data cow are controlled across the entire FS by mount
      options right now.  ioctls are needed to set this on a per file or per
      directory basis.  This has been proposed previously, but VFS developers
      wanted us to use generic ioctls rather than btrfs-specific ones.
      
      According to Chris's comment, there should be just one true compression
      method(probably LZO) stored in the super.  However, before this, we would
      wait for that one method is stable enough to be adopted into the super.
      So I list it as a long term goal, and just store it in ram today.
      
      After applying this patch, we can use the generic "FS_IOC_SETFLAGS" ioctl to
      control file and directory's datacow and compression attribute.
      
      NOTE:
       - The compression type is selected by such rules:
         If we mount btrfs with compress options, ie, zlib/lzo, the type is it.
         Otherwise, we'll use the default compress type (zlib today).
      
      v1->v2:
      - rebase to the latest btrfs.
      v2->v3:
      - fix a problem, i.e. when a file is set NOCOW via mount option, then this NOCOW
        will be screwed by inheritance from parent directory.
      Signed-off-by: default avatarLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      75e7cb7f
    • liubo's avatar
      Btrfs: add datacow flag in inode flag · 32471f6e
      liubo authored
      For datacow control, the corresponding inode flags are needed.
      This is for btrfs use.
      
      v1->v2:
      Change FS_COW_FL to another bit due to conflict with the upstream e2fsprogs
      Signed-off-by: default avatarLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      32471f6e
    • Miao Xie's avatar
      btrfs: use GFP_NOFS instead of GFP_KERNEL · fc0e4a31
      Miao Xie authored
      In the filesystem context, we must allocate memory by GFP_NOFS,
      or we may start another filesystem operation and make kswap thread hang up.
      Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      fc0e4a31
    • Tsutomu Itoh's avatar
      Btrfs: check return value of read_tree_block() · 97d9a8a4
      Tsutomu Itoh authored
      This patch is checking return value of read_tree_block(),
      and if it is NULL, error processing.
      Signed-off-by: default avatarTsutomu Itoh <t-itoh@jp.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      97d9a8a4
    • David Sterba's avatar
      btrfs: properly access unaligned checksum buffer · 7e75bf3f
      David Sterba authored
      On Fri, Mar 18, 2011 at 11:56:53AM -0400, Chris Mason wrote:
      > Thanks for fielding this one.  Does put_unaligned_le32 optimize away on
      > platforms with efficient access?  It would be great if we didn't need
      > the #ifdef.
      
      (quicktest: assembly output is same for put_unaligned_le32 and direct
      assignment on my x86_64)
      I was originally following examples in
      Documentation/unaligned-memory-access.txt. From other code it seems to me that
      the define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is intended for larger
      portions of code. Macros/wrappers for {put,get}_unaligned* are chosen via
      arch/<arch>/include/asm/unaligned.h accordingly, therefore it's safe to use
      put_unaligned_le32 without the ifdef.
      
      dave
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      7e75bf3f
    • Tsutomu Itoh's avatar
      Btrfs: cleanup some BUG_ON() · db5b493a
      Tsutomu Itoh authored
      This patch changes some BUG_ON() to the error return.
      (but, most callers still use BUG_ON())
      Signed-off-by: default avatarTsutomu Itoh <t-itoh@jp.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      db5b493a
    • liubo's avatar
      Btrfs: add initial tracepoint support for btrfs · 1abe9b8a
      liubo authored
      Tracepoints can provide insight into why btrfs hits bugs and be greatly
      helpful for debugging, e.g
                    dd-7822  [000]  2121.641088: btrfs_inode_request: root = 5(FS_TREE), gen = 4, ino = 256, blocks = 8, disk_i_size = 0, last_trans = 8, logged_trans = 0
                    dd-7822  [000]  2121.641100: btrfs_inode_new: root = 5(FS_TREE), gen = 8, ino = 257, blocks = 0, disk_i_size = 0, last_trans = 0, logged_trans = 0
       btrfs-transacti-7804  [001]  2146.935420: btrfs_cow_block: root = 2(EXTENT_TREE), refs = 2, orig_buf = 29368320 (orig_level = 0), cow_buf = 29388800 (cow_level = 0)
       btrfs-transacti-7804  [001]  2146.935473: btrfs_cow_block: root = 1(ROOT_TREE), refs = 2, orig_buf = 29364224 (orig_level = 0), cow_buf = 29392896 (cow_level = 0)
       btrfs-transacti-7804  [001]  2146.972221: btrfs_transaction_commit: root = 1(ROOT_TREE), gen = 8
         flush-btrfs-2-7821  [001]  2155.824210: btrfs_chunk_alloc: root = 3(CHUNK_TREE), offset = 1103101952, size = 1073741824, num_stripes = 1, sub_stripes = 0, type = DATA
         flush-btrfs-2-7821  [001]  2155.824241: btrfs_cow_block: root = 2(EXTENT_TREE), refs = 2, orig_buf = 29388800 (orig_level = 0), cow_buf = 29396992 (cow_level = 0)
         flush-btrfs-2-7821  [001]  2155.824255: btrfs_cow_block: root = 4(DEV_TREE), refs = 2, orig_buf = 29372416 (orig_level = 0), cow_buf = 29401088 (cow_level = 0)
         flush-btrfs-2-7821  [000]  2155.824329: btrfs_cow_block: root = 3(CHUNK_TREE), refs = 2, orig_buf = 20971520 (orig_level = 0), cow_buf = 20975616 (cow_level = 0)
       btrfs-endio-wri-7800  [001]  2155.898019: btrfs_cow_block: root = 5(FS_TREE), refs = 2, orig_buf = 29384704 (orig_level = 0), cow_buf = 29405184 (cow_level = 0)
       btrfs-endio-wri-7800  [001]  2155.898043: btrfs_cow_block: root = 7(CSUM_TREE), refs = 2, orig_buf = 29376512 (orig_level = 0), cow_buf = 29409280 (cow_level = 0)
      
      Here is what I have added:
      
      1) ordere_extent:
              btrfs_ordered_extent_add
              btrfs_ordered_extent_remove
              btrfs_ordered_extent_start
              btrfs_ordered_extent_put
      
      These provide critical information to understand how ordered_extents are
      updated.
      
      2) extent_map:
              btrfs_get_extent
      
      extent_map is used in both read and write cases, and it is useful for tracking
      how btrfs specific IO is running.
      
      3) writepage:
              __extent_writepage
              btrfs_writepage_end_io_hook
      
      Pages are cirtical resourses and produce a lot of corner cases during writeback,
      so it is valuable to know how page is written to disk.
      
      4) inode:
              btrfs_inode_new
              btrfs_inode_request
              btrfs_inode_evict
      
      These can show where and when a inode is created, when a inode is evicted.
      
      5) sync:
              btrfs_sync_file
              btrfs_sync_fs
      
      These show sync arguments.
      
      6) transaction:
              btrfs_transaction_commit
      
      In transaction based filesystem, it will be useful to know the generation and
      who does commit.
      
      7) back reference and cow:
      	btrfs_delayed_tree_ref
      	btrfs_delayed_data_ref
      	btrfs_delayed_ref_head
      	btrfs_cow_block
      
      Btrfs natively supports back references, these tracepoints are helpful on
      understanding btrfs's COW mechanism.
      
      8) chunk:
      	btrfs_chunk_alloc
      	btrfs_chunk_free
      
      Chunk is a link between physical offset and logical offset, and stands for space
      infomation in btrfs, and these are helpful on tracing space things.
      
      9) reserved_extent:
      	btrfs_reserved_extent_alloc
      	btrfs_reserved_extent_free
      
      These can show how btrfs uses its space.
      Signed-off-by: default avatarLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      1abe9b8a
    • Chris Mason's avatar
      Btrfs: use RCU instead of a spinlock to protect the root node · 240f62c8
      Chris Mason authored
      The pointer to the extent buffer for the root of each tree
      is protected by a spinlock so that we can safely read the pointer
      and take a reference on the extent buffer.
      
      But now that the extent buffers are freed via RCU, we can safely
      use rcu_read_lock instead.
      Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
      240f62c8