From dce8b76d1fb098903fe9b718796ca8774e3e5e7c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 12 Dec 2015 11:46:57 -0800 Subject: [PATCH] 4.3-stable patches added patches: btrfs-fix-regression-running-delayed-references-when-using-qgroups.patch --- ...elayed-references-when-using-qgroups.patch | 832 ++++++++++++++++++ ...o-fix-bugs-in-ext4_encrypted_zeroout.patch | 4 +- ...lace-some-bug_on-s-with-error-checks.patch | 101 --- queue-4.3/series | 2 +- 4 files changed, 835 insertions(+), 104 deletions(-) create mode 100644 queue-4.3/btrfs-fix-regression-running-delayed-references-when-using-qgroups.patch delete mode 100644 queue-4.3/ext4-crypto-replace-some-bug_on-s-with-error-checks.patch diff --git a/queue-4.3/btrfs-fix-regression-running-delayed-references-when-using-qgroups.patch b/queue-4.3/btrfs-fix-regression-running-delayed-references-when-using-qgroups.patch new file mode 100644 index 00000000000..4afd9698ec2 --- /dev/null +++ b/queue-4.3/btrfs-fix-regression-running-delayed-references-when-using-qgroups.patch @@ -0,0 +1,832 @@ +From b06c4bf5c874a57254b197f53ddf588e7a24a2bf Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Fri, 23 Oct 2015 07:52:54 +0100 +Subject: Btrfs: fix regression running delayed references when using qgroups +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Filipe Manana + +commit b06c4bf5c874a57254b197f53ddf588e7a24a2bf upstream. + +In the kernel 4.2 merge window we had a big changes to the implementation +of delayed references and qgroups which made the no_quota field of delayed +references not used anymore. More specifically the no_quota field is not +used anymore as of: + + commit 0ed4792af0e8 ("btrfs: qgroup: Switch to new extent-oriented qgroup mechanism.") + +Leaving the no_quota field actually prevents delayed references from +getting merged, which in turn cause the following BUG_ON(), at +fs/btrfs/extent-tree.c, to be hit when qgroups are enabled: + + static int run_delayed_tree_ref(...) + { + (...) + BUG_ON(node->ref_mod != 1); + (...) + } + +This happens on a scenario like the following: + + 1) Ref1 bytenr X, action = BTRFS_ADD_DELAYED_REF, no_quota = 1, added. + + 2) Ref2 bytenr X, action = BTRFS_DROP_DELAYED_REF, no_quota = 0, added. + It's not merged with Ref1 because Ref1->no_quota != Ref2->no_quota. + + 3) Ref3 bytenr X, action = BTRFS_ADD_DELAYED_REF, no_quota = 1, added. + It's not merged with the reference at the tail of the list of refs + for bytenr X because the reference at the tail, Ref2 is incompatible + due to Ref2->no_quota != Ref3->no_quota. + + 4) Ref4 bytenr X, action = BTRFS_DROP_DELAYED_REF, no_quota = 0, added. + It's not merged with the reference at the tail of the list of refs + for bytenr X because the reference at the tail, Ref3 is incompatible + due to Ref3->no_quota != Ref4->no_quota. + + 5) We run delayed references, trigger merging of delayed references, + through __btrfs_run_delayed_refs() -> btrfs_merge_delayed_refs(). + + 6) Ref1 and Ref3 are merged as Ref1->no_quota = Ref3->no_quota and + all other conditions are satisfied too. So Ref1 gets a ref_mod + value of 2. + + 7) Ref2 and Ref4 are merged as Ref2->no_quota = Ref4->no_quota and + all other conditions are satisfied too. So Ref2 gets a ref_mod + value of 2. + + 8) Ref1 and Ref2 aren't merged, because they have different values + for their no_quota field. + + 9) Delayed reference Ref1 is picked for running (select_delayed_ref() + always prefers references with an action == BTRFS_ADD_DELAYED_REF). + So run_delayed_tree_ref() is called for Ref1 which triggers the + BUG_ON because Ref1->red_mod != 1 (equals 2). + +So fix this by removing the no_quota field, as it's not used anymore as +of commit 0ed4792af0e8 ("btrfs: qgroup: Switch to new extent-oriented +qgroup mechanism."). + +The use of no_quota was also buggy in at least two places: + +1) At delayed-refs.c:btrfs_add_delayed_tree_ref() - we were setting + no_quota to 0 instead of 1 when the following condition was true: + is_fstree(ref_root) || !fs_info->quota_enabled + +2) At extent-tree.c:__btrfs_inc_extent_ref() - we were attempting to + reset a node's no_quota when the condition "!is_fstree(root_objectid) + || !root->fs_info->quota_enabled" was true but we did it only in + an unused local stack variable, that is, we never reset the no_quota + value in the node itself. + +This fixes the remainder of problems several people have been having when +running delayed references, mostly while a balance is running in parallel, +on a 4.2+ kernel. + +Very special thanks to Stéphane Lesimple for helping debugging this issue +and testing this fix on his multi terabyte filesystem (which took more +than one day to balance alone, plus fsck, etc). + +Also, this fixes deadlock issue when using the clone ioctl with qgroups +enabled, as reported by Elias Probst in the mailing list. The deadlock +happens because after calling btrfs_insert_empty_item we have our path +holding a write lock on a leaf of the fs/subvol tree and then before +releasing the path we called check_ref() which did backref walking, when +qgroups are enabled, and tried to read lock the same leaf. The trace for +this case is the following: + + INFO: task systemd-nspawn:6095 blocked for more than 120 seconds. + (...) + Call Trace: + [] schedule+0x74/0x83 + [] btrfs_tree_read_lock+0xc0/0xea + [] ? wait_woken+0x74/0x74 + [] btrfs_search_old_slot+0x51a/0x810 + [] btrfs_next_old_leaf+0xdf/0x3ce + [] ? ulist_add_merge+0x1b/0x127 + [] __resolve_indirect_refs+0x62a/0x667 + [] ? btrfs_clear_lock_blocking_rw+0x78/0xbe + [] find_parent_nodes+0xaf3/0xfc6 + [] __btrfs_find_all_roots+0x92/0xf0 + [] btrfs_find_all_roots+0x45/0x65 + [] ? btrfs_get_tree_mod_seq+0x2b/0x88 + [] check_ref+0x64/0xc4 + [] btrfs_clone+0x66e/0xb5d + [] btrfs_ioctl_clone+0x48f/0x5bb + [] ? native_sched_clock+0x28/0x77 + [] btrfs_ioctl+0xabc/0x25cb + (...) + +The problem goes away by eleminating check_ref(), which no longer is +needed as its purpose was to get a value for the no_quota field of +a delayed reference (this patch removes the no_quota field as mentioned +earlier). + +Reported-by: Stéphane Lesimple +Tested-by: Stéphane Lesimple +Reported-by: Elias Probst +Reported-by: Peter Becker +Reported-by: Malte Schröder +Reported-by: Derek Dongray +Reported-by: Erkki Seppala +Signed-off-by: Filipe Manana +Reviewed-by: Qu Wenruo +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ctree.h | 4 - + fs/btrfs/delayed-ref.c | 139 ++++++++++++++++++++++++++++++++++++++++++------- + fs/btrfs/delayed-ref.h | 7 -- + fs/btrfs/extent-tree.c | 45 +++++---------- + fs/btrfs/file.c | 10 +-- + fs/btrfs/inode.c | 4 - + fs/btrfs/ioctl.c | 62 --------------------- + fs/btrfs/relocation.c | 16 ++--- + fs/btrfs/tree-log.c | 2 + 9 files changed, 156 insertions(+), 133 deletions(-) + +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -3398,7 +3398,7 @@ int btrfs_set_disk_extent_flags(struct b + int btrfs_free_extent(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, +- u64 owner, u64 offset, int no_quota); ++ u64 owner, u64 offset); + + int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len, + int delalloc); +@@ -3411,7 +3411,7 @@ int btrfs_finish_extent_commit(struct bt + int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 bytenr, u64 num_bytes, u64 parent, +- u64 root_objectid, u64 owner, u64 offset, int no_quota); ++ u64 root_objectid, u64 owner, u64 offset); + + int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans, + struct btrfs_root *root); +--- a/fs/btrfs/delayed-ref.c ++++ b/fs/btrfs/delayed-ref.c +@@ -310,6 +310,119 @@ next: + } + } + ++static bool merge_ref(struct btrfs_trans_handle *trans, ++ struct btrfs_delayed_ref_root *delayed_refs, ++ struct btrfs_delayed_ref_head *head, ++ struct btrfs_delayed_ref_node *ref, ++ u64 seq) ++{ ++ struct btrfs_delayed_ref_node *next; ++ bool done = false; ++ ++ next = list_first_entry(&head->ref_list, struct btrfs_delayed_ref_node, ++ list); ++ while (!done && &next->list != &head->ref_list) { ++ int mod; ++ struct btrfs_delayed_ref_node *next2; ++ ++ next2 = list_next_entry(next, list); ++ ++ if (next == ref) ++ goto next; ++ ++ if (seq && next->seq >= seq) ++ goto next; ++ ++ if (next->type != ref->type) ++ goto next; ++ ++ if ((ref->type == BTRFS_TREE_BLOCK_REF_KEY || ++ ref->type == BTRFS_SHARED_BLOCK_REF_KEY) && ++ comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref), ++ btrfs_delayed_node_to_tree_ref(next), ++ ref->type)) ++ goto next; ++ if ((ref->type == BTRFS_EXTENT_DATA_REF_KEY || ++ ref->type == BTRFS_SHARED_DATA_REF_KEY) && ++ comp_data_refs(btrfs_delayed_node_to_data_ref(ref), ++ btrfs_delayed_node_to_data_ref(next))) ++ goto next; ++ ++ if (ref->action == next->action) { ++ mod = next->ref_mod; ++ } else { ++ if (ref->ref_mod < next->ref_mod) { ++ swap(ref, next); ++ done = true; ++ } ++ mod = -next->ref_mod; ++ } ++ ++ drop_delayed_ref(trans, delayed_refs, head, next); ++ ref->ref_mod += mod; ++ if (ref->ref_mod == 0) { ++ drop_delayed_ref(trans, delayed_refs, head, ref); ++ done = true; ++ } else { ++ /* ++ * Can't have multiples of the same ref on a tree block. ++ */ ++ WARN_ON(ref->type == BTRFS_TREE_BLOCK_REF_KEY || ++ ref->type == BTRFS_SHARED_BLOCK_REF_KEY); ++ } ++next: ++ next = next2; ++ } ++ ++ return done; ++} ++ ++void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans, ++ struct btrfs_fs_info *fs_info, ++ struct btrfs_delayed_ref_root *delayed_refs, ++ struct btrfs_delayed_ref_head *head) ++{ ++ struct btrfs_delayed_ref_node *ref; ++ u64 seq = 0; ++ ++ assert_spin_locked(&head->lock); ++ ++ if (list_empty(&head->ref_list)) ++ return; ++ ++ /* We don't have too many refs to merge for data. */ ++ if (head->is_data) ++ return; ++ ++ spin_lock(&fs_info->tree_mod_seq_lock); ++ if (!list_empty(&fs_info->tree_mod_seq_list)) { ++ struct seq_list *elem; ++ ++ elem = list_first_entry(&fs_info->tree_mod_seq_list, ++ struct seq_list, list); ++ seq = elem->seq; ++ } ++ spin_unlock(&fs_info->tree_mod_seq_lock); ++ ++ ref = list_first_entry(&head->ref_list, struct btrfs_delayed_ref_node, ++ list); ++ while (&ref->list != &head->ref_list) { ++ if (seq && ref->seq >= seq) ++ goto next; ++ ++ if (merge_ref(trans, delayed_refs, head, ref, seq)) { ++ if (list_empty(&head->ref_list)) ++ break; ++ ref = list_first_entry(&head->ref_list, ++ struct btrfs_delayed_ref_node, ++ list); ++ continue; ++ } ++next: ++ ref = list_next_entry(ref, list); ++ } ++} ++ + int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, + struct btrfs_delayed_ref_root *delayed_refs, + u64 seq) +@@ -405,8 +518,7 @@ add_delayed_ref_tail_merge(struct btrfs_ + exist = list_entry(href->ref_list.prev, struct btrfs_delayed_ref_node, + list); + /* No need to compare bytenr nor is_head */ +- if (exist->type != ref->type || exist->no_quota != ref->no_quota || +- exist->seq != ref->seq) ++ if (exist->type != ref->type || exist->seq != ref->seq) + goto add_tail; + + if ((exist->type == BTRFS_TREE_BLOCK_REF_KEY || +@@ -637,7 +749,7 @@ add_delayed_tree_ref(struct btrfs_fs_inf + struct btrfs_delayed_ref_head *head_ref, + struct btrfs_delayed_ref_node *ref, u64 bytenr, + u64 num_bytes, u64 parent, u64 ref_root, int level, +- int action, int no_quota) ++ int action) + { + struct btrfs_delayed_tree_ref *full_ref; + struct btrfs_delayed_ref_root *delayed_refs; +@@ -659,7 +771,6 @@ add_delayed_tree_ref(struct btrfs_fs_inf + ref->action = action; + ref->is_head = 0; + ref->in_tree = 1; +- ref->no_quota = no_quota; + ref->seq = seq; + + full_ref = btrfs_delayed_node_to_tree_ref(ref); +@@ -692,7 +803,7 @@ add_delayed_data_ref(struct btrfs_fs_inf + struct btrfs_delayed_ref_head *head_ref, + struct btrfs_delayed_ref_node *ref, u64 bytenr, + u64 num_bytes, u64 parent, u64 ref_root, u64 owner, +- u64 offset, int action, int no_quota) ++ u64 offset, int action) + { + struct btrfs_delayed_data_ref *full_ref; + struct btrfs_delayed_ref_root *delayed_refs; +@@ -715,7 +826,6 @@ add_delayed_data_ref(struct btrfs_fs_inf + ref->action = action; + ref->is_head = 0; + ref->in_tree = 1; +- ref->no_quota = no_quota; + ref->seq = seq; + + full_ref = btrfs_delayed_node_to_data_ref(ref); +@@ -746,17 +856,13 @@ int btrfs_add_delayed_tree_ref(struct bt + struct btrfs_trans_handle *trans, + u64 bytenr, u64 num_bytes, u64 parent, + u64 ref_root, int level, int action, +- struct btrfs_delayed_extent_op *extent_op, +- int no_quota) ++ struct btrfs_delayed_extent_op *extent_op) + { + struct btrfs_delayed_tree_ref *ref; + struct btrfs_delayed_ref_head *head_ref; + struct btrfs_delayed_ref_root *delayed_refs; + struct btrfs_qgroup_extent_record *record = NULL; + +- if (!is_fstree(ref_root) || !fs_info->quota_enabled) +- no_quota = 0; +- + BUG_ON(extent_op && extent_op->is_data); + ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS); + if (!ref) +@@ -785,8 +891,7 @@ int btrfs_add_delayed_tree_ref(struct bt + bytenr, num_bytes, action, 0); + + add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr, +- num_bytes, parent, ref_root, level, action, +- no_quota); ++ num_bytes, parent, ref_root, level, action); + spin_unlock(&delayed_refs->lock); + + return 0; +@@ -807,17 +912,13 @@ int btrfs_add_delayed_data_ref(struct bt + u64 bytenr, u64 num_bytes, + u64 parent, u64 ref_root, + u64 owner, u64 offset, int action, +- struct btrfs_delayed_extent_op *extent_op, +- int no_quota) ++ struct btrfs_delayed_extent_op *extent_op) + { + struct btrfs_delayed_data_ref *ref; + struct btrfs_delayed_ref_head *head_ref; + struct btrfs_delayed_ref_root *delayed_refs; + struct btrfs_qgroup_extent_record *record = NULL; + +- if (!is_fstree(ref_root) || !fs_info->quota_enabled) +- no_quota = 0; +- + BUG_ON(extent_op && !extent_op->is_data); + ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS); + if (!ref) +@@ -853,7 +954,7 @@ int btrfs_add_delayed_data_ref(struct bt + + add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr, + num_bytes, parent, ref_root, owner, offset, +- action, no_quota); ++ action); + spin_unlock(&delayed_refs->lock); + + return 0; +--- a/fs/btrfs/delayed-ref.h ++++ b/fs/btrfs/delayed-ref.h +@@ -68,7 +68,6 @@ struct btrfs_delayed_ref_node { + + unsigned int action:8; + unsigned int type:8; +- unsigned int no_quota:1; + /* is this node still in the rbtree? */ + unsigned int is_head:1; + unsigned int in_tree:1; +@@ -233,15 +232,13 @@ int btrfs_add_delayed_tree_ref(struct bt + struct btrfs_trans_handle *trans, + u64 bytenr, u64 num_bytes, u64 parent, + u64 ref_root, int level, int action, +- struct btrfs_delayed_extent_op *extent_op, +- int no_quota); ++ struct btrfs_delayed_extent_op *extent_op); + int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, + struct btrfs_trans_handle *trans, + u64 bytenr, u64 num_bytes, + u64 parent, u64 ref_root, + u64 owner, u64 offset, int action, +- struct btrfs_delayed_extent_op *extent_op, +- int no_quota); ++ struct btrfs_delayed_extent_op *extent_op); + int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, + struct btrfs_trans_handle *trans, + u64 bytenr, u64 num_bytes, +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -95,8 +95,7 @@ static int alloc_reserved_tree_block(str + struct btrfs_root *root, + u64 parent, u64 root_objectid, + u64 flags, struct btrfs_disk_key *key, +- int level, struct btrfs_key *ins, +- int no_quota); ++ int level, struct btrfs_key *ins); + static int do_chunk_alloc(struct btrfs_trans_handle *trans, + struct btrfs_root *extent_root, u64 flags, + int force); +@@ -2009,8 +2008,7 @@ int btrfs_discard_extent(struct btrfs_ro + int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + u64 bytenr, u64 num_bytes, u64 parent, +- u64 root_objectid, u64 owner, u64 offset, +- int no_quota) ++ u64 root_objectid, u64 owner, u64 offset) + { + int ret; + struct btrfs_fs_info *fs_info = root->fs_info; +@@ -2022,12 +2020,12 @@ int btrfs_inc_extent_ref(struct btrfs_tr + ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, + num_bytes, + parent, root_objectid, (int)owner, +- BTRFS_ADD_DELAYED_REF, NULL, no_quota); ++ BTRFS_ADD_DELAYED_REF, NULL); + } else { + ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, + num_bytes, + parent, root_objectid, owner, offset, +- BTRFS_ADD_DELAYED_REF, NULL, no_quota); ++ BTRFS_ADD_DELAYED_REF, NULL); + } + return ret; + } +@@ -2048,15 +2046,11 @@ static int __btrfs_inc_extent_ref(struct + u64 num_bytes = node->num_bytes; + u64 refs; + int ret; +- int no_quota = node->no_quota; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + +- if (!is_fstree(root_objectid) || !root->fs_info->quota_enabled) +- no_quota = 1; +- + path->reada = 1; + path->leave_spinning = 1; + /* this will setup the path even if it fails to insert the back ref */ +@@ -2291,8 +2285,7 @@ static int run_delayed_tree_ref(struct b + parent, ref_root, + extent_op->flags_to_set, + &extent_op->key, +- ref->level, &ins, +- node->no_quota); ++ ref->level, &ins); + } else if (node->action == BTRFS_ADD_DELAYED_REF) { + ret = __btrfs_inc_extent_ref(trans, root, node, + parent, ref_root, +@@ -3123,7 +3116,7 @@ static int __btrfs_mod_ref(struct btrfs_ + int level; + int ret = 0; + int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, +- u64, u64, u64, u64, u64, u64, int); ++ u64, u64, u64, u64, u64, u64); + + + if (btrfs_test_is_dummy_root(root)) +@@ -3164,15 +3157,14 @@ static int __btrfs_mod_ref(struct btrfs_ + key.offset -= btrfs_file_extent_offset(buf, fi); + ret = process_func(trans, root, bytenr, num_bytes, + parent, ref_root, key.objectid, +- key.offset, 1); ++ key.offset); + if (ret) + goto fail; + } else { + bytenr = btrfs_node_blockptr(buf, i); + num_bytes = root->nodesize; + ret = process_func(trans, root, bytenr, num_bytes, +- parent, ref_root, level - 1, 0, +- 1); ++ parent, ref_root, level - 1, 0); + if (ret) + goto fail; + } +@@ -6247,7 +6239,6 @@ static int __btrfs_free_extent(struct bt + int extent_slot = 0; + int found_extent = 0; + int num_to_del = 1; +- int no_quota = node->no_quota; + u32 item_size; + u64 refs; + u64 bytenr = node->bytenr; +@@ -6256,9 +6247,6 @@ static int __btrfs_free_extent(struct bt + bool skinny_metadata = btrfs_fs_incompat(root->fs_info, + SKINNY_METADATA); + +- if (!info->quota_enabled || !is_fstree(root_objectid)) +- no_quota = 1; +- + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; +@@ -6584,7 +6572,7 @@ void btrfs_free_tree_block(struct btrfs_ + buf->start, buf->len, + parent, root->root_key.objectid, + btrfs_header_level(buf), +- BTRFS_DROP_DELAYED_REF, NULL, 0); ++ BTRFS_DROP_DELAYED_REF, NULL); + BUG_ON(ret); /* -ENOMEM */ + } + +@@ -6632,7 +6620,7 @@ out: + /* Can return -ENOMEM */ + int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, + u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, +- u64 owner, u64 offset, int no_quota) ++ u64 owner, u64 offset) + { + int ret; + struct btrfs_fs_info *fs_info = root->fs_info; +@@ -6655,13 +6643,13 @@ int btrfs_free_extent(struct btrfs_trans + ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, + num_bytes, + parent, root_objectid, (int)owner, +- BTRFS_DROP_DELAYED_REF, NULL, no_quota); ++ BTRFS_DROP_DELAYED_REF, NULL); + } else { + ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, + num_bytes, + parent, root_objectid, owner, + offset, BTRFS_DROP_DELAYED_REF, +- NULL, no_quota); ++ NULL); + } + return ret; + } +@@ -7443,8 +7431,7 @@ static int alloc_reserved_tree_block(str + struct btrfs_root *root, + u64 parent, u64 root_objectid, + u64 flags, struct btrfs_disk_key *key, +- int level, struct btrfs_key *ins, +- int no_quota) ++ int level, struct btrfs_key *ins) + { + int ret; + struct btrfs_fs_info *fs_info = root->fs_info; +@@ -7534,7 +7521,7 @@ int btrfs_alloc_reserved_file_extent(str + ret = btrfs_add_delayed_data_ref(root->fs_info, trans, ins->objectid, + ins->offset, 0, + root_objectid, owner, offset, +- BTRFS_ADD_DELAYED_EXTENT, NULL, 0); ++ BTRFS_ADD_DELAYED_EXTENT, NULL); + return ret; + } + +@@ -7748,7 +7735,7 @@ struct extent_buffer *btrfs_alloc_tree_b + ins.objectid, ins.offset, + parent, root_objectid, level, + BTRFS_ADD_DELAYED_EXTENT, +- extent_op, 0); ++ extent_op); + if (ret) + goto out_free_delayed; + } +@@ -8296,7 +8283,7 @@ skip: + } + } + ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, +- root->root_key.objectid, level - 1, 0, 0); ++ root->root_key.objectid, level - 1, 0); + BUG_ON(ret); /* -ENOMEM */ + } + btrfs_tree_unlock(next); +--- a/fs/btrfs/file.c ++++ b/fs/btrfs/file.c +@@ -855,7 +855,7 @@ next_slot: + disk_bytenr, num_bytes, 0, + root->root_key.objectid, + new_key.objectid, +- start - extent_offset, 1); ++ start - extent_offset); + BUG_ON(ret); /* -ENOMEM */ + } + key.offset = start; +@@ -933,7 +933,7 @@ delete_extent_item: + disk_bytenr, num_bytes, 0, + root->root_key.objectid, + key.objectid, key.offset - +- extent_offset, 0); ++ extent_offset); + BUG_ON(ret); /* -ENOMEM */ + inode_sub_bytes(inode, + extent_end - key.offset); +@@ -1212,7 +1212,7 @@ again: + + ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, + root->root_key.objectid, +- ino, orig_offset, 1); ++ ino, orig_offset); + BUG_ON(ret); /* -ENOMEM */ + + if (split == start) { +@@ -1239,7 +1239,7 @@ again: + del_nr++; + ret = btrfs_free_extent(trans, root, bytenr, num_bytes, + 0, root->root_key.objectid, +- ino, orig_offset, 0); ++ ino, orig_offset); + BUG_ON(ret); /* -ENOMEM */ + } + other_start = 0; +@@ -1256,7 +1256,7 @@ again: + del_nr++; + ret = btrfs_free_extent(trans, root, bytenr, num_bytes, + 0, root->root_key.objectid, +- ino, orig_offset, 0); ++ ino, orig_offset); + BUG_ON(ret); /* -ENOMEM */ + } + if (del_nr == 0) { +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -2579,7 +2579,7 @@ again: + ret = btrfs_inc_extent_ref(trans, root, new->bytenr, + new->disk_len, 0, + backref->root_id, backref->inum, +- new->file_pos, 0); /* start - extent_offset */ ++ new->file_pos); /* start - extent_offset */ + if (ret) { + btrfs_abort_transaction(trans, root, ret); + goto out_free_path; +@@ -4521,7 +4521,7 @@ delete: + ret = btrfs_free_extent(trans, root, extent_start, + extent_num_bytes, 0, + btrfs_header_owner(leaf), +- ino, extent_offset, 0); ++ ino, extent_offset); + BUG_ON(ret); + if (btrfs_should_throttle_delayed_refs(trans, root)) + btrfs_async_run_delayed_refs(root, +--- a/fs/btrfs/ioctl.c ++++ b/fs/btrfs/ioctl.c +@@ -3203,41 +3203,6 @@ out: + return ret; + } + +-/* Helper to check and see if this root currently has a ref on the given disk +- * bytenr. If it does then we need to update the quota for this root. This +- * doesn't do anything if quotas aren't enabled. +- */ +-static int check_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, +- u64 disko) +-{ +- struct seq_list tree_mod_seq_elem = SEQ_LIST_INIT(tree_mod_seq_elem); +- struct ulist *roots; +- struct ulist_iterator uiter; +- struct ulist_node *root_node = NULL; +- int ret; +- +- if (!root->fs_info->quota_enabled) +- return 1; +- +- btrfs_get_tree_mod_seq(root->fs_info, &tree_mod_seq_elem); +- ret = btrfs_find_all_roots(trans, root->fs_info, disko, +- tree_mod_seq_elem.seq, &roots); +- if (ret < 0) +- goto out; +- ret = 0; +- ULIST_ITER_INIT(&uiter); +- while ((root_node = ulist_next(roots, &uiter))) { +- if (root_node->val == root->objectid) { +- ret = 1; +- break; +- } +- } +- ulist_free(roots); +-out: +- btrfs_put_tree_mod_seq(root->fs_info, &tree_mod_seq_elem); +- return ret; +-} +- + static int clone_finish_inode_update(struct btrfs_trans_handle *trans, + struct inode *inode, + u64 endoff, +@@ -3496,9 +3461,7 @@ static int btrfs_clone(struct inode *src + u32 nritems; + int slot; + int ret; +- int no_quota; + const u64 len = olen_aligned; +- u64 last_disko = 0; + u64 last_dest_end = destoff; + + ret = -ENOMEM; +@@ -3544,7 +3507,6 @@ static int btrfs_clone(struct inode *src + + nritems = btrfs_header_nritems(path->nodes[0]); + process_slot: +- no_quota = 1; + if (path->slots[0] >= nritems) { + ret = btrfs_next_leaf(BTRFS_I(src)->root, path); + if (ret < 0) +@@ -3696,35 +3658,13 @@ process_slot: + btrfs_set_file_extent_num_bytes(leaf, extent, + datal); + +- /* +- * We need to look up the roots that point at +- * this bytenr and see if the new root does. If +- * it does not we need to make sure we update +- * quotas appropriately. +- */ +- if (disko && root != BTRFS_I(src)->root && +- disko != last_disko) { +- no_quota = check_ref(trans, root, +- disko); +- if (no_quota < 0) { +- btrfs_abort_transaction(trans, +- root, +- ret); +- btrfs_end_transaction(trans, +- root); +- ret = no_quota; +- goto out; +- } +- } +- + if (disko) { + inode_add_bytes(inode, datal); + ret = btrfs_inc_extent_ref(trans, root, + disko, diskl, 0, + root->root_key.objectid, + btrfs_ino(inode), +- new_key.offset - datao, +- no_quota); ++ new_key.offset - datao); + if (ret) { + btrfs_abort_transaction(trans, + root, +--- a/fs/btrfs/relocation.c ++++ b/fs/btrfs/relocation.c +@@ -1716,7 +1716,7 @@ int replace_file_extents(struct btrfs_tr + ret = btrfs_inc_extent_ref(trans, root, new_bytenr, + num_bytes, parent, + btrfs_header_owner(leaf), +- key.objectid, key.offset, 1); ++ key.objectid, key.offset); + if (ret) { + btrfs_abort_transaction(trans, root, ret); + break; +@@ -1724,7 +1724,7 @@ int replace_file_extents(struct btrfs_tr + + ret = btrfs_free_extent(trans, root, bytenr, num_bytes, + parent, btrfs_header_owner(leaf), +- key.objectid, key.offset, 1); ++ key.objectid, key.offset); + if (ret) { + btrfs_abort_transaction(trans, root, ret); + break; +@@ -1900,23 +1900,21 @@ again: + + ret = btrfs_inc_extent_ref(trans, src, old_bytenr, blocksize, + path->nodes[level]->start, +- src->root_key.objectid, level - 1, 0, +- 1); ++ src->root_key.objectid, level - 1, 0); + BUG_ON(ret); + ret = btrfs_inc_extent_ref(trans, dest, new_bytenr, blocksize, + 0, dest->root_key.objectid, level - 1, +- 0, 1); ++ 0); + BUG_ON(ret); + + ret = btrfs_free_extent(trans, src, new_bytenr, blocksize, + path->nodes[level]->start, +- src->root_key.objectid, level - 1, 0, +- 1); ++ src->root_key.objectid, level - 1, 0); + BUG_ON(ret); + + ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize, + 0, dest->root_key.objectid, level - 1, +- 0, 1); ++ 0); + BUG_ON(ret); + + btrfs_unlock_up_safe(path, 0); +@@ -2745,7 +2743,7 @@ static int do_relocation(struct btrfs_tr + node->eb->start, blocksize, + upper->eb->start, + btrfs_header_owner(upper->eb), +- node->level, 0, 1); ++ node->level, 0); + BUG_ON(ret); + + ret = btrfs_drop_subtree(trans, root, eb, upper->eb); +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -691,7 +691,7 @@ static noinline int replay_one_extent(st + ret = btrfs_inc_extent_ref(trans, root, + ins.objectid, ins.offset, + 0, root->root_key.objectid, +- key->objectid, offset, 0); ++ key->objectid, offset); + if (ret) + goto out; + } else { diff --git a/queue-4.3/ext4-crypto-fix-bugs-in-ext4_encrypted_zeroout.patch b/queue-4.3/ext4-crypto-fix-bugs-in-ext4_encrypted_zeroout.patch index 09eb7405fac..5d79ad054b8 100644 --- a/queue-4.3/ext4-crypto-fix-bugs-in-ext4_encrypted_zeroout.patch +++ b/queue-4.3/ext4-crypto-fix-bugs-in-ext4_encrypted_zeroout.patch @@ -31,7 +31,7 @@ Signed-off-by: Greg Kroah-Hartman --- a/fs/ext4/crypto.c +++ b/fs/ext4/crypto.c -@@ -410,7 +410,13 @@ int ext4_encrypted_zeroout(struct inode +@@ -411,7 +411,13 @@ int ext4_encrypted_zeroout(struct inode ext4_lblk_t lblk = ex->ee_block; ext4_fsblk_t pblk = ext4_ext_pblock(ex); unsigned int len = ext4_ext_get_actual_len(ex); @@ -46,7 +46,7 @@ Signed-off-by: Greg Kroah-Hartman BUG_ON(inode->i_sb->s_blocksize != PAGE_CACHE_SIZE); -@@ -436,17 +442,26 @@ int ext4_encrypted_zeroout(struct inode +@@ -437,17 +443,26 @@ int ext4_encrypted_zeroout(struct inode goto errout; } bio->bi_bdev = inode->i_sb->s_bdev; diff --git a/queue-4.3/ext4-crypto-replace-some-bug_on-s-with-error-checks.patch b/queue-4.3/ext4-crypto-replace-some-bug_on-s-with-error-checks.patch deleted file mode 100644 index 2a2d30891e9..00000000000 --- a/queue-4.3/ext4-crypto-replace-some-bug_on-s-with-error-checks.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 687c3c36e754a999a8263745b27965128db4fee5 Mon Sep 17 00:00:00 2001 -From: Theodore Ts'o -Date: Sat, 3 Oct 2015 10:49:27 -0400 -Subject: ext4 crypto: replace some BUG_ON()'s with error checks - -From: Theodore Ts'o - -commit 687c3c36e754a999a8263745b27965128db4fee5 upstream. - -Buggy (or hostile) userspace should not be able to cause the kernel to -crash. - -Signed-off-by: Theodore Ts'o -Signed-off-by: Greg Kroah-Hartman - ---- - fs/ext4/crypto.c | 1 - - fs/ext4/crypto_fname.c | 2 -- - fs/ext4/crypto_key.c | 16 +++++++++++++--- - fs/ext4/crypto_policy.c | 3 ++- - 4 files changed, 15 insertions(+), 7 deletions(-) - ---- a/fs/ext4/crypto.c -+++ b/fs/ext4/crypto.c -@@ -296,7 +296,6 @@ static int ext4_page_crypto(struct ext4_ - else - res = crypto_ablkcipher_encrypt(req); - if (res == -EINPROGRESS || res == -EBUSY) { -- BUG_ON(req->base.data != &ecr); - wait_for_completion(&ecr.completion); - res = ecr.res; - } ---- a/fs/ext4/crypto_fname.c -+++ b/fs/ext4/crypto_fname.c -@@ -120,7 +120,6 @@ static int ext4_fname_encrypt(struct ino - ablkcipher_request_set_crypt(req, &src_sg, &dst_sg, ciphertext_len, iv); - res = crypto_ablkcipher_encrypt(req); - if (res == -EINPROGRESS || res == -EBUSY) { -- BUG_ON(req->base.data != &ecr); - wait_for_completion(&ecr.completion); - res = ecr.res; - } -@@ -182,7 +181,6 @@ static int ext4_fname_decrypt(struct ino - ablkcipher_request_set_crypt(req, &src_sg, &dst_sg, iname->len, iv); - res = crypto_ablkcipher_decrypt(req); - if (res == -EINPROGRESS || res == -EBUSY) { -- BUG_ON(req->base.data != &ecr); - wait_for_completion(&ecr.completion); - res = ecr.res; - } ---- a/fs/ext4/crypto_key.c -+++ b/fs/ext4/crypto_key.c -@@ -71,7 +71,6 @@ static int ext4_derive_key_aes(char deri - EXT4_AES_256_XTS_KEY_SIZE, NULL); - res = crypto_ablkcipher_encrypt(req); - if (res == -EINPROGRESS || res == -EBUSY) { -- BUG_ON(req->base.data != &ecr); - wait_for_completion(&ecr.completion); - res = ecr.res; - } -@@ -208,7 +207,12 @@ retry: - goto out; - } - crypt_info->ci_keyring_key = keyring_key; -- BUG_ON(keyring_key->type != &key_type_logon); -+ if (keyring_key->type != &key_type_logon) { -+ printk_once(KERN_WARNING -+ "ext4: key type must be logon\n"); -+ res = -ENOKEY; -+ goto out; -+ } - ukp = ((struct user_key_payload *)keyring_key->payload.data); - if (ukp->datalen != sizeof(struct ext4_encryption_key)) { - res = -EINVAL; -@@ -217,7 +221,13 @@ retry: - master_key = (struct ext4_encryption_key *)ukp->data; - BUILD_BUG_ON(EXT4_AES_128_ECB_KEY_SIZE != - EXT4_KEY_DERIVATION_NONCE_SIZE); -- BUG_ON(master_key->size != EXT4_AES_256_XTS_KEY_SIZE); -+ if (master_key->size != EXT4_AES_256_XTS_KEY_SIZE) { -+ printk_once(KERN_WARNING -+ "ext4: key size incorrect: %d\n", -+ master_key->size); -+ res = -ENOKEY; -+ goto out; -+ } - res = ext4_derive_key_aes(ctx.nonce, master_key->raw, - raw_key); - if (res) ---- a/fs/ext4/crypto_policy.c -+++ b/fs/ext4/crypto_policy.c -@@ -150,7 +150,8 @@ int ext4_is_child_context_consistent_wit - - if ((parent == NULL) || (child == NULL)) { - pr_err("parent %p child %p\n", parent, child); -- BUG_ON(1); -+ WARN_ON(1); /* Should never happen */ -+ return 0; - } - /* no restrictions if the parent directory is not encrypted */ - if (!ext4_encrypted_inode(parent)) diff --git a/queue-4.3/series b/queue-4.3/series index faf3dbfaa66..b48062baf1c 100644 --- a/queue-4.3/series +++ b/queue-4.3/series @@ -53,7 +53,6 @@ btrfs-fix-race-when-listing-an-inode-s-xattrs.patch btrfs-fix-signed-overflows-in-btrfs_sync_file.patch rbd-don-t-put-snap_context-twice-in-rbd_queue_workfn.patch ext4-crypto-fix-memory-leak-in-ext4_bio_write_page.patch -ext4-crypto-replace-some-bug_on-s-with-error-checks.patch ext4-crypto-fix-bugs-in-ext4_encrypted_zeroout.patch ext4-fix-potential-use-after-free-in-__ext4_journal_stop.patch ext4-jbd2-ensure-entering-into-panic-after-recording-an-error-in-superblock.patch @@ -70,3 +69,4 @@ ceph-fix-message-length-computation.patch alsa-pci-depend-on-zone_dma.patch alsa-hda-hdmi-apply-skylake-fix-ups-to-broxton-display-codec.patch cobalt-fix-kconfig-dependency.patch +btrfs-fix-regression-running-delayed-references-when-using-qgroups.patch -- 2.47.3