1. 29 8月, 2012 4 次提交
    • J
      Btrfs: fix enospc problems when deleting a subvol · 5a24e84c
      Josef Bacik 提交于
      Subvol delete is a special kind of awful where we use the global reserve to
      cover the ENOSPC requirements.  The problem is once we're done removing
      everything we do a btrfs_update_inode(), which by default will try to do the
      delayed update stuff which will use it's own reserve.  There will be no
      space in this reserve and we'll return ENOSPC.  So instead use
      btrfs_update_inode_fallback() which will just fallback to updating the inode
      item in the case of enospc.  This is fine because the global reserve covers
      the space requirements for this.  With this patch I can now delete a subvol
      on a problem image Dave Sterba sent me.  Thanks,
      Reported-by: NDavid Sterba <dave@jikos.cz>
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      Signed-off-by: NChris Mason <chris.mason@fusionio.com>
      5a24e84c
    • J
      Btrfs: barrier before waitqueue_active · 66657b31
      Josef Bacik 提交于
      We need a barrir before calling waitqueue_active otherwise we will miss
      wakeups.  So in places that do atomic_dec(); then atomic_read() use
      atomic_dec_return() which imply a memory barrier (see memory-barriers.txt)
      and then add an explicit memory barrier everywhere else that need them.
      Thanks,
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      66657b31
    • J
      Btrfs: don't allocate a seperate csums array for direct reads · c329861d
      Josef Bacik 提交于
      We've been allocating a big array for csums instead of storing them in the
      io_tree like we do for buffered reads because previously we were locking the
      entire range, so we didn't have an extent state for each sector of the
      range.  But now that we do the range locking as we map the buffers we can
      limit the mapping lenght to sectorsize and use the private part of the
      io_tree for our csums.  This allows us to avoid an extra memory allocation
      for direct reads which could incur latency.  Thanks,
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      c329861d
    • J
      Btrfs: lock extents as we map them in DIO · eb838e73
      Josef Bacik 提交于
      A deadlock in xfstests 113 was uncovered by commit
      
      d187663e
      
      This is because we would not return EIOCBQUEUED for short AIO reads, instead
      we'd wait for the DIO to complete and then return the amount of data we
      transferred, which would allow our stuff to unlock the remaning amount.  But
      with this change this no longer happens, so if we have a short AIO read (for
      example if we try to read past EOF), we could leave the section from EOF to
      the end of where we tried to read locked.  Fixing this is tricky since there
      is no clear way to know exactly how much data DIO truly submitted for IO, so
      to make this less hard on ourselves and less combersome we need to lock the
      extents as we try to map them, and then we unlock any areas we didn't
      actually map.  This makes us completely safe from deadlocks and reliance on
      a particular behavior of the DIO code.  This also lays the groundwork for
      allowing us to use the normal csum storage method for reads which means we
      can remove an allocation.  Thanks,
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      eb838e73
  2. 26 7月, 2012 1 次提交
    • A
      Btrfs: introduce subvol uuids and times · 8ea05e3a
      Alexander Block 提交于
      This patch introduces uuids for subvolumes. Each
      subvolume has it's own uuid. In case it was snapshotted,
      it also contains parent_uuid. In case it was received,
      it also contains received_uuid.
      
      It also introduces subvolume ctime/otime/stime/rtime. The
      first two are comparable to the times found in inodes. otime
      is the origin/creation time and ctime is the change time.
      stime/rtime are only valid on received subvolumes.
      stime is the time of the subvolume when it was
      sent. rtime is the time of the subvolume when it was
      received.
      
      Additionally to the times, we have a transid for each
      time. They are updated at the same place as the times.
      
      btrfs receive uses stransid and rtransid to find out
      if a received subvolume changed in the meantime.
      
      If an older kernel mounts a filesystem with the
      extented fields, all fields become invalid. The next
      mount with a new kernel will detect this and reset the
      fields.
      Signed-off-by: NAlexander Block <ablock84@googlemail.com>
      Reviewed-by: NDavid Sterba <dave@jikos.cz>
      Reviewed-by: NArne Jansen <sensille@gmx.net>
      Reviewed-by: NJan Schmidt <list.btrfs@jan-o-sch.net>
      Reviewed-by: NAlex Lyakas <alex.bolshoy.btrfs@gmail.com>
      8ea05e3a
  3. 24 7月, 2012 6 次提交
  4. 03 7月, 2012 2 次提交
    • L
      Btrfs: fix wrong check during log recovery · 6bf02314
      Liu Bo 提交于
      When we're evicting an inode during log recovery, we need to ensure that the inode
      is not in orphan state any more, which means inode's run_time flags has _no_
      BTRFS_INODE_HAS_ORPHAN_ITEM.  Thus, the BUG_ON was triggered because of a wrong
      check for the flags.
      Reviewed-by: NDavid Sterba <dsterba@suse.cz>
      Signed-off-by: NLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: NJosef Bacik <jbacik@fusionio.com>
      6bf02314
    • J
      Btrfs: fix dio write vs buffered read race · c3473e83
      Josef Bacik 提交于
      Miao pointed out there's a problem with mixing dio writes and buffered
      reads.  If the read happens between us invalidating the page range and
      actually locking the extent we can bring in pages into page cache.  Then
      once the write finishes if somebody tries to read again it will just find
      uptodate pages and we'll read stale data.  So we need to lock the extent and
      check for uptodate bits in the range.  If there are uptodate bits we need to
      unlock and invalidate again.  This will keep this race from happening since
      we will hold the extent locked until we create the ordered extent, and then
      teh read side always waits for ordered extents.  There was also a race in
      how we updated i_size, previously we were relying on the generic DIO stuff
      to adjust the i_size after the DIO had completed, but this happens outside
      of the extent lock which means reads could come in and not see the updated
      i_size.  So instead move this work into where we create the extents, and
      then this way the update ordered i_size stuff works properly in the endio
      handlers.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      c3473e83
  5. 21 6月, 2012 1 次提交
  6. 15 6月, 2012 5 次提交
    • L
      Btrfs: fix missing inherited flag in rename · bc178237
      Liu Bo 提交于
      When we move a file into a directory with compression flag, we need to
      inherite BTRFS_INODE_COMPRESS and clear BTRFS_INODE_NOCOMPRESS as well.
      But if we move a file into a directory without compression flag, we need
      to clear both of them.
      
      It is the way how our setflags deals with compression flag, so keep
      the same behaviour here.
      Signed-off-by: NLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: NChris Mason <chris.mason@fusionio.com>
      bc178237
    • J
      Btrfs: call filemap_fdatawrite twice for compression · 7ddf5a42
      Josef Bacik 提交于
      I removed this in an earlier commit and I was wrong.  Because compression
      can return from filemap_fdatawrite() without having actually set any of it's
      pages as writeback() it can make filemap_fdatawait() do essentially nothing,
      and then we won't find any ordered extents because they may not have been
      created yet.  So not only does this make fsync() completely useless, but it
      will also screw up if you truncate on a non-page aligned offset since we
      zero out the end and then wait on ordered extents and then call drop caches.
      We can drop the cache before the io completes and then we try to unpin the
      extent we just wrote we won't find it and everything goes sideways.  So fix
      this by putting it back and put a giant comment there to keep me from trying
      to remove it in the future.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      7ddf5a42
    • J
      Btrfs: keep inode pinned when compressing writes · 8180ef88
      Josef Bacik 提交于
      A user reported lots of problems using compression on the new code and it
      turns out part of the problem was that igrab() was failing when we added a
      new ordered extent.  This is because when writing out an inode under
      compression we immediately return without actually doing anything to the
      pages, and then in another thread at some point down the line actually do
      the ordered dance.  The problem is between the point that we start writeback
      and we actually add the ordered extent we could be trying to reclaim the
      inode, which makes igrab() return NULL.  So we need to do an igrab() when we
      create the async extent and then drop it when we are done with it.  This
      makes sure we stay pinned in memory until the ordered extent can get a
      reference on it and we are good to go.  With this patch we no longer panic
      in btrfs_finish_ordered_io().  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      8180ef88
    • J
      Btrfs: unlock everything properly in the error case for nocow · 17ca04af
      Josef Bacik 提交于
      I was getting hung on umount when a transaction was aborted because a range
      of one of the free space inodes was still locked.  This is because the nocow
      stuff doesn't unlock anything on error.  This fixed the problem and I
      verified that is what was happening.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      17ca04af
    • J
      Btrfs: pass locked_page into extent_clear_unlock_delalloc if theres an error · beb42dd7
      Josef Bacik 提交于
      While doing my enospc work I got a transaction abortion that resulted in a
      panic when we tried to unlock_page() an already unlocked page.  This is
      because we aren't calling extent_clear_unlock_delalloc with the locked page
      so it was unlocking all the pages in the range.  This is wrong since
      __extent_writepage expects to have the page locked still unless we return
      *page_started as 1.  This should keep us from panicing.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      beb42dd7
  7. 02 6月, 2012 1 次提交
  8. 30 5月, 2012 5 次提交
    • J
      Btrfs: fall back to non-inline if we don't have enough space · 2adcac1a
      Josef Bacik 提交于
      If cow_file_range_inline fails with ENOSPC we abort the transaction which
      isn't very nice.  This really shouldn't be happening anyways but there's no
      sense in making it a horrible error when we can easily just go allocate
      normal data space for this stuff.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      2adcac1a
    • J
      Btrfs: fix how we deal with the orphan block rsv · 8a35d95f
      Josef Bacik 提交于
      Ceph was hitting this race where we would remove an inode from the per-root
      orphan list before we would release the space we had reserved for the inode.
      We actually don't need a list or anything, we just need to make sure the
      root doesn't try to free up the orphan reserve until after the inodes have
      released their reservations.  So use an atomic counter instead of a list on
      the root and only decrement the counter after we've released our
      reservation.  I've tested this as well as several others and we no longer
      see the warnings that you would see while running ceph.  Thanks,
      Btrfs: fix how we deal with the orphan block rsv
      
      Ceph was hitting this race where we would remove an inode from the per-root
      orphan list before we would release the space we had reserved for the inode.
      We actually don't need a list or anything, we just need to make sure the
      root doesn't try to free up the orphan reserve until after the inodes have
      released their reservations.  So use an atomic counter instead of a list on
      the root and only decrement the counter after we've released our
      reservation.  I've tested this as well as several others and we no longer
      see the warnings that you would see while running ceph.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      8a35d95f
    • J
      Btrfs: convert the inode bit field to use the actual bit operations · 72ac3c0d
      Josef Bacik 提交于
      Miao pointed this out while I was working on an orphan problem that messing
      with a bitfield where different ranges are protected by different locks
      doesn't work out right.  Turns out we've been doing this forever where we
      have different parts of the bit field protected by either no lock at all or
      different locks which could cause all sorts of weird problems including the
      issue I was hitting.  So instead make a runtime_flags thing that we use the
      normal bit operations on that are all atomic so we can keep having our
      no/different locking for the different flags and then make force_compress
      it's own thing so it can be treated normally.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      72ac3c0d
    • J
      Btrfs: finish ordered extents in their own thread · 5fd02043
      Josef Bacik 提交于
      We noticed that the ordered extent completion doesn't really rely on having
      a page and that it could be done independantly of ending the writeback on a
      page.  This patch makes us not do the threaded endio stuff for normal
      buffered writes and direct writes so we can end page writeback as soon as
      possible (in irq context) and only start threads to do the ordered work when
      it is actually done.  Compression needs to be reworked some to take
      advantage of this as well, but atm it has to do a find_get_page in its endio
      handler so it must be done in its own thread.  This makes direct writes
      quite a bit faster.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      5fd02043
    • J
      Btrfs: use i_version instead of our own sequence · 0c4d2d95
      Josef Bacik 提交于
      We've been keeping around the inode sequence number in hopes that somebody
      would use it, but nobody uses it and people actually use i_version which
      serves the same purpose, so use i_version where we used the incore inode's
      sequence number and that way the sequence is updated properly across the
      board, and not just in file write.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      0c4d2d95
  9. 06 5月, 2012 1 次提交
  10. 28 4月, 2012 1 次提交
  11. 19 4月, 2012 3 次提交
    • J
      Btrfs: always store the mirror we read the eb from · 5cf1ab56
      Josef Bacik 提交于
      A user reported a panic where we were trying to fix a bad mirror but the
      mirror number we were giving was 0, which is invalid.  This is because we
      don't do the transid verification until after the read, so as far as the
      read code is concerned the read was a success.  So instead store the mirror
      we read from so that if there is some failure post read we know which mirror
      to try next and which mirror needs to be fixed if we find a good copy of the
      block.  Thanks,
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      5cf1ab56
    • A
      btrfs: fix race in reada · 8c9c2bf7
      Arne Jansen 提交于
      When inserting into the radix tree returns EEXIST, get the existing
      entry without giving up the spinlock in between.
      There was a race for both the zones trees and the extent tree.
      Signed-off-by: NArne Jansen <sensille@gmx.net>
      8c9c2bf7
    • L
      Btrfs: avoid setting ->d_op twice · 848cce0d
      Li Zefan 提交于
      Follow those instructions, and you'll trigger a warning in the
      beginning of d_set_d_op():
      
        # mkfs.btrfs /dev/loop3
        # mount /dev/loop3 /mnt
        # btrfs sub create /mnt/sub
        # btrfs sub snap /mnt /mnt/snap
        # touch /mnt/snap/sub
        touch: cannot touch `tmp': Permission denied
      
      __d_alloc() set d_op to sb->s_d_op (btrfs_dentry_operations), and
      then simple_lookup() reset it to simple_dentry_operations, which
      triggered the warning.
      Signed-off-by: NLi Zefan <lizf@cn.fujitsu.com>
      848cce0d
  12. 29 3月, 2012 1 次提交
    • L
      Btrfs: fix recursive defragment with autodefrag option · 4cb13e5d
      Liu Bo 提交于
      $ mkfs.btrfs disk
      $ mount disk /mnt -o autodefrag
      $ dd if=/dev/zero of=/mnt/foobar bs=4k count=10 2>/dev/null && sync
      $ for i in `seq 9 -2 0`; do dd if=/dev/zero of=/mnt/foobar bs=4k count=1 \
        seek=$i conv=notrunc 2> /dev/null; done && sync
      
      then we'll get to defrag "foobar" again and again.
      So does option "-o autodefrag,compress".
      
      Reasons:
      When the cleaner kthread gets to fetch inodes from the defrag tree and defrag
      them, it will dirty pages and submit them, this will comes to another DATA COW
      where the processing inode will be inserted to the defrag tree again.
      
      This patch sets a rule for COW code, i.e. insert an inode when we're really
      going to make some defragments.
      Signed-off-by: NLiu Bo <liubo2009@cn.fujitsu.com>
      Signed-off-by: NChris Mason <chris.mason@oracle.com>
      4cb13e5d
  13. 27 3月, 2012 2 次提交
  14. 22 3月, 2012 7 次提交