1. 06 11月, 2011 1 次提交
    • D
      btrfs: separate superblock items out of fs_info · 6c41761f
      David Sterba 提交于
      fs_info has now ~9kb, more than fits into one page. This will cause
      mount failure when memory is too fragmented. Top space consumers are
      super block structures super_copy and super_for_commit, ~2.8kb each.
      Allocate them dynamically. fs_info will be ~3.5kb. (measured on x86_64)
      
      Add a wrapper for freeing fs_info and all of it's dynamically allocated
      members.
      Signed-off-by: NDavid Sterba <dsterba@suse.cz>
      6c41761f
  2. 21 10月, 2011 6 次提交
    • L
      btrfs: return EINVAL if start > total_bytes in fitrim ioctl · f4c697e6
      Lukas Czerner 提交于
      We should retirn EINVAL if the start is beyond the end of the file
      system in the btrfs_ioctl_fitrim(). Fix that by adding the appropriate
      check for it.
      
      Also in the btrfs_trim_fs() it is possible that len+start might overflow
      if big values are passed. Fix it by decrementing the len so that start+len
      is equal to the file system size in the worst case.
      Signed-off-by: NLukas Czerner <lczerner@redhat.com>
      f4c697e6
    • L
      Btrfs: honor extent thresh during defragmentation · 008873ea
      Li Zefan 提交于
      We won't defrag an extent, if it's bigger than the threshold we
      specified and there's no small extent before it, but actually
      the code doesn't work this way.
      
      There are three bugs:
      
      - When should_defrag_range() decides we should keep on defragmenting
        an extent, last_len is not incremented. (old bug)
      
      - The length that passes to should_defrag_range() is not the length
        we're going to defrag. (new bug)
      
      - We always defrag 256K bytes data, and a big extent can be part of
        this range. (new bug)
      
      For a file with 4 extents:
      
              | 4K | 4K | 256K | 256K |
      
      The result of defrag with (the default) 256K extent thresh should be:
      
              | 264K | 256K |
      
      but with those bugs, we'll get:
      
              | 520K |
      Signed-off-by: NLi Zefan <lizf@cn.fujitsu.com>
      008873ea
    • L
      Btrfs: fix wrong max_to_defrag in btrfs_defrag_file() · 5ca49660
      Li Zefan 提交于
      It's off-by-one, and thus we may skip the last page while defragmenting.
      
      An example case:
      
        # create /mnt/file with 2 4K file extents
        # btrfs fi defrag /mnt/file
        # sync
        # filefrag /mnt/file
        /mnt/file: 2 extents found
      
      So it's not defragmented.
      Signed-off-by: NLi Zefan <lizf@cn.fujitsu.com>
      5ca49660
    • L
      Btrfs: use i_size_read() in btrfs_defrag_file() · 151a31b2
      Li Zefan 提交于
      Don't use inode->i_size directly, since we're not holding i_mutex.
      
      This also fixes another bug, that i_size can change after it's checked
      against 0 and then (i_size - 1) can be negative.
      Signed-off-by: NLi Zefan <lizf@cn.fujitsu.com>
      151a31b2
    • L
      Btrfs: fix defragmentation regression · cbcc8326
      Li Zefan 提交于
      There's an off-by-one bug:
      
        # create a file with lots of 4K file extents
        # btrfs fi defrag /mnt/file
        # sync
        # filefrag -v /mnt/file
        Filesystem type is: 9123683e
        File size of /mnt/file is 1228800 (300 blocks, blocksize 4096)
         ext logical physical expected length flags
           0       0     3372              64
           1      64     3136     3435      1
           2      65     3436     3136     64
           3     129     3201     3499      1
           4     130     3500     3201     64
           5     194     3266     3563      1
           6     195     3564     3266     64
           7     259     3331     3627      1
           8     260     3628     3331     40 eof
      
      After this patch:
      
        ...
        # filefrag -v /mnt/file
        Filesystem type is: 9123683e
        File size of /mnt/file is 1228800 (300 blocks, blocksize 4096)
         ext logical physical expected length flags
           0       0     3372             300 eof
        /mnt/file: 1 extent found
      Signed-off-by: NLi Zefan <lizf@cn.fujitsu.com>
      cbcc8326
    • D
      btrfs: fix memory leak in btrfs_defrag_file · 60ccf82f
      Diego Calleja 提交于
      kmemleak found this:
      unreferenced object 0xffff8801b64af968 (size 512):
        comm "btrfs-cleaner", pid 3317, jiffies 4306810886 (age 903.272s)
        hex dump (first 32 bytes):
          00 82 01 07 00 ea ff ff c0 83 01 07 00 ea ff ff  ................
          80 82 01 07 00 ea ff ff c0 87 01 07 00 ea ff ff  ................
        backtrace:
          [<ffffffff816875cc>] kmemleak_alloc+0x5c/0xc0
          [<ffffffff8114aec3>] kmem_cache_alloc_trace+0x163/0x240
          [<ffffffff8127a290>] btrfs_defrag_file+0xf0/0xb20
          [<ffffffff8125d9a5>] btrfs_run_defrag_inodes+0x165/0x210
          [<ffffffff812479d7>] cleaner_kthread+0x177/0x190
          [<ffffffff81075c7d>] kthread+0x8d/0xa0
          [<ffffffff816af5f4>] kernel_thread_helper+0x4/0x10
          [<ffffffffffffffff>] 0xffffffffffffffff
      
      "pages" is not always freed. Fix it removing the unnecesary additional return.
      Signed-off-by: NDiego Calleja <diegocg@gmail.com>
      60ccf82f
  3. 20 10月, 2011 2 次提交
    • J
      Btrfs: only inherit btrfs specific flags when creating files · e27425d6
      Josef Bacik 提交于
      Xfstests 79 was failing because we were inheriting the S_APPEND flag when we
      weren't supposed to.  There isn't any specific documentation on this so I'm
      taking the test as the standard of how things work, and having S_APPEND set on a
      directory doesn't mean that S_APPEND gets inherited by its children according to
      this test.  So only inherit btrfs specific things.  This will let us set
      compress/nocompress on specific directories and everything in the directories
      will inherit this flag, same with nodatacow.  With this patch test 79 passes.
      Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      e27425d6
    • J
      Btrfs: use the inode's mapping mask for allocating pages · 3b16a4e3
      Josef Bacik 提交于
      Johannes pointed out we were allocating only kernel pages for doing writes,
      which is kind of a big deal if you are on 32bit and have more than a gig of ram.
      So fix our allocations to use the mapping's gfp but still clear __GFP_FS so we
      don't re-enter.  Thanks,
      Reported-by: NJohannes Weiner <jweiner@redhat.com>
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      3b16a4e3
  4. 11 10月, 2011 2 次提交
    • C
      Btrfs: make sure not to defrag extents past i_size · f7f43cc8
      Chris Mason 提交于
      The btrfs file defrag code will loop through the extents and
      force COW on them.  But there is a concurrent truncate in the middle of
      the defrag, it might end up defragging the same range over and over
      again.
      
      The problem is that writepage won't go through and do anything on pages
      past i_size, so the cow won't happen, so the file will appear to still
      be fragmented.  defrag will end up hitting the same extents again and
      again.
      
      In the worst case, the truncate can actually live lock with the defrag
      because the defrag keeps creating new ordered extents which the truncate
      code keeps waiting on.
      
      The fix here is to make defrag check for i_size inside the main loop,
      instead of just once before the looping starts.
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      f7f43cc8
    • L
      Btrfs: fix recursive auto-defrag · 2a0f7f57
      Li Zefan 提交于
      Follow those steps:
      
        # mount -o autodefrag /dev/sda7 /mnt
        # dd if=/dev/urandom of=/mnt/tmp bs=200K count=1
        # sync
        # dd if=/dev/urandom of=/mnt/tmp bs=8K count=1 conv=notrunc
      
      and then it'll go into a loop: writeback -> defrag -> writeback ...
      
      It's because writeback writes [8K, 200K] and then writes [0, 8K].
      
      I tried to make writeback know if the pages are dirtied by defrag,
      but the patch was a bit intrusive. Here I simply set writeback_index
      when we defrag a file.
      Signed-off-by: NLi Zefan <lizf@cn.fujitsu.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      2a0f7f57
  5. 21 9月, 2011 1 次提交
  6. 18 9月, 2011 3 次提交
  7. 11 9月, 2011 2 次提交
  8. 17 8月, 2011 1 次提交
  9. 02 8月, 2011 1 次提交
  10. 28 7月, 2011 2 次提交
    • J
      Btrfs: fix enospc problems with delalloc · 9e0baf60
      Josef Bacik 提交于
      So I had this brilliant idea to use atomic counters for outstanding and reserved
      extents, but this turned out to be a bad idea.  Consider this where we have 1
      outstanding extent and 1 reserved extent
      
      Reserver				Releaser
      					atomic_dec(outstanding) now 0
      atomic_read(outstanding)+1 get 1
      atomic_read(reserved) get 1
      don't actually reserve anything because
      they are the same
      					atomic_cmpxchg(reserved, 1, 0)
      atomic_inc(outstanding)
      atomic_add(0, reserved)
      					free reserved space for 1 extent
      
      Then the reserver now has no actual space reserved for it, and when it goes to
      finish the ordered IO it won't have enough space to do it's allocation and you
      get those lovely warnings.
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      9e0baf60
    • J
      Btrfs: use find_or_create_page instead of grab_cache_page · a94733d0
      Josef Bacik 提交于
      grab_cache_page will use mapping_gfp_mask(), which for all inodes is set to
      GFP_HIGHUSER_MOVABLE.  So instead use find_or_create_page in all cases where we
      need GFP_NOFS so we don't deadlock.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      a94733d0
  11. 21 7月, 2011 1 次提交
  12. 16 6月, 2011 1 次提交
    • J
      Btrfs: protect the pending_snapshots list with trans_lock · 8351583e
      Josef Bacik 提交于
      Currently there is nothing protecting the pending_snapshots list on the
      transaction.  We only hold the directory mutex that we are snapshotting and a
      read lock on the subvol_sem, so we could race with somebody else creating a
      snapshot in a different directory and end up with list corruption.  So protect
      this list with the trans_lock.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      8351583e
  13. 11 6月, 2011 1 次提交
  14. 04 6月, 2011 1 次提交
  15. 27 5月, 2011 1 次提交
  16. 24 5月, 2011 5 次提交
    • X
      Btrfs: using rcu lock in the reader side of devices list · 1f78160c
      Xiao Guangrong 提交于
      fs_devices->devices is only updated on remove and add device paths, so we can
      use rcu to protect it in the reader side
      Signed-off-by: NXiao Guangrong <xiaoguangrong@cn.fujitsu.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      1f78160c
    • H
      btrfs: Ensure the tree search ioctl returns the right number of records · e2156867
      Hugo Mills 提交于
      Btrfs's tree search ioctl has a field to indicate that no more than a
      given number of records should be returned. The ioctl doesn't honour
      this, as the tested value is not incremented until the end of the
      copy_to_sk function. This patch removes an unnecessary local variable,
      and updates the num_found counter as each key is found in the tree.
      Signed-off-by: NHugo Mills <hugo@carfax.org.uk>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      e2156867
    • J
      Btrfs: kill BTRFS_I(inode)->block_group · d82a6f1d
      Josef Bacik 提交于
      Originally this was going to be used as a way to give hints to the allocator,
      but frankly we can get much better hints elsewhere and it's not even used at all
      for anything usefull.  In addition to be completely useless, when we initialize
      an inode we try and find a freeish block group to set as the inodes block group,
      and with a completely full 40gb fs this takes _forever_, so I imagine with say
      1tb fs this is just unbearable.  So just axe the thing altoghether, we don't
      need it and it saves us 8 bytes in the inode and saves us 500 microseconds per
      inode lookup in my testcase.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      d82a6f1d
    • J
      Btrfs: kill trans_mutex · a4abeea4
      Josef Bacik 提交于
      We use trans_mutex for lots of things, here's a basic list
      
      1) To serialize trans_handles joining the currently running transaction
      2) To make sure that no new trans handles are started while we are committing
      3) To protect the dead_roots list and the transaction lists
      
      Really the serializing trans_handles joining is not too hard, and can really get
      bogged down in acquiring a reference to the transaction.  So replace the
      trans_mutex with a trans_lock spinlock and use it to do the following
      
      1) Protect fs_info->running_transaction.  All trans handles have to do is check
      this, and then take a reference of the transaction and keep on going.
      2) Protect the fs_info->trans_list.  This doesn't get used too much, basically
      it just holds the current transactions, which will usually just be the currently
      committing transaction and the currently running transaction at most.
      3) Protect the dead roots list.  This is only ever processed by splicing the
      list so this is relatively simple.
      4) Protect the fs_info->reloc_ctl stuff.  This is very lightweight and was using
      the trans_mutex before, so this is a pretty straightforward change.
      5) Protect fs_info->no_trans_join.  Because we don't hold the trans_lock over
      the entirety of the commit we need to have a way to block new people from
      creating a new transaction while we're doing our work.  So we set no_trans_join
      and in join_transaction we test to see if that is set, and if it is we do a
      wait_on_commit.
      6) Make the transaction use count atomic so we don't need to take locks to
      modify it when we're dropping references.
      7) Add a commit_lock to the transaction to make sure multiple people trying to
      commit the same transaction don't race and commit at the same time.
      8) Make open_ioctl_trans an atomic so we don't have to take any locks for ioctl
      trans.
      
      I have tested this with xfstests, but obviously it is a pretty hairy change so
      lots of testing is greatly appreciated.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      a4abeea4
    • J
      Btrfs: take away the num_items argument from btrfs_join_transaction · 7a7eaa40
      Josef Bacik 提交于
      I keep forgetting that btrfs_join_transaction() just ignores the num_items
      argument, which leads me to sending pointless patches and looking stupid :).  So
      just kill the num_items argument from btrfs_join_transaction and
      btrfs_start_ioctl_transaction, since neither of them use it.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      7a7eaa40
  17. 21 5月, 2011 1 次提交
    • M
      btrfs: implement delayed inode items operation · 16cdcec7
      Miao Xie 提交于
      Changelog V5 -> V6:
      - Fix oom when the memory load is high, by storing the delayed nodes into the
        root's radix tree, and letting btrfs inodes go.
      
      Changelog V4 -> V5:
      - Fix the race on adding the delayed node to the inode, which is spotted by
        Chris Mason.
      - Merge Chris Mason's incremental patch into this patch.
      - Fix deadlock between readdir() and memory fault, which is reported by
        Itaru Kitayama.
      
      Changelog V3 -> V4:
      - Fix nested lock, which is reported by Itaru Kitayama, by updating space cache
        inode in time.
      
      Changelog V2 -> V3:
      - Fix the race between the delayed worker and the task which does delayed items
        balance, which is reported by Tsutomu Itoh.
      - Modify the patch address David Sterba's comment.
      - Fix the bug of the cpu recursion spinlock, reported by Chris Mason
      
      Changelog V1 -> V2:
      - break up the global rb-tree, use a list to manage the delayed nodes,
        which is created for every directory and file, and used to manage the
        delayed directory name index items and the delayed inode item.
      - introduce a worker to deal with the delayed nodes.
      
      Compare with Ext3/4, the performance of file creation and deletion on btrfs
      is very poor. the reason is that btrfs must do a lot of b+ tree insertions,
      such as inode item, directory name item, directory name index and so on.
      
      If we can do some delayed b+ tree insertion or deletion, we can improve the
      performance, so we made this patch which implemented delayed directory name
      index insertion/deletion and delayed inode update.
      
      Implementation:
      - introduce a delayed root object into the filesystem, that use two lists to
        manage the delayed nodes which are created for every file/directory.
        One is used to manage all the delayed nodes that have delayed items. And the
        other is used to manage the delayed nodes which is waiting to be dealt with
        by the work thread.
      - Every delayed node has two rb-tree, one is used to manage the directory name
        index which is going to be inserted into b+ tree, and the other is used to
        manage the directory name index which is going to be deleted from b+ tree.
      - introduce a worker to deal with the delayed operation. This worker is used
        to deal with the works of the delayed directory name index items insertion
        and deletion and the delayed inode update.
        When the delayed items is beyond the lower limit, we create works for some
        delayed nodes and insert them into the work queue of the worker, and then
        go back.
        When the delayed items is beyond the upper bound, we create works for all
        the delayed nodes that haven't been dealt with, and insert them into the work
        queue of the worker, and then wait for that the untreated items is below some
        threshold value.
      - When we want to insert a directory name index into b+ tree, we just add the
        information into the delayed inserting rb-tree.
        And then we check the number of the delayed items and do delayed items
        balance. (The balance policy is above.)
      - When we want to delete a directory name index from the b+ tree, we search it
        in the inserting rb-tree at first. If we look it up, just drop it. If not,
        add the key of it into the delayed deleting rb-tree.
        Similar to the delayed inserting rb-tree, we also check the number of the
        delayed items and do delayed items balance.
        (The same to inserting manipulation)
      - When we want to update the metadata of some inode, we cached the data of the
        inode into the delayed node. the worker will flush it into the b+ tree after
        dealing with the delayed insertion and deletion.
      - We will move the delayed node to the tail of the list after we access the
        delayed node, By this way, we can cache more delayed items and merge more
        inode updates.
      - If we want to commit transaction, we will deal with all the delayed node.
      - the delayed node will be freed when we free the btrfs inode.
      - Before we log the inode items, we commit all the directory name index items
        and the delayed inode update.
      
      I did a quick test by the benchmark tool[1] and found we can improve the
      performance of file creation by ~15%, and file deletion by ~20%.
      
      Before applying this patch:
      Create files:
              Total files: 50000
              Total time: 1.096108
              Average time: 0.000022
      Delete files:
              Total files: 50000
              Total time: 1.510403
              Average time: 0.000030
      
      After applying this patch:
      Create files:
              Total files: 50000
              Total time: 0.932899
              Average time: 0.000019
      Delete files:
              Total files: 50000
              Total time: 1.215732
              Average time: 0.000024
      
      [1] http://marc.info/?l=linux-btrfs&m=128212635122920&q=p3
      
      Many thanks for Kitayama-san's help!
      Signed-off-by: NMiao Xie <miaox@cn.fujitsu.com>
      Reviewed-by: NDavid Sterba <dave@jikos.cz>
      Tested-by: NTsutomu Itoh <t-itoh@jp.fujitsu.com>
      Tested-by: NItaru Kitayama <kitayama@cl.bb4u.ne.jp>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      16cdcec7
  18. 15 5月, 2011 3 次提交
  19. 12 5月, 2011 2 次提交
  20. 02 5月, 2011 1 次提交
  21. 25 4月, 2011 2 次提交
    • L
      Btrfs: Always use 64bit inode number · 33345d01
      Li Zefan 提交于
      There's a potential problem in 32bit system when we exhaust 32bit inode
      numbers and start to allocate big inode numbers, because btrfs uses
      inode->i_ino in many places.
      
      So here we always use BTRFS_I(inode)->location.objectid, which is an
      u64 variable.
      
      There are 2 exceptions that BTRFS_I(inode)->location.objectid !=
      inode->i_ino: the btree inode (0 vs 1) and empty subvol dirs (256 vs 2),
      and inode->i_ino will be used in those cases.
      
      Another reason to make this change is I'm going to use a special inode
      to save free ino cache, and the inode number must be > (u64)-256.
      Signed-off-by: NLi Zefan <lizf@cn.fujitsu.com>
      33345d01
    • L
      Btrfs: Cache free inode numbers in memory · 581bb050
      Li Zefan 提交于
      Currently btrfs stores the highest objectid of the fs tree, and it always
      returns (highest+1) inode number when we create a file, so inode numbers
      won't be reclaimed when we delete files, so we'll run out of inode numbers
      as we keep create/delete files in 32bits machines.
      
      This fixes it, and it works similarly to how we cache free space in block
      cgroups.
      
      We start a kernel thread to read the file tree. By scanning inode items,
      we know which chunks of inode numbers are free, and we cache them in
      an rb-tree.
      
      Because we are searching the commit root, we have to carefully handle the
      cross-transaction case.
      
      The rb-tree is a hybrid extent+bitmap tree, so if we have too many small
      chunks of inode numbers, we'll use bitmaps. Initially we allow 16K ram
      of extents, and a bitmap will be used if we exceed this threshold. The
      extents threshold is adjusted in runtime.
      Signed-off-by: NLi Zefan <lizf@cn.fujitsu.com>
      581bb050