1. 29 3月, 2012 2 次提交
    • L
      Btrfs: fix the mismatch of page->mapping · 1f12bd06
      Liu Bo 提交于
      commit 600a45e1
      (Btrfs: fix deadlock on page lock when doing auto-defragment)
      fixes the deadlock on page, but it also introduces another bug.
      
      A page may have been truncated after unlock & lock.
      So we need to find it again to get the right one.
      
      And since we've held i_mutex lock, inode size remains unchanged and
      we can drop isize overflow checks.
      Signed-off-by: NLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: NMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      1f12bd06
    • L
      Btrfs: fix race between direct io and autodefrag · ecb8bea8
      Liu Bo 提交于
      The bug is from running xfstests 209 with autodefrag.
      
      The race is as follows:
             t1                       t2(autodefrag)
         direct IO
           invalidate pagecache
           dio(old data)             add_inode_defrag
           invalidate pagecache
         endio
      
         direct IO
           invalidate pagecache
                                      run_defrag
                                        readpage(old data)
                                        set page dirty (old data)
           dio(new data, rewrite)
           invalidate pagecache (*)
           endio
      
      t2(autodefrag) will get old data into pagecache via readpage and set
      pagecache dirty.  Meanwhile, invalidate pagecache(*) will fail due to
      dirty flags in pages.  So the old data may be flushed into disk by
      flush thread, which will lead to data loss.
      
      And so does the case of user defragment progs.
      
      The patch fixes this race by holding i_mutex when we readpage and set page dirty.
      Signed-off-by: NLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: NMiao Xie <miaox@cn.fujitsu.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      ecb8bea8
  2. 27 3月, 2012 1 次提交
    • J
      Btrfs: fix regression in scrub path resolving · 7a3ae2f8
      Jan Schmidt 提交于
      In commit 4692cf58 we introduced new backref walking code for btrfs. This
      assumes we're searching live roots, which requires a transaction context.
      While scrubbing, however, we must not join a transaction because this could
      deadlock with the commit path. Additionally, what scrub really wants to do
      is resolving a logical address in the commit root it's currently checking.
      
      This patch adds support for logical to path resolving on commit roots and
      makes scrub use that.
      Signed-off-by: NJan Schmidt <list.btrfs@jan-o-sch.net>
      7a3ae2f8
  3. 22 3月, 2012 3 次提交
  4. 23 2月, 2012 1 次提交
  5. 17 2月, 2012 1 次提交
    • M
      Btrfs: fix deadlock on page lock when doing auto-defragment · 600a45e1
      Miao Xie 提交于
      When I ran xfstests circularly on a auto-defragment btrfs, the deadlock
      happened.
      
      Steps to reproduce:
      [tty0]
       # export MOUNT_OPTIONS="-o autodefrag"
       # export TEST_DEV=<partition1>
       # export TEST_DIR=<mountpoint1>
       # export SCRATCH_DEV=<partition2>
       # export SCRATCH_MNT=<mountpoint2>
       # while [ 1 ]
       > do
       > ./check 091 127 263
       > sleep 1
       > done
      [tty1]
       # while [ 1 ]
       > do
       > echo 3 > /proc/sys/vm/drop_caches
       > done
      
      Several hours later, the test processes will hang on, and the deadlock will
      happen on page lock.
      
      The reason is that:
        Auto defrag task		Flush thread			Test task
      				btrfs_writepages()
      				  add ordered extent
      				  (including page 1, 2)
      				  set page 1 writeback
      				  set page 2 writeback
      				endio_fn()
      				  end page 2 writeback
      								release page 2
      lock page 1
      alloc and lock page 2
      page 2 is not uptodate
        btrfs_readpage()
          start ordered extent()
          btrfs_writepages()
            try  to lock page 1
      
      so deadlock happens.
      
      Fix this bug by unlocking the page which is in writeback, and re-locking it
      after the writeback end.
      Signed-off-by: NMiao Xie <miax@cn.fujitsu.com>
      600a45e1
  6. 27 1月, 2012 1 次提交
  7. 17 1月, 2012 7 次提交
  8. 11 1月, 2012 2 次提交
  9. 09 1月, 2012 1 次提交
  10. 05 1月, 2012 1 次提交
    • J
      Btrfs: new backref walking code · 4692cf58
      Jan Schmidt 提交于
      The old backref iteration code could only safely be used on commit roots.
      Besides this limitation, it had bugs in finding the roots for these
      references. This commit replaces large parts of it by btrfs_find_all_roots()
      which a) really finds all roots and the correct roots, b) works correctly
      under heavy file system load, c) considers delayed refs.
      Signed-off-by: NJan Schmidt <list.btrfs@jan-o-sch.net>
      4692cf58
  11. 04 1月, 2012 2 次提交
  12. 22 12月, 2011 1 次提交
    • A
      Btrfs: mark delayed refs as for cow · 66d7e7f0
      Arne Jansen 提交于
      Add a for_cow parameter to add_delayed_*_ref and pass the appropriate value
      from every call site. The for_cow parameter will later on be used to
      determine if a ref will change anything with respect to qgroups.
      
      Delayed refs coming from relocation are always counted as for_cow, as they
      don't change subvol quota.
      
      Also pass in the fs_info for later use.
      
      btrfs_find_all_roots() will use this as an optimization, as changes that are
      for_cow will not change anything with respect to which root points to a
      certain leaf. Thus, we don't need to add the current sequence number to
      those delayed refs.
      Signed-off-by: NArne Jansen <sensille@gmx.net>
      Signed-off-by: NJan Schmidt <list.btrfs@jan-o-sch.net>
      66d7e7f0
  13. 16 12月, 2011 1 次提交
    • J
      Btrfs: fix how we do delalloc reservations and how we free reservations on error · 660d3f6c
      Josef Bacik 提交于
      Running xfstests 269 with some tracing my scripts kept spitting out errors about
      releasing bytes that we didn't actually have reserved.  This took me down a huge
      rabbit hole and it turns out the way we deal with reserved_extents is wrong,
      we need to only be setting it if the reservation succeeds, otherwise the free()
      method will come in and unreserve space that isn't actually reserved yet, which
      can lead to other warnings and such.  The math was all working out right in the
      end, but it caused all sorts of other issues in addition to making my scripts
      yell and scream and generally make it impossible for me to track down the
      original issue I was looking for.  The other problem is with our error handling
      in the reservation code.  There are two cases that we need to deal with
      
      1) We raced with free.  In this case free won't free anything because csum_bytes
      is modified before we dro the lock in our reservation path, so free rightly
      doesn't release any space because the reservation code may be depending on that
      reservation.  However if we fail, we need the reservation side to do the free at
      that point since that space is no longer in use.  So as it stands the code was
      doing this fine and it worked out, except in case #2
      
      2) We don't race with free.  Nobody comes in and changes anything, and our
      reservation fails.  In this case we didn't reserve anything anyway and we just
      need to clean up csum_bytes but not free anything.  So we keep track of
      csum_bytes before we drop the lock and if it hasn't changed we know we can just
      decrement csum_bytes and carry on.
      
      Because of the case where we can race with free()'s since we have to drop our
      spin_lock to do the reservation, I'm going to serialize all reservations with
      the i_mutex.  We already get this for free in the heavy use paths, truncate and
      file write all hold the i_mutex, just needed to add it to page_mkwrite and
      various ioctl/balance things.  With this patch my space leak scripts no longer
      scream bloody murder.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      660d3f6c
  14. 15 12月, 2011 1 次提交
    • L
      Btrfs: fix ctime update of on-disk inode · 306424cc
      Li Zefan 提交于
      To reproduce the bug:
      
          # touch /mnt/tmp
          # stat /mnt/tmp | grep Change
          Change: 2011-12-09 09:32:23.412105981 +0800
          # chattr +i /mnt/tmp
          # stat /mnt/tmp | grep Change
          Change: 2011-12-09 09:32:43.198105295 +0800
          # umount /mnt
          # mount /dev/loop1 /mnt
          # stat /mnt/tmp | grep Change
          Change: 2011-12-09 09:32:23.412105981 +0800
      
      We should update ctime of in-memory inode before calling
      btrfs_update_inode().
      Signed-off-by: NLi Zefan <lizf@cn.fujitsu.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      306424cc
  15. 01 12月, 2011 1 次提交
  16. 20 11月, 2011 2 次提交
    • A
      Btrfs: prefix resize related printks with btrfs: · 5bb14682
      Arnd Hannemann 提交于
      For the user it is confusing to find something like:
      [10197.627710] new size for /dev/mapper/vg0-usr_share is 3221225472
      in kernel log, because it doesn't point directly to btrfs.
      
      This patch prefixes those messages with "btrfs:" like other btrfs
      related printks.
      Signed-off-by: NArnd Hannemann <arnd@arndnet.de>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      5bb14682
    • J
      btrfs: Fix up 32/64-bit compatibility for new ioctls · 745c4d8e
      Jeff Mahoney 提交于
       This patch casts to unsigned long before casting to a pointer and fixes
       the following warnings:
      fs/btrfs/extent_io.c:2289:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
      fs/btrfs/ioctl.c:2933:37: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
      fs/btrfs/ioctl.c:2937:21: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
      fs/btrfs/ioctl.c:3020:21: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
      fs/btrfs/scrub.c:275:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
      fs/btrfs/backref.c:686:27: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
      Signed-off-by: NJeff Mahoney <jeffm@suse.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      745c4d8e
  17. 06 11月, 2011 2 次提交
  18. 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
  19. 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
  20. 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