Merge branch 'for-4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Nov 2016 03:08:16 +0000 (20:08 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 5 Nov 2016 03:08:16 +0000 (20:08 -0700)
Pull btrfs fixes from Chris Mason:
 "Some fixes that Dave Sterba collected.  We held off on these last week
  because I was focused on the memory corruption testing"

* 'for-4.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: fix WARNING in btrfs_select_ref_head()
  Btrfs: remove some no-op casts
  btrfs: pass correct args to btrfs_async_run_delayed_refs()
  btrfs: make file clone aware of fatal signals
  btrfs: qgroup: Prevent qgroup->reserved from going subzero
  Btrfs: kill BUG_ON in do_relocation

fs/btrfs/extent-tree.c
fs/btrfs/extent_io.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c
fs/btrfs/relocation.c

index 210c94ac881888045b59a2f7a0d10f7c698cdebc..4607af38c72e100e6728ff41d8198140dd722d93 100644 (file)
@@ -2647,7 +2647,10 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
 
                btrfs_free_delayed_extent_op(extent_op);
                if (ret) {
+                       spin_lock(&delayed_refs->lock);
                        locked_ref->processing = 0;
+                       delayed_refs->num_heads_ready++;
+                       spin_unlock(&delayed_refs->lock);
                        btrfs_delayed_ref_unlock(locked_ref);
                        btrfs_put_delayed_ref(ref);
                        btrfs_debug(fs_info, "run_one_delayed_ref returned %d",
index 66a755150056ed06af2c3bc636b4dc76f45adce5..8ed05d95584a30c2c0cdc4feb1bd2036e93d3276 100644 (file)
@@ -5569,7 +5569,7 @@ void le_bitmap_set(u8 *map, unsigned int start, int len)
                *p |= mask_to_set;
                len -= bits_to_set;
                bits_to_set = BITS_PER_BYTE;
-               mask_to_set = ~(u8)0;
+               mask_to_set = ~0;
                p++;
        }
        if (len) {
@@ -5589,7 +5589,7 @@ void le_bitmap_clear(u8 *map, unsigned int start, int len)
                *p &= ~mask_to_clear;
                len -= bits_to_clear;
                bits_to_clear = BITS_PER_BYTE;
-               mask_to_clear = ~(u8)0;
+               mask_to_clear = ~0;
                p++;
        }
        if (len) {
@@ -5679,7 +5679,7 @@ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
                kaddr[offset] |= mask_to_set;
                len -= bits_to_set;
                bits_to_set = BITS_PER_BYTE;
-               mask_to_set = ~(u8)0;
+               mask_to_set = ~0;
                if (++offset >= PAGE_SIZE && len > 0) {
                        offset = 0;
                        page = eb->pages[++i];
@@ -5721,7 +5721,7 @@ void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
                kaddr[offset] &= ~mask_to_clear;
                len -= bits_to_clear;
                bits_to_clear = BITS_PER_BYTE;
-               mask_to_clear = ~(u8)0;
+               mask_to_clear = ~0;
                if (++offset >= PAGE_SIZE && len > 0) {
                        offset = 0;
                        page = eb->pages[++i];
index 2b790bda79988002403f6fe326dcc5535e9f079d..8e3a5a266917c0fac9da9f41ee080262f3394779 100644 (file)
@@ -4605,8 +4605,8 @@ delete:
                        BUG_ON(ret);
                        if (btrfs_should_throttle_delayed_refs(trans, root))
                                btrfs_async_run_delayed_refs(root,
-                                                            trans->transid,
-                                       trans->delayed_ref_updates * 2, 0);
+                                       trans->delayed_ref_updates * 2,
+                                       trans->transid, 0);
                        if (be_nice) {
                                if (truncate_space_check(trans, root,
                                                         extent_num_bytes)) {
@@ -8931,9 +8931,14 @@ again:
         *    So even we call qgroup_free_data(), it won't decrease reserved
         *    space.
         * 2) Not written to disk
-        *    This means the reserved space should be freed here.
+        *    This means the reserved space should be freed here. However,
+        *    if a truncate invalidates the page (by clearing PageDirty)
+        *    and the page is accounted for while allocating extent
+        *    in btrfs_check_data_free_space() we let delayed_ref to
+        *    free the entire extent.
         */
-       btrfs_qgroup_free_data(inode, page_start, PAGE_SIZE);
+       if (PageDirty(page))
+               btrfs_qgroup_free_data(inode, page_start, PAGE_SIZE);
        if (!inode_evicting) {
                clear_extent_bit(tree, page_start, page_end,
                                 EXTENT_LOCKED | EXTENT_DIRTY |
index 18e1aa0f85f5764aa28de59e148a96f49fdacf04..7acbd2cf6192ee8d967236f4b3aeecf1bfc98658 100644 (file)
@@ -3814,6 +3814,11 @@ process_slot:
                }
                btrfs_release_path(path);
                key.offset = next_key_min_offset;
+
+               if (fatal_signal_pending(current)) {
+                       ret = -EINTR;
+                       goto out;
+               }
        }
        ret = 0;
 
index 0ec8ffa37ab09dce21e6d2806c938cce6d4d17a7..c4af0cdb783d0e2ee203ad416abb745fcabd7e02 100644 (file)
@@ -2728,7 +2728,14 @@ static int do_relocation(struct btrfs_trans_handle *trans,
 
                bytenr = btrfs_node_blockptr(upper->eb, slot);
                if (lowest) {
-                       BUG_ON(bytenr != node->bytenr);
+                       if (bytenr != node->bytenr) {
+                               btrfs_err(root->fs_info,
+               "lowest leaf/node mismatch: bytenr %llu node->bytenr %llu slot %d upper %llu",
+                                         bytenr, node->bytenr, slot,
+                                         upper->eb->start);
+                               err = -EIO;
+                               goto next;
+                       }
                } else {
                        if (node->eb->start == bytenr)
                                goto next;