From: Greg Kroah-Hartman Date: Wed, 16 Oct 2019 13:28:34 +0000 (-0700) Subject: 4.19-stable patches X-Git-Tag: v4.4.197~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fae69a17d9952d00fd0ffabcb2cb63e02da86810;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: btrfs-fix-incorrect-updating-of-log-root-tree.patch btrfs-fix-uninitialized-ret-in-ref-verify.patch mips-disable-loongson-mmi-instructions-for-kernel-build.patch mips-elf_hwcap-export-userspace-ases.patch nfs-fix-o_direct-accounting-of-number-of-bytes-read-written.patch --- diff --git a/queue-4.19/btrfs-fix-incorrect-updating-of-log-root-tree.patch b/queue-4.19/btrfs-fix-incorrect-updating-of-log-root-tree.patch new file mode 100644 index 00000000000..a7146ea064c --- /dev/null +++ b/queue-4.19/btrfs-fix-incorrect-updating-of-log-root-tree.patch @@ -0,0 +1,132 @@ +From 4203e968947071586a98b5314fd7ffdea3b4f971 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Mon, 30 Sep 2019 16:27:25 -0400 +Subject: btrfs: fix incorrect updating of log root tree + +From: Josef Bacik + +commit 4203e968947071586a98b5314fd7ffdea3b4f971 upstream. + +We've historically had reports of being unable to mount file systems +because the tree log root couldn't be read. Usually this is the "parent +transid failure", but could be any of the related errors, including +"fsid mismatch" or "bad tree block", depending on which block got +allocated. + +The modification of the individual log root items are serialized on the +per-log root root_mutex. This means that any modification to the +per-subvol log root_item is completely protected. + +However we update the root item in the log root tree outside of the log +root tree log_mutex. We do this in order to allow multiple subvolumes +to be updated in each log transaction. + +This is problematic however because when we are writing the log root +tree out we update the super block with the _current_ log root node +information. Since these two operations happen independently of each +other, you can end up updating the log root tree in between writing out +the dirty blocks and setting the super block to point at the current +root. + +This means we'll point at the new root node that hasn't been written +out, instead of the one we should be pointing at. Thus whatever garbage +or old block we end up pointing at complains when we mount the file +system later and try to replay the log. + +Fix this by copying the log's root item into a local root item copy. +Then once we're safely under the log_root_tree->log_mutex we update the +root item in the log_root_tree. This way we do not modify the +log_root_tree while we're committing it, fixing the problem. + +CC: stable@vger.kernel.org # 4.4+ +Reviewed-by: Chris Mason +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 | 36 +++++++++++++++++++++++++++--------- + 1 file changed, 27 insertions(+), 9 deletions(-) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -2860,7 +2860,8 @@ out: + * in the tree of log roots + */ + static int update_log_root(struct btrfs_trans_handle *trans, +- struct btrfs_root *log) ++ struct btrfs_root *log, ++ struct btrfs_root_item *root_item) + { + struct btrfs_fs_info *fs_info = log->fs_info; + int ret; +@@ -2868,10 +2869,10 @@ static int update_log_root(struct btrfs_ + if (log->log_transid == 1) { + /* insert root item on the first sync */ + ret = btrfs_insert_root(trans, fs_info->log_root_tree, +- &log->root_key, &log->root_item); ++ &log->root_key, root_item); + } else { + ret = btrfs_update_root(trans, fs_info->log_root_tree, +- &log->root_key, &log->root_item); ++ &log->root_key, root_item); + } + return ret; + } +@@ -2969,6 +2970,7 @@ int btrfs_sync_log(struct btrfs_trans_ha + struct btrfs_fs_info *fs_info = root->fs_info; + struct btrfs_root *log = root->log_root; + struct btrfs_root *log_root_tree = fs_info->log_root_tree; ++ struct btrfs_root_item new_root_item; + int log_transid = 0; + struct btrfs_log_ctx root_log_ctx; + struct blk_plug plug; +@@ -3032,18 +3034,26 @@ int btrfs_sync_log(struct btrfs_trans_ha + goto out; + } + ++ /* ++ * We _must_ update under the root->log_mutex in order to make sure we ++ * have a consistent view of the log root we are trying to commit at ++ * this moment. ++ * ++ * We _must_ copy this into a local copy, because we are not holding the ++ * log_root_tree->log_mutex yet. This is important because when we ++ * commit the log_root_tree we must have a consistent view of the ++ * log_root_tree when we update the super block to point at the ++ * log_root_tree bytenr. If we update the log_root_tree here we'll race ++ * with the commit and possibly point at the new block which we may not ++ * have written out. ++ */ + btrfs_set_root_node(&log->root_item, log->node); ++ memcpy(&new_root_item, &log->root_item, sizeof(new_root_item)); + + root->log_transid++; + log->log_transid = root->log_transid; + root->log_start_pid = 0; + /* +- * Update or create log root item under the root's log_mutex to prevent +- * races with concurrent log syncs that can lead to failure to update +- * log root item because it was not created yet. +- */ +- ret = update_log_root(trans, log); +- /* + * IO has been started, blocks of the log tree have WRITTEN flag set + * in their headers. new modifications of the log will be written to + * new positions. so it's safe to allow log writers to go in. +@@ -3063,6 +3073,14 @@ int btrfs_sync_log(struct btrfs_trans_ha + mutex_unlock(&log_root_tree->log_mutex); + + mutex_lock(&log_root_tree->log_mutex); ++ ++ /* ++ * Now we are safe to update the log_root_tree because we're under the ++ * log_mutex, and we're a current writer so we're holding the commit ++ * open until we drop the log_mutex. ++ */ ++ ret = update_log_root(trans, log, &new_root_item); ++ + if (atomic_dec_and_test(&log_root_tree->log_writers)) { + /* atomic_dec_and_test implies a barrier */ + cond_wake_up_nomb(&log_root_tree->log_writer_wait); diff --git a/queue-4.19/btrfs-fix-uninitialized-ret-in-ref-verify.patch b/queue-4.19/btrfs-fix-uninitialized-ret-in-ref-verify.patch new file mode 100644 index 00000000000..9d1fb929b06 --- /dev/null +++ b/queue-4.19/btrfs-fix-uninitialized-ret-in-ref-verify.patch @@ -0,0 +1,37 @@ +From c5f4987e86f6692fdb12533ea1fc7a7bb98e555a Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Wed, 2 Oct 2019 10:03:36 -0400 +Subject: btrfs: fix uninitialized ret in ref-verify + +From: Josef Bacik + +commit c5f4987e86f6692fdb12533ea1fc7a7bb98e555a upstream. + +Coverity caught a case where we could return with a uninitialized value +in ret in process_leaf. This is actually pretty likely because we could +very easily run into a block group item key and have a garbage value in +ret and think there was an errror. Fix this by initializing ret to 0. + +Reported-by: Colin Ian King +Fixes: fd708b81d972 ("Btrfs: add a extent ref verify tool") +CC: stable@vger.kernel.org # 4.19+ +Signed-off-by: Josef Bacik +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ref-verify.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/ref-verify.c ++++ b/fs/btrfs/ref-verify.c +@@ -511,7 +511,7 @@ static int process_leaf(struct btrfs_roo + struct btrfs_extent_data_ref *dref; + struct btrfs_shared_data_ref *sref; + u32 count; +- int i = 0, tree_block_level = 0, ret; ++ int i = 0, tree_block_level = 0, ret = 0; + struct btrfs_key key; + int nritems = btrfs_header_nritems(leaf); + diff --git a/queue-4.19/mips-disable-loongson-mmi-instructions-for-kernel-build.patch b/queue-4.19/mips-disable-loongson-mmi-instructions-for-kernel-build.patch new file mode 100644 index 00000000000..1ef092d71bd --- /dev/null +++ b/queue-4.19/mips-disable-loongson-mmi-instructions-for-kernel-build.patch @@ -0,0 +1,60 @@ +From 2f2b4fd674cadd8c6b40eb629e140a14db4068fd Mon Sep 17 00:00:00 2001 +From: Paul Burton +Date: Thu, 10 Oct 2019 18:54:03 +0000 +Subject: MIPS: Disable Loongson MMI instructions for kernel build +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paul Burton + +commit 2f2b4fd674cadd8c6b40eb629e140a14db4068fd upstream. + +GCC 9.x automatically enables support for Loongson MMI instructions when +using some -march= flags, and then errors out when -msoft-float is +specified with: + + cc1: error: ‘-mloongson-mmi’ must be used with ‘-mhard-float’ + +The kernel shouldn't be using these MMI instructions anyway, just as it +doesn't use floating point instructions. Explicitly disable them in +order to fix the build with GCC 9.x. + +Signed-off-by: Paul Burton +Fixes: 3702bba5eb4f ("MIPS: Loongson: Add GCC 4.4 support for Loongson2E") +Fixes: 6f7a251a259e ("MIPS: Loongson: Add basic Loongson 2F support") +Fixes: 5188129b8c9f ("MIPS: Loongson-3: Improve -march option and move it to Platform") +Cc: Huacai Chen +Cc: Jiaxun Yang +Cc: stable@vger.kernel.org # v2.6.32+ +Cc: linux-mips@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/loongson64/Platform | 4 ++++ + arch/mips/vdso/Makefile | 1 + + 2 files changed, 5 insertions(+) + +--- a/arch/mips/loongson64/Platform ++++ b/arch/mips/loongson64/Platform +@@ -43,6 +43,10 @@ else + $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) + endif + ++# Some -march= flags enable MMI instructions, and GCC complains about that ++# support being enabled alongside -msoft-float. Thus explicitly disable MMI. ++cflags-y += $(call cc-option,-mno-loongson-mmi) ++ + # + # Loongson Machines' Support + # +--- a/arch/mips/vdso/Makefile ++++ b/arch/mips/vdso/Makefile +@@ -9,6 +9,7 @@ ccflags-vdso := \ + $(filter -mmicromips,$(KBUILD_CFLAGS)) \ + $(filter -march=%,$(KBUILD_CFLAGS)) \ + $(filter -m%-float,$(KBUILD_CFLAGS)) \ ++ $(filter -mno-loongson-%,$(KBUILD_CFLAGS)) \ + -D__VDSO__ + + ifeq ($(cc-name),clang) diff --git a/queue-4.19/mips-elf_hwcap-export-userspace-ases.patch b/queue-4.19/mips-elf_hwcap-export-userspace-ases.patch new file mode 100644 index 00000000000..edede736776 --- /dev/null +++ b/queue-4.19/mips-elf_hwcap-export-userspace-ases.patch @@ -0,0 +1,89 @@ +From 38dffe1e4dde1d3174fdce09d67370412843ebb5 Mon Sep 17 00:00:00 2001 +From: Jiaxun Yang +Date: Thu, 10 Oct 2019 23:01:57 +0800 +Subject: MIPS: elf_hwcap: Export userspace ASEs + +From: Jiaxun Yang + +commit 38dffe1e4dde1d3174fdce09d67370412843ebb5 upstream. + +A Golang developer reported MIPS hwcap isn't reflecting instructions +that the processor actually supported so programs can't apply optimized +code at runtime. + +Thus we export the ASEs that can be used in userspace programs. + +Reported-by: Meng Zhuo +Signed-off-by: Jiaxun Yang +Cc: linux-mips@vger.kernel.org +Cc: Paul Burton +Cc: # 4.14+ +Signed-off-by: Paul Burton +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/include/uapi/asm/hwcap.h | 11 +++++++++++ + arch/mips/kernel/cpu-probe.c | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 44 insertions(+) + +--- a/arch/mips/include/uapi/asm/hwcap.h ++++ b/arch/mips/include/uapi/asm/hwcap.h +@@ -6,5 +6,16 @@ + #define HWCAP_MIPS_R6 (1 << 0) + #define HWCAP_MIPS_MSA (1 << 1) + #define HWCAP_MIPS_CRC32 (1 << 2) ++#define HWCAP_MIPS_MIPS16 (1 << 3) ++#define HWCAP_MIPS_MDMX (1 << 4) ++#define HWCAP_MIPS_MIPS3D (1 << 5) ++#define HWCAP_MIPS_SMARTMIPS (1 << 6) ++#define HWCAP_MIPS_DSP (1 << 7) ++#define HWCAP_MIPS_DSP2 (1 << 8) ++#define HWCAP_MIPS_DSP3 (1 << 9) ++#define HWCAP_MIPS_MIPS16E2 (1 << 10) ++#define HWCAP_LOONGSON_MMI (1 << 11) ++#define HWCAP_LOONGSON_EXT (1 << 12) ++#define HWCAP_LOONGSON_EXT2 (1 << 13) + + #endif /* _UAPI_ASM_HWCAP_H */ +--- a/arch/mips/kernel/cpu-probe.c ++++ b/arch/mips/kernel/cpu-probe.c +@@ -2105,6 +2105,39 @@ void cpu_probe(void) + elf_hwcap |= HWCAP_MIPS_MSA; + } + ++ if (cpu_has_mips16) ++ elf_hwcap |= HWCAP_MIPS_MIPS16; ++ ++ if (cpu_has_mdmx) ++ elf_hwcap |= HWCAP_MIPS_MDMX; ++ ++ if (cpu_has_mips3d) ++ elf_hwcap |= HWCAP_MIPS_MIPS3D; ++ ++ if (cpu_has_smartmips) ++ elf_hwcap |= HWCAP_MIPS_SMARTMIPS; ++ ++ if (cpu_has_dsp) ++ elf_hwcap |= HWCAP_MIPS_DSP; ++ ++ if (cpu_has_dsp2) ++ elf_hwcap |= HWCAP_MIPS_DSP2; ++ ++ if (cpu_has_dsp3) ++ elf_hwcap |= HWCAP_MIPS_DSP3; ++ ++ if (cpu_has_mips16e2) ++ elf_hwcap |= HWCAP_MIPS_MIPS16E2; ++ ++ if (cpu_has_loongson_mmi) ++ elf_hwcap |= HWCAP_LOONGSON_MMI; ++ ++ if (cpu_has_loongson_ext) ++ elf_hwcap |= HWCAP_LOONGSON_EXT; ++ ++ if (cpu_has_loongson_ext2) ++ elf_hwcap |= HWCAP_LOONGSON_EXT2; ++ + if (cpu_has_vz) + cpu_probe_vz(c); + diff --git a/queue-4.19/nfs-fix-o_direct-accounting-of-number-of-bytes-read-written.patch b/queue-4.19/nfs-fix-o_direct-accounting-of-number-of-bytes-read-written.patch new file mode 100644 index 00000000000..97db0061b5c --- /dev/null +++ b/queue-4.19/nfs-fix-o_direct-accounting-of-number-of-bytes-read-written.patch @@ -0,0 +1,155 @@ +From 031d73ed768a40684f3ca21992265ffdb6a270bf Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Mon, 30 Sep 2019 14:02:56 -0400 +Subject: NFS: Fix O_DIRECT accounting of number of bytes read/written + +From: Trond Myklebust + +commit 031d73ed768a40684f3ca21992265ffdb6a270bf upstream. + +When a series of O_DIRECT reads or writes are truncated, either due to +eof or due to an error, then we should return the number of contiguous +bytes that were received/sent starting at the offset specified by the +application. + +Currently, we are failing to correctly check contiguity, and so we're +failing the generic/465 in xfstests when the race between the read +and write RPCs causes the file to get extended while the 2 reads are +outstanding. If the first read RPC call wins the race and returns with +eof set, we should treat the second read RPC as being truncated. + +Reported-by: Su Yanjun +Fixes: 1ccbad9f9f9bd ("nfs: fix DIO good bytes calculation") +Cc: stable@vger.kernel.org # 4.1+ +Signed-off-by: Trond Myklebust +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/direct.c | 78 ++++++++++++++++++++++++++++++-------------------------- + 1 file changed, 43 insertions(+), 35 deletions(-) + +--- a/fs/nfs/direct.c ++++ b/fs/nfs/direct.c +@@ -122,32 +122,49 @@ static inline int put_dreq(struct nfs_di + } + + static void +-nfs_direct_good_bytes(struct nfs_direct_req *dreq, struct nfs_pgio_header *hdr) ++nfs_direct_handle_truncated(struct nfs_direct_req *dreq, ++ const struct nfs_pgio_header *hdr, ++ ssize_t dreq_len) ++{ ++ struct nfs_direct_mirror *mirror = &dreq->mirrors[hdr->pgio_mirror_idx]; ++ ++ if (!(test_bit(NFS_IOHDR_ERROR, &hdr->flags) || ++ test_bit(NFS_IOHDR_EOF, &hdr->flags))) ++ return; ++ if (dreq->max_count >= dreq_len) { ++ dreq->max_count = dreq_len; ++ if (dreq->count > dreq_len) ++ dreq->count = dreq_len; ++ ++ if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) ++ dreq->error = hdr->error; ++ else /* Clear outstanding error if this is EOF */ ++ dreq->error = 0; ++ } ++ if (mirror->count > dreq_len) ++ mirror->count = dreq_len; ++} ++ ++static void ++nfs_direct_count_bytes(struct nfs_direct_req *dreq, ++ const struct nfs_pgio_header *hdr) + { +- int i; +- ssize_t count; ++ struct nfs_direct_mirror *mirror = &dreq->mirrors[hdr->pgio_mirror_idx]; ++ loff_t hdr_end = hdr->io_start + hdr->good_bytes; ++ ssize_t dreq_len = 0; + +- WARN_ON_ONCE(dreq->count >= dreq->max_count); ++ if (hdr_end > dreq->io_start) ++ dreq_len = hdr_end - dreq->io_start; + +- if (dreq->mirror_count == 1) { +- dreq->mirrors[hdr->pgio_mirror_idx].count += hdr->good_bytes; +- dreq->count += hdr->good_bytes; +- } else { +- /* mirrored writes */ +- count = dreq->mirrors[hdr->pgio_mirror_idx].count; +- if (count + dreq->io_start < hdr->io_start + hdr->good_bytes) { +- count = hdr->io_start + hdr->good_bytes - dreq->io_start; +- dreq->mirrors[hdr->pgio_mirror_idx].count = count; +- } +- /* update the dreq->count by finding the minimum agreed count from all +- * mirrors */ +- count = dreq->mirrors[0].count; ++ nfs_direct_handle_truncated(dreq, hdr, dreq_len); + +- for (i = 1; i < dreq->mirror_count; i++) +- count = min(count, dreq->mirrors[i].count); ++ if (dreq_len > dreq->max_count) ++ dreq_len = dreq->max_count; + +- dreq->count = count; +- } ++ if (mirror->count < dreq_len) ++ mirror->count = dreq_len; ++ if (dreq->count < dreq_len) ++ dreq->count = dreq_len; + } + + /* +@@ -401,20 +418,12 @@ static void nfs_direct_read_completion(s + struct nfs_direct_req *dreq = hdr->dreq; + + spin_lock(&dreq->lock); +- if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) +- dreq->error = hdr->error; +- + if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) { + spin_unlock(&dreq->lock); + goto out_put; + } + +- if (hdr->good_bytes != 0) +- nfs_direct_good_bytes(dreq, hdr); +- +- if (test_bit(NFS_IOHDR_EOF, &hdr->flags)) +- dreq->error = 0; +- ++ nfs_direct_count_bytes(dreq, hdr); + spin_unlock(&dreq->lock); + + while (!list_empty(&hdr->pages)) { +@@ -651,6 +660,9 @@ static void nfs_direct_write_reschedule( + nfs_direct_write_scan_commit_list(dreq->inode, &reqs, &cinfo); + + dreq->count = 0; ++ dreq->max_count = 0; ++ list_for_each_entry(req, &reqs, wb_list) ++ dreq->max_count += req->wb_bytes; + dreq->verf.committed = NFS_INVALID_STABLE_HOW; + nfs_clear_pnfs_ds_commit_verifiers(&dreq->ds_cinfo); + for (i = 0; i < dreq->mirror_count; i++) +@@ -783,17 +795,13 @@ static void nfs_direct_write_completion( + nfs_init_cinfo_from_dreq(&cinfo, dreq); + + spin_lock(&dreq->lock); +- +- if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) +- dreq->error = hdr->error; +- + if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) { + spin_unlock(&dreq->lock); + goto out_put; + } + ++ nfs_direct_count_bytes(dreq, hdr); + if (hdr->good_bytes != 0) { +- nfs_direct_good_bytes(dreq, hdr); + if (nfs_write_need_commit(hdr)) { + if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) + request_commit = true; diff --git a/queue-4.19/series b/queue-4.19/series index 2ce7c4309d3..427dfd94e89 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -60,3 +60,8 @@ gpiolib-don-t-clear-flag_is_out-when-emulating-open-.patch iio-adc-stm32-adc-move-registers-definitions.patch iio-adc-stm32-adc-fix-a-race-when-using-several-adcs.patch cifs-use-cifsinodeinfo-open_file_lock-while-iteratin.patch +btrfs-fix-incorrect-updating-of-log-root-tree.patch +btrfs-fix-uninitialized-ret-in-ref-verify.patch +nfs-fix-o_direct-accounting-of-number-of-bytes-read-written.patch +mips-disable-loongson-mmi-instructions-for-kernel-build.patch +mips-elf_hwcap-export-userspace-ases.patch