From: Greg Kroah-Hartman Date: Mon, 21 May 2018 07:05:54 +0000 (+0200) Subject: lots of broken btrfs patches dropped X-Git-Tag: v4.9.102~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3919e207d4a807b3910dd16c4df613e78b0f5399;p=thirdparty%2Fkernel%2Fstable-queue.git lots of broken btrfs patches dropped --- diff --git a/queue-4.14/btrfs-fix-delalloc-inodes-invalidation-during-transaction-abort.patch b/queue-4.14/btrfs-fix-delalloc-inodes-invalidation-during-transaction-abort.patch deleted file mode 100644 index ee15a679ab9..00000000000 --- a/queue-4.14/btrfs-fix-delalloc-inodes-invalidation-during-transaction-abort.patch +++ /dev/null @@ -1,131 +0,0 @@ -From fe816d0f1d4c31c4c31d42ca78a87660565fc800 Mon Sep 17 00:00:00 2001 -From: Nikolay Borisov -Date: Fri, 27 Apr 2018 12:21:53 +0300 -Subject: btrfs: Fix delalloc inodes invalidation during transaction abort - -From: Nikolay Borisov - -commit fe816d0f1d4c31c4c31d42ca78a87660565fc800 upstream. - -When a transaction is aborted btrfs_cleanup_transaction is called to -cleanup all the various in-flight bits and pieces which migth be -active. One of those is delalloc inodes - inodes which have dirty -pages which haven't been persisted yet. Currently the process of -freeing such delalloc inodes in exceptional circumstances such as -transaction abort boiled down to calling btrfs_invalidate_inodes whose -sole job is to invalidate the dentries for all inodes related to a -root. This is in fact wrong and insufficient since such delalloc inodes -will likely have pending pages or ordered-extents and will be linked to -the sb->s_inode_list. This means that unmounting a btrfs instance with -an aborted transaction could potentially lead inodes/their pages -visible to the system long after their superblock has been freed. This -in turn leads to a "use-after-free" situation once page shrink is -triggered. This situation could be simulated by running generic/019 -which would cause such inodes to be left hanging, followed by -generic/176 which causes memory pressure and page eviction which lead -to touching the freed super block instance. This situation is -additionally detected by the unmount code of VFS with the following -message: - -"VFS: Busy inodes after unmount of Self-destruct in 5 seconds. Have a nice day..." - -Additionally btrfs hits WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); -in free_fs_root for the same reason. - -This patch aims to rectify the sitaution by doing the following: - -1. Change btrfs_destroy_delalloc_inodes so that it calls -invalidate_inode_pages2 for every inode on the delalloc list, this -ensures that all the pages of the inode are released. This function -boils down to calling btrfs_releasepage. During test I observed cases -where inodes on the delalloc list were having an i_count of 0, so this -necessitates using igrab to be sure we are working on a non-freed inode. - -2. Since calling btrfs_releasepage might queue delayed iputs move the -call out to btrfs_cleanup_transaction in btrfs_error_commit_super before -calling run_delayed_iputs for the last time. This is necessary to ensure -that delayed iputs are run. - -Note: this patch is tagged for 4.14 stable but the fix applies to older -versions too but needs to be backported manually due to conflicts. - -CC: stable@vger.kernel.org # 4.14.x: 2b8773313494: btrfs: Split btrfs_del_delalloc_inode into 2 functions -CC: stable@vger.kernel.org # 4.14.x -Signed-off-by: Nikolay Borisov -Reviewed-by: David Sterba -[ add comment to igrab ] -Signed-off-by: David Sterba -Signed-off-by: Greg Kroah-Hartman - ---- - fs/btrfs/disk-io.c | 26 +++++++++++++++----------- - 1 file changed, 15 insertions(+), 11 deletions(-) - ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -3905,6 +3905,7 @@ void close_ctree(struct btrfs_fs_info *f - set_bit(BTRFS_FS_CLOSING_DONE, &fs_info->flags); - - btrfs_free_qgroup_config(fs_info); -+ ASSERT(list_empty(&fs_info->delalloc_roots)); - - if (percpu_counter_sum(&fs_info->delalloc_bytes)) { - btrfs_info(fs_info, "at unmount delalloc count %lld", -@@ -4203,15 +4204,15 @@ static int btrfs_check_super_valid(struc - - static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info) - { -+ /* cleanup FS via transaction */ -+ btrfs_cleanup_transaction(fs_info); -+ - mutex_lock(&fs_info->cleaner_mutex); - btrfs_run_delayed_iputs(fs_info); - mutex_unlock(&fs_info->cleaner_mutex); - - down_write(&fs_info->cleanup_work_sem); - up_write(&fs_info->cleanup_work_sem); -- -- /* cleanup FS via transaction */ -- btrfs_cleanup_transaction(fs_info); - } - - static void btrfs_destroy_ordered_extents(struct btrfs_root *root) -@@ -4334,19 +4335,23 @@ static void btrfs_destroy_delalloc_inode - list_splice_init(&root->delalloc_inodes, &splice); - - while (!list_empty(&splice)) { -+ struct inode *inode = NULL; - btrfs_inode = list_first_entry(&splice, struct btrfs_inode, - delalloc_inodes); -- -- list_del_init(&btrfs_inode->delalloc_inodes); -- clear_bit(BTRFS_INODE_IN_DELALLOC_LIST, -- &btrfs_inode->runtime_flags); -+ __btrfs_del_delalloc_inode(root, btrfs_inode); - spin_unlock(&root->delalloc_lock); - -- btrfs_invalidate_inodes(btrfs_inode->root); -- -+ /* -+ * Make sure we get a live inode and that it'll not disappear -+ * meanwhile. -+ */ -+ inode = igrab(&btrfs_inode->vfs_inode); -+ if (inode) { -+ invalidate_inode_pages2(inode->i_mapping); -+ iput(inode); -+ } - spin_lock(&root->delalloc_lock); - } -- - spin_unlock(&root->delalloc_lock); - } - -@@ -4362,7 +4367,6 @@ static void btrfs_destroy_all_delalloc_i - while (!list_empty(&splice)) { - root = list_first_entry(&splice, struct btrfs_root, - delalloc_root); -- list_del_init(&root->delalloc_root); - root = btrfs_grab_fs_root(root); - BUG_ON(!root); - spin_unlock(&fs_info->delalloc_root_lock); diff --git a/queue-4.14/series b/queue-4.14/series index 92236ae9b34..d9d590b6be5 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -38,7 +38,6 @@ tick-broadcast-use-for_each_cpu-specially-on-up-kernels.patch arm-8769-1-kprobes-fix-to-use-get_kprobe_ctlblk-after-irq-disabed.patch arm-8770-1-kprobes-prohibit-probing-on-optimized_callback.patch arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch -btrfs-fix-delalloc-inodes-invalidation-during-transaction-abort.patch btrfs-fix-xattr-loss-after-power-failure.patch btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch btrfs-property-set-incompat-flag-if-lzo-zstd-compression-is-set.patch diff --git a/queue-4.16/btrfs-fix-delalloc-inodes-invalidation-during-transaction-abort.patch b/queue-4.16/btrfs-fix-delalloc-inodes-invalidation-during-transaction-abort.patch deleted file mode 100644 index 939bf88b487..00000000000 --- a/queue-4.16/btrfs-fix-delalloc-inodes-invalidation-during-transaction-abort.patch +++ /dev/null @@ -1,131 +0,0 @@ -From fe816d0f1d4c31c4c31d42ca78a87660565fc800 Mon Sep 17 00:00:00 2001 -From: Nikolay Borisov -Date: Fri, 27 Apr 2018 12:21:53 +0300 -Subject: btrfs: Fix delalloc inodes invalidation during transaction abort - -From: Nikolay Borisov - -commit fe816d0f1d4c31c4c31d42ca78a87660565fc800 upstream. - -When a transaction is aborted btrfs_cleanup_transaction is called to -cleanup all the various in-flight bits and pieces which migth be -active. One of those is delalloc inodes - inodes which have dirty -pages which haven't been persisted yet. Currently the process of -freeing such delalloc inodes in exceptional circumstances such as -transaction abort boiled down to calling btrfs_invalidate_inodes whose -sole job is to invalidate the dentries for all inodes related to a -root. This is in fact wrong and insufficient since such delalloc inodes -will likely have pending pages or ordered-extents and will be linked to -the sb->s_inode_list. This means that unmounting a btrfs instance with -an aborted transaction could potentially lead inodes/their pages -visible to the system long after their superblock has been freed. This -in turn leads to a "use-after-free" situation once page shrink is -triggered. This situation could be simulated by running generic/019 -which would cause such inodes to be left hanging, followed by -generic/176 which causes memory pressure and page eviction which lead -to touching the freed super block instance. This situation is -additionally detected by the unmount code of VFS with the following -message: - -"VFS: Busy inodes after unmount of Self-destruct in 5 seconds. Have a nice day..." - -Additionally btrfs hits WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); -in free_fs_root for the same reason. - -This patch aims to rectify the sitaution by doing the following: - -1. Change btrfs_destroy_delalloc_inodes so that it calls -invalidate_inode_pages2 for every inode on the delalloc list, this -ensures that all the pages of the inode are released. This function -boils down to calling btrfs_releasepage. During test I observed cases -where inodes on the delalloc list were having an i_count of 0, so this -necessitates using igrab to be sure we are working on a non-freed inode. - -2. Since calling btrfs_releasepage might queue delayed iputs move the -call out to btrfs_cleanup_transaction in btrfs_error_commit_super before -calling run_delayed_iputs for the last time. This is necessary to ensure -that delayed iputs are run. - -Note: this patch is tagged for 4.14 stable but the fix applies to older -versions too but needs to be backported manually due to conflicts. - -CC: stable@vger.kernel.org # 4.14.x: 2b8773313494: btrfs: Split btrfs_del_delalloc_inode into 2 functions -CC: stable@vger.kernel.org # 4.14.x -Signed-off-by: Nikolay Borisov -Reviewed-by: David Sterba -[ add comment to igrab ] -Signed-off-by: David Sterba -Signed-off-by: Greg Kroah-Hartman - ---- - fs/btrfs/disk-io.c | 26 +++++++++++++++----------- - 1 file changed, 15 insertions(+), 11 deletions(-) - ---- a/fs/btrfs/disk-io.c -+++ b/fs/btrfs/disk-io.c -@@ -3744,6 +3744,7 @@ void close_ctree(struct btrfs_fs_info *f - set_bit(BTRFS_FS_CLOSING_DONE, &fs_info->flags); - - btrfs_free_qgroup_config(fs_info); -+ ASSERT(list_empty(&fs_info->delalloc_roots)); - - if (percpu_counter_sum(&fs_info->delalloc_bytes)) { - btrfs_info(fs_info, "at unmount delalloc count %lld", -@@ -4049,15 +4050,15 @@ static int btrfs_check_super_valid(struc - - static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info) - { -+ /* cleanup FS via transaction */ -+ btrfs_cleanup_transaction(fs_info); -+ - mutex_lock(&fs_info->cleaner_mutex); - btrfs_run_delayed_iputs(fs_info); - mutex_unlock(&fs_info->cleaner_mutex); - - down_write(&fs_info->cleanup_work_sem); - up_write(&fs_info->cleanup_work_sem); -- -- /* cleanup FS via transaction */ -- btrfs_cleanup_transaction(fs_info); - } - - static void btrfs_destroy_ordered_extents(struct btrfs_root *root) -@@ -4182,19 +4183,23 @@ static void btrfs_destroy_delalloc_inode - list_splice_init(&root->delalloc_inodes, &splice); - - while (!list_empty(&splice)) { -+ struct inode *inode = NULL; - btrfs_inode = list_first_entry(&splice, struct btrfs_inode, - delalloc_inodes); -- -- list_del_init(&btrfs_inode->delalloc_inodes); -- clear_bit(BTRFS_INODE_IN_DELALLOC_LIST, -- &btrfs_inode->runtime_flags); -+ __btrfs_del_delalloc_inode(root, btrfs_inode); - spin_unlock(&root->delalloc_lock); - -- btrfs_invalidate_inodes(btrfs_inode->root); -- -+ /* -+ * Make sure we get a live inode and that it'll not disappear -+ * meanwhile. -+ */ -+ inode = igrab(&btrfs_inode->vfs_inode); -+ if (inode) { -+ invalidate_inode_pages2(inode->i_mapping); -+ iput(inode); -+ } - spin_lock(&root->delalloc_lock); - } -- - spin_unlock(&root->delalloc_lock); - } - -@@ -4210,7 +4215,6 @@ static void btrfs_destroy_all_delalloc_i - while (!list_empty(&splice)) { - root = list_first_entry(&splice, struct btrfs_root, - delalloc_root); -- list_del_init(&root->delalloc_root); - root = btrfs_grab_fs_root(root); - BUG_ON(!root); - spin_unlock(&fs_info->delalloc_root_lock); diff --git a/queue-4.16/series b/queue-4.16/series index b72f836aa0a..066ff25d780 100644 --- a/queue-4.16/series +++ b/queue-4.16/series @@ -52,7 +52,6 @@ tick-broadcast-use-for_each_cpu-specially-on-up-kernels.patch arm-8769-1-kprobes-fix-to-use-get_kprobe_ctlblk-after-irq-disabed.patch arm-8770-1-kprobes-prohibit-probing-on-optimized_callback.patch arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch -btrfs-fix-delalloc-inodes-invalidation-during-transaction-abort.patch btrfs-fix-xattr-loss-after-power-failure.patch btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch btrfs-property-set-incompat-flag-if-lzo-zstd-compression-is-set.patch diff --git a/queue-4.4/btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch b/queue-4.4/btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch deleted file mode 100644 index 5053fe82e43..00000000000 --- a/queue-4.4/btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 6f2f0b394b54e2b159ef969a0b5274e9bbf82ff2 Mon Sep 17 00:00:00 2001 -From: Robbie Ko -Date: Mon, 14 May 2018 10:51:34 +0800 -Subject: Btrfs: send, fix invalid access to commit roots due to concurrent snapshotting - -From: Robbie Ko - -commit 6f2f0b394b54e2b159ef969a0b5274e9bbf82ff2 upstream. - -[BUG] -btrfs incremental send BUG happens when creating a snapshot of snapshot -that is being used by send. - -[REASON] -The problem can happen if while we are doing a send one of the snapshots -used (parent or send) is snapshotted, because snapshoting implies COWing -the root of the source subvolume/snapshot. - -1. When doing an incremental send, the send process will get the commit - roots from the parent and send snapshots, and add references to them - through extent_buffer_get(). - -2. When a snapshot/subvolume is snapshotted, its root node is COWed - (transaction.c:create_pending_snapshot()). - -3. COWing releases the space used by the node immediately, through: - - __btrfs_cow_block() - --btrfs_free_tree_block() - ----btrfs_add_free_space(bytenr of node) - -4. Because send doesn't hold a transaction open, it's possible that - the transaction used to create the snapshot commits, switches the - commit root and the old space used by the previous root node gets - assigned to some other node allocation. Allocation of a new node will - use the existing extent buffer found in memory, which we previously - got a reference through extent_buffer_get(), and allow the extent - buffer's content (pages) to be modified: - - btrfs_alloc_tree_block - --btrfs_reserve_extent - ----find_free_extent (get bytenr of old node) - --btrfs_init_new_buffer (use bytenr of old node) - ----btrfs_find_create_tree_block - ------alloc_extent_buffer - --------find_extent_buffer (get old node) - -5. So send can access invalid memory content and have unpredictable - behaviour. - -[FIX] -So we fix the problem by copying the commit roots of the send and -parent snapshots and use those copies. - -CallTrace looks like this: - ------------[ cut here ]------------ - kernel BUG at fs/btrfs/ctree.c:1861! - invalid opcode: 0000 [#1] SMP - CPU: 6 PID: 24235 Comm: btrfs Tainted: P O 3.10.105 #23721 - ffff88046652d680 ti: ffff88041b720000 task.ti: ffff88041b720000 - RIP: 0010:[] read_node_slot+0x108/0x110 [btrfs] - RSP: 0018:ffff88041b723b68 EFLAGS: 00010246 - RAX: ffff88043ca6b000 RBX: ffff88041b723c50 RCX: ffff880000000000 - RDX: 000000000000004c RSI: ffff880314b133f8 RDI: ffff880458b24000 - RBP: 0000000000000000 R08: 0000000000000001 R09: ffff88041b723c66 - R10: 0000000000000001 R11: 0000000000001000 R12: ffff8803f3e48890 - R13: ffff8803f3e48880 R14: ffff880466351800 R15: 0000000000000001 - FS: 00007f8c321dc8c0(0000) GS:ffff88047fcc0000(0000) - CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 - R2: 00007efd1006d000 CR3: 0000000213a24000 CR4: 00000000003407e0 - DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 - DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 - Stack: - ffff88041b723c50 ffff8803f3e48880 ffff8803f3e48890 ffff8803f3e48880 - ffff880466351800 0000000000000001 ffffffffa08dd9d7 ffff88041b723c50 - ffff8803f3e48880 ffff88041b723c66 ffffffffa08dde85 a9ff88042d2c4400 - Call Trace: - [] ? tree_move_down.isra.33+0x27/0x50 [btrfs] - [] ? tree_advance+0xb5/0xc0 [btrfs] - [] ? btrfs_compare_trees+0x2d4/0x760 [btrfs] - [] ? finish_inode_if_needed+0x870/0x870 [btrfs] - [] ? btrfs_ioctl_send+0xeda/0x1050 [btrfs] - [] ? btrfs_ioctl+0x1e3d/0x33f0 [btrfs] - [] ? handle_pte_fault+0x373/0x990 - [] ? atomic_notifier_call_chain+0x16/0x20 - [] ? set_task_cpu+0xb6/0x1d0 - [] ? handle_mm_fault+0x143/0x2a0 - [] ? __do_page_fault+0x1d0/0x500 - [] ? check_preempt_curr+0x57/0x90 - [] ? do_vfs_ioctl+0x4aa/0x990 - [] ? do_fork+0x113/0x3b0 - [] ? trace_hardirqs_off_thunk+0x3a/0x6c - [] ? SyS_ioctl+0x88/0xa0 - [] ? system_call_fastpath+0x16/0x1b - ---[ end trace 29576629ee80b2e1 ]--- - -Fixes: 7069830a9e38 ("Btrfs: add btrfs_compare_trees function") -CC: stable@vger.kernel.org # 3.6+ -Signed-off-by: Robbie Ko -Reviewed-by: Filipe Manana -Signed-off-by: David Sterba -Signed-off-by: Greg Kroah-Hartman - ---- - fs/btrfs/ctree.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - ---- a/fs/btrfs/ctree.c -+++ b/fs/btrfs/ctree.c -@@ -5415,12 +5415,24 @@ int btrfs_compare_trees(struct btrfs_roo - down_read(&left_root->fs_info->commit_root_sem); - left_level = btrfs_header_level(left_root->commit_root); - left_root_level = left_level; -- left_path->nodes[left_level] = left_root->commit_root; -+ left_path->nodes[left_level] = -+ btrfs_clone_extent_buffer(left_root->commit_root); -+ if (!left_path->nodes[left_level]) { -+ up_read(&fs_info->commit_root_sem); -+ ret = -ENOMEM; -+ goto out; -+ } - extent_buffer_get(left_path->nodes[left_level]); - - right_level = btrfs_header_level(right_root->commit_root); - right_root_level = right_level; -- right_path->nodes[right_level] = right_root->commit_root; -+ right_path->nodes[right_level] = -+ btrfs_clone_extent_buffer(right_root->commit_root); -+ if (!right_path->nodes[right_level]) { -+ up_read(&fs_info->commit_root_sem); -+ ret = -ENOMEM; -+ goto out; -+ } - extent_buffer_get(right_path->nodes[right_level]); - up_read(&left_root->fs_info->commit_root_sem); - diff --git a/queue-4.4/series b/queue-4.4/series index 5eb08a9c0ce..01196a32807 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -66,5 +66,4 @@ arm-8769-1-kprobes-fix-to-use-get_kprobe_ctlblk-after-irq-disabed.patch arm-8770-1-kprobes-prohibit-probing-on-optimized_callback.patch arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch btrfs-fix-xattr-loss-after-power-failure.patch -btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch btrfs-fix-crash-when-trying-to-resume-balance-without-the-resume-flag.patch diff --git a/queue-4.9/btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch b/queue-4.9/btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch deleted file mode 100644 index f2b8429dd08..00000000000 --- a/queue-4.9/btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 6f2f0b394b54e2b159ef969a0b5274e9bbf82ff2 Mon Sep 17 00:00:00 2001 -From: Robbie Ko -Date: Mon, 14 May 2018 10:51:34 +0800 -Subject: Btrfs: send, fix invalid access to commit roots due to concurrent snapshotting - -From: Robbie Ko - -commit 6f2f0b394b54e2b159ef969a0b5274e9bbf82ff2 upstream. - -[BUG] -btrfs incremental send BUG happens when creating a snapshot of snapshot -that is being used by send. - -[REASON] -The problem can happen if while we are doing a send one of the snapshots -used (parent or send) is snapshotted, because snapshoting implies COWing -the root of the source subvolume/snapshot. - -1. When doing an incremental send, the send process will get the commit - roots from the parent and send snapshots, and add references to them - through extent_buffer_get(). - -2. When a snapshot/subvolume is snapshotted, its root node is COWed - (transaction.c:create_pending_snapshot()). - -3. COWing releases the space used by the node immediately, through: - - __btrfs_cow_block() - --btrfs_free_tree_block() - ----btrfs_add_free_space(bytenr of node) - -4. Because send doesn't hold a transaction open, it's possible that - the transaction used to create the snapshot commits, switches the - commit root and the old space used by the previous root node gets - assigned to some other node allocation. Allocation of a new node will - use the existing extent buffer found in memory, which we previously - got a reference through extent_buffer_get(), and allow the extent - buffer's content (pages) to be modified: - - btrfs_alloc_tree_block - --btrfs_reserve_extent - ----find_free_extent (get bytenr of old node) - --btrfs_init_new_buffer (use bytenr of old node) - ----btrfs_find_create_tree_block - ------alloc_extent_buffer - --------find_extent_buffer (get old node) - -5. So send can access invalid memory content and have unpredictable - behaviour. - -[FIX] -So we fix the problem by copying the commit roots of the send and -parent snapshots and use those copies. - -CallTrace looks like this: - ------------[ cut here ]------------ - kernel BUG at fs/btrfs/ctree.c:1861! - invalid opcode: 0000 [#1] SMP - CPU: 6 PID: 24235 Comm: btrfs Tainted: P O 3.10.105 #23721 - ffff88046652d680 ti: ffff88041b720000 task.ti: ffff88041b720000 - RIP: 0010:[] read_node_slot+0x108/0x110 [btrfs] - RSP: 0018:ffff88041b723b68 EFLAGS: 00010246 - RAX: ffff88043ca6b000 RBX: ffff88041b723c50 RCX: ffff880000000000 - RDX: 000000000000004c RSI: ffff880314b133f8 RDI: ffff880458b24000 - RBP: 0000000000000000 R08: 0000000000000001 R09: ffff88041b723c66 - R10: 0000000000000001 R11: 0000000000001000 R12: ffff8803f3e48890 - R13: ffff8803f3e48880 R14: ffff880466351800 R15: 0000000000000001 - FS: 00007f8c321dc8c0(0000) GS:ffff88047fcc0000(0000) - CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 - R2: 00007efd1006d000 CR3: 0000000213a24000 CR4: 00000000003407e0 - DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 - DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 - Stack: - ffff88041b723c50 ffff8803f3e48880 ffff8803f3e48890 ffff8803f3e48880 - ffff880466351800 0000000000000001 ffffffffa08dd9d7 ffff88041b723c50 - ffff8803f3e48880 ffff88041b723c66 ffffffffa08dde85 a9ff88042d2c4400 - Call Trace: - [] ? tree_move_down.isra.33+0x27/0x50 [btrfs] - [] ? tree_advance+0xb5/0xc0 [btrfs] - [] ? btrfs_compare_trees+0x2d4/0x760 [btrfs] - [] ? finish_inode_if_needed+0x870/0x870 [btrfs] - [] ? btrfs_ioctl_send+0xeda/0x1050 [btrfs] - [] ? btrfs_ioctl+0x1e3d/0x33f0 [btrfs] - [] ? handle_pte_fault+0x373/0x990 - [] ? atomic_notifier_call_chain+0x16/0x20 - [] ? set_task_cpu+0xb6/0x1d0 - [] ? handle_mm_fault+0x143/0x2a0 - [] ? __do_page_fault+0x1d0/0x500 - [] ? check_preempt_curr+0x57/0x90 - [] ? do_vfs_ioctl+0x4aa/0x990 - [] ? do_fork+0x113/0x3b0 - [] ? trace_hardirqs_off_thunk+0x3a/0x6c - [] ? SyS_ioctl+0x88/0xa0 - [] ? system_call_fastpath+0x16/0x1b - ---[ end trace 29576629ee80b2e1 ]--- - -Fixes: 7069830a9e38 ("Btrfs: add btrfs_compare_trees function") -CC: stable@vger.kernel.org # 3.6+ -Signed-off-by: Robbie Ko -Reviewed-by: Filipe Manana -Signed-off-by: David Sterba -Signed-off-by: Greg Kroah-Hartman - ---- - fs/btrfs/ctree.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - ---- a/fs/btrfs/ctree.c -+++ b/fs/btrfs/ctree.c -@@ -5433,12 +5433,24 @@ int btrfs_compare_trees(struct btrfs_roo - down_read(&left_root->fs_info->commit_root_sem); - left_level = btrfs_header_level(left_root->commit_root); - left_root_level = left_level; -- left_path->nodes[left_level] = left_root->commit_root; -+ left_path->nodes[left_level] = -+ btrfs_clone_extent_buffer(left_root->commit_root); -+ if (!left_path->nodes[left_level]) { -+ up_read(&fs_info->commit_root_sem); -+ ret = -ENOMEM; -+ goto out; -+ } - extent_buffer_get(left_path->nodes[left_level]); - - right_level = btrfs_header_level(right_root->commit_root); - right_root_level = right_level; -- right_path->nodes[right_level] = right_root->commit_root; -+ right_path->nodes[right_level] = -+ btrfs_clone_extent_buffer(right_root->commit_root); -+ if (!right_path->nodes[right_level]) { -+ up_read(&fs_info->commit_root_sem); -+ ret = -ENOMEM; -+ goto out; -+ } - extent_buffer_get(right_path->nodes[right_level]); - up_read(&left_root->fs_info->commit_root_sem); - diff --git a/queue-4.9/series b/queue-4.9/series index 50756d677c1..18aa731d98c 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -30,5 +30,4 @@ arm-8769-1-kprobes-fix-to-use-get_kprobe_ctlblk-after-irq-disabed.patch arm-8770-1-kprobes-prohibit-probing-on-optimized_callback.patch arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch btrfs-fix-xattr-loss-after-power-failure.patch -btrfs-send-fix-invalid-access-to-commit-roots-due-to-concurrent-snapshotting.patch btrfs-fix-crash-when-trying-to-resume-balance-without-the-resume-flag.patch