From: Greg Kroah-Hartman Date: Fri, 29 Mar 2019 16:45:46 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v3.18.138~60 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=92f6577da97964c558e57cbfad71fc0475d7043e;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: arm-imx6q-cpuidle-fix-bug-that-cpu-might-not-wake-up-at-expected-time.patch btrfs-fix-incorrect-file-size-after-shrinking-truncate-and-fsync.patch btrfs-raid56-properly-unmap-parity-page-in-finish_parity_scrub.patch btrfs-remove-warn_on-in-log_dir_items.patch --- diff --git a/queue-4.4/arm-imx6q-cpuidle-fix-bug-that-cpu-might-not-wake-up-at-expected-time.patch b/queue-4.4/arm-imx6q-cpuidle-fix-bug-that-cpu-might-not-wake-up-at-expected-time.patch new file mode 100644 index 00000000000..33b6f9ccd83 --- /dev/null +++ b/queue-4.4/arm-imx6q-cpuidle-fix-bug-that-cpu-might-not-wake-up-at-expected-time.patch @@ -0,0 +1,76 @@ +From 91740fc8242b4f260cfa4d4536d8551804777fae Mon Sep 17 00:00:00 2001 +From: Kohji Okuno +Date: Tue, 26 Feb 2019 11:34:13 +0900 +Subject: ARM: imx6q: cpuidle: fix bug that CPU might not wake up at expected time + +From: Kohji Okuno + +commit 91740fc8242b4f260cfa4d4536d8551804777fae upstream. + +In the current cpuidle implementation for i.MX6q, the CPU that sets +'WAIT_UNCLOCKED' and the CPU that returns to 'WAIT_CLOCKED' are always +the same. While the CPU that sets 'WAIT_UNCLOCKED' is in IDLE state of +"WAIT", if the other CPU wakes up and enters IDLE state of "WFI" +istead of "WAIT", this CPU can not wake up at expired time. + Because, in the case of "WFI", the CPU must be waked up by the local +timer interrupt. But, while 'WAIT_UNCLOCKED' is set, the local timer +is stopped, when all CPUs execute "wfi" instruction. As a result, the +local timer interrupt is not fired. + In this situation, this CPU will wake up by IRQ different from local +timer. (e.g. broacast timer) + +So, this fix changes CPU to return to 'WAIT_CLOCKED'. + +Signed-off-by: Kohji Okuno +Fixes: e5f9dec8ff5f ("ARM: imx6q: support WAIT mode using cpuidle") +Cc: +Signed-off-by: Shawn Guo +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mach-imx/cpuidle-imx6q.c | 27 ++++++++++----------------- + 1 file changed, 10 insertions(+), 17 deletions(-) + +--- a/arch/arm/mach-imx/cpuidle-imx6q.c ++++ b/arch/arm/mach-imx/cpuidle-imx6q.c +@@ -14,30 +14,23 @@ + #include "cpuidle.h" + #include "hardware.h" + +-static atomic_t master = ATOMIC_INIT(0); +-static DEFINE_SPINLOCK(master_lock); ++static int num_idle_cpus = 0; ++static DEFINE_SPINLOCK(cpuidle_lock); + + static int imx6q_enter_wait(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) + { +- if (atomic_inc_return(&master) == num_online_cpus()) { +- /* +- * With this lock, we prevent other cpu to exit and enter +- * this function again and become the master. +- */ +- if (!spin_trylock(&master_lock)) +- goto idle; ++ spin_lock(&cpuidle_lock); ++ if (++num_idle_cpus == num_online_cpus()) + imx6_set_lpm(WAIT_UNCLOCKED); +- cpu_do_idle(); +- imx6_set_lpm(WAIT_CLOCKED); +- spin_unlock(&master_lock); +- goto done; +- } ++ spin_unlock(&cpuidle_lock); + +-idle: + cpu_do_idle(); +-done: +- atomic_dec(&master); ++ ++ spin_lock(&cpuidle_lock); ++ if (num_idle_cpus-- == num_online_cpus()) ++ imx6_set_lpm(WAIT_CLOCKED); ++ spin_unlock(&cpuidle_lock); + + return index; + } diff --git a/queue-4.4/btrfs-fix-incorrect-file-size-after-shrinking-truncate-and-fsync.patch b/queue-4.4/btrfs-fix-incorrect-file-size-after-shrinking-truncate-and-fsync.patch new file mode 100644 index 00000000000..c7f05594fdb --- /dev/null +++ b/queue-4.4/btrfs-fix-incorrect-file-size-after-shrinking-truncate-and-fsync.patch @@ -0,0 +1,98 @@ +From bf504110bc8aa05df48b0e5f0aa84bfb81e0574b Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Mon, 4 Mar 2019 14:06:12 +0000 +Subject: Btrfs: fix incorrect file size after shrinking truncate and fsync + +From: Filipe Manana + +commit bf504110bc8aa05df48b0e5f0aa84bfb81e0574b upstream. + +If we do a shrinking truncate against an inode which is already present +in the respective log tree and then rename it, as part of logging the new +name we end up logging an inode item that reflects the old size of the +file (the one which we previously logged) and not the new smaller size. +The decision to preserve the size previously logged was added by commit +1a4bcf470c886b ("Btrfs: fix fsync data loss after adding hard link to +inode") in order to avoid data loss after replaying the log. However that +decision is only needed for the case the logged inode size is smaller then +the current size of the inode, as explained in that commit's change log. +If the current size of the inode is smaller then the previously logged +size, we know a shrinking truncate happened and therefore need to use +that smaller size. + +Example to trigger the problem: + + $ mkfs.btrfs -f /dev/sdb + $ mount /dev/sdb /mnt + + $ xfs_io -f -c "pwrite -S 0xab 0 8000" /mnt/foo + $ xfs_io -c "fsync" /mnt/foo + $ xfs_io -c "truncate 3000" /mnt/foo + + $ mv /mnt/foo /mnt/bar + $ xfs_io -c "fsync" /mnt/bar + + + + $ mount /dev/sdb /mnt + $ od -t x1 -A d /mnt/bar + 0000000 ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab + * + 0008000 + +Once we rename the file, we log its name (and inode item), and because +the inode was already logged before in the current transaction, we log it +with a size of 8000 bytes because that is the size we previously logged +(with the first fsync). As part of the rename, besides logging the inode, +we do also sync the log, which is done since commit d4682ba03ef618 +("Btrfs: sync log after logging new name"), so the next fsync against our +inode is effectively a no-op, since no new changes happened since the +rename operation. Even if did not sync the log during the rename +operation, the same problem (fize size of 8000 bytes instead of 3000 +bytes) would be visible after replaying the log if the log ended up +getting synced to disk through some other means, such as for example by +fsyncing some other modified file. In the example above the fsync after +the rename operation is there just because not every filesystem may +guarantee logging/journalling the inode (and syncing the log/journal) +during the rename operation, for example it is needed for f2fs, but not +for ext4 and xfs. + +Fix this scenario by, when logging a new name (which is triggered by +rename and link operations), using the current size of the inode instead +of the previously logged inode size. + +A test case for fstests follows soon. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=202695 +CC: stable@vger.kernel.org # 4.4+ +Reported-by: Seulbae Kim +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/tree-log.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -4233,6 +4233,19 @@ static int logged_inode_size(struct btrf + item = btrfs_item_ptr(path->nodes[0], path->slots[0], + struct btrfs_inode_item); + *size_ret = btrfs_inode_size(path->nodes[0], item); ++ /* ++ * If the in-memory inode's i_size is smaller then the inode ++ * size stored in the btree, return the inode's i_size, so ++ * that we get a correct inode size after replaying the log ++ * when before a power failure we had a shrinking truncate ++ * followed by addition of a new name (rename / new hard link). ++ * Otherwise return the inode size from the btree, to avoid ++ * data loss when replaying a log due to previously doing a ++ * write that expands the inode's size and logging a new name ++ * immediately after. ++ */ ++ if (*size_ret > inode->vfs_inode.i_size) ++ *size_ret = inode->vfs_inode.i_size; + } + + btrfs_release_path(path); diff --git a/queue-4.4/btrfs-raid56-properly-unmap-parity-page-in-finish_parity_scrub.patch b/queue-4.4/btrfs-raid56-properly-unmap-parity-page-in-finish_parity_scrub.patch new file mode 100644 index 00000000000..690e898b680 --- /dev/null +++ b/queue-4.4/btrfs-raid56-properly-unmap-parity-page-in-finish_parity_scrub.patch @@ -0,0 +1,57 @@ +From 3897b6f0a859288c22fb793fad11ec2327e60fcd Mon Sep 17 00:00:00 2001 +From: Andrea Righi +Date: Thu, 14 Mar 2019 08:56:28 +0100 +Subject: btrfs: raid56: properly unmap parity page in finish_parity_scrub() + +From: Andrea Righi + +commit 3897b6f0a859288c22fb793fad11ec2327e60fcd upstream. + +Parity page is incorrectly unmapped in finish_parity_scrub(), triggering +a reference counter bug on i386, i.e.: + + [ 157.662401] kernel BUG at mm/highmem.c:349! + [ 157.666725] invalid opcode: 0000 [#1] SMP PTI + +The reason is that kunmap(p_page) was completely left out, so we never +did an unmap for the p_page and the loop unmapping the rbio page was +iterating over the wrong number of stripes: unmapping should be done +with nr_data instead of rbio->real_stripes. + +Test case to reproduce the bug: + + - create a raid5 btrfs filesystem: + # mkfs.btrfs -m raid5 -d raid5 /dev/sdb /dev/sdc /dev/sdd /dev/sde + + - mount it: + # mount /dev/sdb /mnt + + - run btrfs scrub in a loop: + # while :; do btrfs scrub start -BR /mnt; done + +BugLink: https://bugs.launchpad.net/bugs/1812845 +Fixes: 5a6ac9eacb49 ("Btrfs, raid56: support parity scrub on raid56") +CC: stable@vger.kernel.org # 4.4+ +Reviewed-by: Johannes Thumshirn +Signed-off-by: Andrea Righi +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/raid56.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/raid56.c ++++ b/fs/btrfs/raid56.c +@@ -2420,8 +2420,9 @@ static noinline void finish_parity_scrub + bitmap_clear(rbio->dbitmap, pagenr, 1); + kunmap(p); + +- for (stripe = 0; stripe < rbio->real_stripes; stripe++) ++ for (stripe = 0; stripe < nr_data; stripe++) + kunmap(page_in_rbio(rbio, stripe, pagenr, 0)); ++ kunmap(p_page); + } + + __free_page(p_page); diff --git a/queue-4.4/btrfs-remove-warn_on-in-log_dir_items.patch b/queue-4.4/btrfs-remove-warn_on-in-log_dir_items.patch new file mode 100644 index 00000000000..d099c778e12 --- /dev/null +++ b/queue-4.4/btrfs-remove-warn_on-in-log_dir_items.patch @@ -0,0 +1,50 @@ +From 2cc8334270e281815c3850c3adea363c51f21e0d Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Wed, 6 Mar 2019 17:13:04 -0500 +Subject: btrfs: remove WARN_ON in log_dir_items + +From: Josef Bacik + +commit 2cc8334270e281815c3850c3adea363c51f21e0d upstream. + +When Filipe added the recursive directory logging stuff in +2f2ff0ee5e430 ("Btrfs: fix metadata inconsistencies after directory +fsync") he specifically didn't take the directory i_mutex for the +children directories that we need to log because of lockdep. This is +generally fine, but can lead to this WARN_ON() tripping if we happen to +run delayed deletion's in between our first search and our second search +of dir_item/dir_indexes for this directory. We expect this to happen, +so the WARN_ON() isn't necessary. Drop the WARN_ON() and add a comment +so we know why this case can happen. + +CC: stable@vger.kernel.org # 4.4+ +Reviewed-by: Filipe Manana +Signed-off-by: Josef Bacik +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/tree-log.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -3321,9 +3321,16 @@ static noinline int log_dir_items(struct + } + btrfs_release_path(path); + +- /* find the first key from this transaction again */ ++ /* ++ * Find the first key from this transaction again. See the note for ++ * log_new_dir_dentries, if we're logging a directory recursively we ++ * won't be holding its i_mutex, which means we can modify the directory ++ * while we're logging it. If we remove an entry between our first ++ * search and this search we'll not find the key again and can just ++ * bail. ++ */ + ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0); +- if (WARN_ON(ret != 0)) ++ if (ret != 0) + goto done; + + /* diff --git a/queue-4.4/series b/queue-4.4/series index 884909c7956..42555f80b6c 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -97,3 +97,7 @@ tcp-do-not-use-ipv6-header-for-ipv4-flow.patch vxlan-don-t-call-gro_cells_destroy-before-device-is-unregistered.patch sctp-get-sctphdr-by-offset-in-sctp_compute_cksum.patch mac8390-fix-mmio-access-size-probe.patch +btrfs-fix-incorrect-file-size-after-shrinking-truncate-and-fsync.patch +btrfs-remove-warn_on-in-log_dir_items.patch +btrfs-raid56-properly-unmap-parity-page-in-finish_parity_scrub.patch +arm-imx6q-cpuidle-fix-bug-that-cpu-might-not-wake-up-at-expected-time.patch