From: Greg Kroah-Hartman Date: Mon, 12 Jun 2017 09:19:48 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v3.18.57~19 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=86ba5c33aa29cfece8bed569711dc782c842000b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: btrfs-fix-memory-leak-in-update_space_info-failure-path.patch btrfs-use-correct-types-for-page-indices-in-btrfs_page_exists_in_range.patch cpuset-consider-dying-css-as-offline.patch cxl-avoid-double-free_irq-for-psl-slice-interrupts.patch cxl-fix-error-path-on-bad-ioctl.patch fix-ufs_isblockset.patch ufs-restore-maintaining-i_blocks.patch ufs-restore-proper-tail-allocation.patch ufs-set-correct-s_maxsize.patch ufs_extend_tail-fix-the-braino-in-calling-conventions-of-ufs_new_fragments.patch ufs_getfrag_block-we-only-grab-truncate_mutex-on-block-creation-path.patch --- diff --git a/queue-4.9/btrfs-fix-memory-leak-in-update_space_info-failure-path.patch b/queue-4.9/btrfs-fix-memory-leak-in-update_space_info-failure-path.patch new file mode 100644 index 00000000000..85216a29e98 --- /dev/null +++ b/queue-4.9/btrfs-fix-memory-leak-in-update_space_info-failure-path.patch @@ -0,0 +1,32 @@ +From 896533a7da929136d0432713f02a3edffece2826 Mon Sep 17 00:00:00 2001 +From: Jeff Mahoney +Date: Wed, 17 May 2017 09:49:37 -0400 +Subject: btrfs: fix memory leak in update_space_info failure path + +From: Jeff Mahoney + +commit 896533a7da929136d0432713f02a3edffece2826 upstream. + +If we fail to add the space_info kobject, we'll leak the memory +for the percpu counter. + +Fixes: 6ab0a2029c (btrfs: publish allocation data in sysfs) +Signed-off-by: Jeff Mahoney +Reviewed-by: Liu Bo +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/extent-tree.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -3984,6 +3984,7 @@ static int update_space_info(struct btrf + info->space_info_kobj, "%s", + alloc_name(found->flags)); + if (ret) { ++ percpu_counter_destroy(&found->total_bytes_pinned); + kfree(found); + return ret; + } diff --git a/queue-4.9/btrfs-use-correct-types-for-page-indices-in-btrfs_page_exists_in_range.patch b/queue-4.9/btrfs-use-correct-types-for-page-indices-in-btrfs_page_exists_in_range.patch new file mode 100644 index 00000000000..f7170ec4e02 --- /dev/null +++ b/queue-4.9/btrfs-use-correct-types-for-page-indices-in-btrfs_page_exists_in_range.patch @@ -0,0 +1,64 @@ +From cc2b702c52094b637a351d7491ac5200331d0445 Mon Sep 17 00:00:00 2001 +From: David Sterba +Date: Fri, 12 May 2017 01:03:52 +0200 +Subject: btrfs: use correct types for page indices in btrfs_page_exists_in_range + +From: David Sterba + +commit cc2b702c52094b637a351d7491ac5200331d0445 upstream. + +Variables start_idx and end_idx are supposed to hold a page index +derived from the file offsets. The int type is not the right one though, +offsets larger than 1 << 44 will get silently trimmed off the high bits. +(1 << 44 is 16TiB) + +What can go wrong, if start is below the boundary and end gets trimmed: +- if there's a page after start, we'll find it (radix_tree_gang_lookup_slot) +- the final check "if (page->index <= end_idx)" will unexpectedly fail + +The function will return false, ie. "there's no page in the range", +although there is at least one. + +btrfs_page_exists_in_range is used to prevent races in: + +* in hole punching, where we make sure there are not pages in the + truncated range, otherwise we'll wait for them to finish and redo + truncation, but we're going to replace the pages with holes anyway so + the only problem is the intermediate state + +* lock_extent_direct: we want to make sure there are no pages before we + lock and start DIO, to prevent stale data reads + +For practical occurence of the bug, there are several constaints. The +file must be quite large, the affected range must cross the 16TiB +boundary and the internal state of the file pages and pending operations +must match. Also, we must not have started any ordered data in the +range, otherwise we don't even reach the buggy function check. + +DIO locking tries hard in several places to avoid deadlocks with +buffered IO and avoids waiting for ranges. The worst consequence seems +to be stale data read. + +CC: Liu Bo +Fixes: fc4adbff823f7 ("btrfs: Drop EXTENT_UPTODATE check in hole punching and direct locking") +Reviewed-by: Liu Bo +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/inode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -7435,8 +7435,8 @@ bool btrfs_page_exists_in_range(struct i + int found = false; + void **pagep = NULL; + struct page *page = NULL; +- int start_idx; +- int end_idx; ++ unsigned long start_idx; ++ unsigned long end_idx; + + start_idx = start >> PAGE_SHIFT; + diff --git a/queue-4.9/cpuset-consider-dying-css-as-offline.patch b/queue-4.9/cpuset-consider-dying-css-as-offline.patch new file mode 100644 index 00000000000..feb119d2d84 --- /dev/null +++ b/queue-4.9/cpuset-consider-dying-css-as-offline.patch @@ -0,0 +1,79 @@ +From 41c25707d21716826e3c1f60967f5550610ec1c9 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Wed, 24 May 2017 12:03:48 -0400 +Subject: cpuset: consider dying css as offline + +From: Tejun Heo + +commit 41c25707d21716826e3c1f60967f5550610ec1c9 upstream. + +In most cases, a cgroup controller don't care about the liftimes of +cgroups. For the controller, a css becomes online when ->css_online() +is called on it and offline when ->css_offline() is called. + +However, cpuset is special in that the user interface it exposes cares +whether certain cgroups exist or not. Combined with the RCU delay +between cgroup removal and css offlining, this can lead to user +visible behavior oddities where operations which should succeed after +cgroup removals fail for some time period. The effects of cgroup +removals are delayed when seen from userland. + +This patch adds css_is_dying() which tests whether offline is pending +and updates is_cpuset_online() so that the function returns false also +while offline is pending. This gets rid of the userland visible +delays. + +Signed-off-by: Tejun Heo +Reported-by: Daniel Jordan +Link: http://lkml.kernel.org/r/327ca1f5-7957-fbb9-9e5f-9ba149d40ba2@oracle.com +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/cgroup.h | 20 ++++++++++++++++++++ + kernel/cpuset.c | 4 ++-- + 2 files changed, 22 insertions(+), 2 deletions(-) + +--- a/include/linux/cgroup.h ++++ b/include/linux/cgroup.h +@@ -344,6 +344,26 @@ static inline bool css_tryget_online(str + } + + /** ++ * css_is_dying - test whether the specified css is dying ++ * @css: target css ++ * ++ * Test whether @css is in the process of offlining or already offline. In ++ * most cases, ->css_online() and ->css_offline() callbacks should be ++ * enough; however, the actual offline operations are RCU delayed and this ++ * test returns %true also when @css is scheduled to be offlined. ++ * ++ * This is useful, for example, when the use case requires synchronous ++ * behavior with respect to cgroup removal. cgroup removal schedules css ++ * offlining but the css can seem alive while the operation is being ++ * delayed. If the delay affects user visible semantics, this test can be ++ * used to resolve the situation. ++ */ ++static inline bool css_is_dying(struct cgroup_subsys_state *css) ++{ ++ return !(css->flags & CSS_NO_REF) && percpu_ref_is_dying(&css->refcnt); ++} ++ ++/** + * css_put - put a css reference + * @css: target css + * +--- a/kernel/cpuset.c ++++ b/kernel/cpuset.c +@@ -174,9 +174,9 @@ typedef enum { + } cpuset_flagbits_t; + + /* convenient tests for these bits */ +-static inline bool is_cpuset_online(const struct cpuset *cs) ++static inline bool is_cpuset_online(struct cpuset *cs) + { +- return test_bit(CS_ONLINE, &cs->flags); ++ return test_bit(CS_ONLINE, &cs->flags) && !css_is_dying(&cs->css); + } + + static inline int is_cpu_exclusive(const struct cpuset *cs) diff --git a/queue-4.9/cxl-avoid-double-free_irq-for-psl-slice-interrupts.patch b/queue-4.9/cxl-avoid-double-free_irq-for-psl-slice-interrupts.patch new file mode 100644 index 00000000000..ea4207c6d4e --- /dev/null +++ b/queue-4.9/cxl-avoid-double-free_irq-for-psl-slice-interrupts.patch @@ -0,0 +1,100 @@ +From b3aa20ba2ba8072b73bd799605b8c98927b7056c Mon Sep 17 00:00:00 2001 +From: Vaibhav Jain +Date: Fri, 2 Jun 2017 22:26:48 +0530 +Subject: cxl: Avoid double free_irq() for psl,slice interrupts + +From: Vaibhav Jain + +commit b3aa20ba2ba8072b73bd799605b8c98927b7056c upstream. + +During an eeh call to cxl_remove can result in double free_irq of +psl,slice interrupts. This can happen if perst_reloads_same_image == 1 +and call to cxl_configure_adapter() fails during slot_reset +callback. In such a case we see a kernel oops with following back-trace: + +Oops: Kernel access of bad area, sig: 11 [#1] +Call Trace: + free_irq+0x88/0xd0 (unreliable) + cxl_unmap_irq+0x20/0x40 [cxl] + cxl_native_release_psl_irq+0x78/0xd8 [cxl] + pci_deconfigure_afu+0xac/0x110 [cxl] + cxl_remove+0x104/0x210 [cxl] + pci_device_remove+0x6c/0x110 + device_release_driver_internal+0x204/0x2e0 + pci_stop_bus_device+0xa0/0xd0 + pci_stop_and_remove_bus_device+0x28/0x40 + pci_hp_remove_devices+0xb0/0x150 + pci_hp_remove_devices+0x68/0x150 + eeh_handle_normal_event+0x140/0x580 + eeh_handle_event+0x174/0x360 + eeh_event_handler+0x1e8/0x1f0 + +This patch fixes the issue of double free_irq by checking that +variables that hold the virqs (err_hwirq, serr_hwirq, psl_virq) are +not '0' before un-mapping and resetting these variables to '0' when +they are un-mapped. + +Signed-off-by: Vaibhav Jain +Reviewed-by: Andrew Donnellan +Acked-by: Frederic Barrat +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/cxl/native.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/drivers/misc/cxl/native.c ++++ b/drivers/misc/cxl/native.c +@@ -1066,13 +1066,16 @@ int cxl_native_register_psl_err_irq(stru + + void cxl_native_release_psl_err_irq(struct cxl *adapter) + { +- if (adapter->native->err_virq != irq_find_mapping(NULL, adapter->native->err_hwirq)) ++ if (adapter->native->err_virq == 0 || ++ adapter->native->err_virq != ++ irq_find_mapping(NULL, adapter->native->err_hwirq)) + return; + + cxl_p1_write(adapter, CXL_PSL_ErrIVTE, 0x0000000000000000); + cxl_unmap_irq(adapter->native->err_virq, adapter); + cxl_ops->release_one_irq(adapter, adapter->native->err_hwirq); + kfree(adapter->irq_name); ++ adapter->native->err_virq = 0; + } + + int cxl_native_register_serr_irq(struct cxl_afu *afu) +@@ -1102,13 +1105,15 @@ int cxl_native_register_serr_irq(struct + + void cxl_native_release_serr_irq(struct cxl_afu *afu) + { +- if (afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq)) ++ if (afu->serr_virq == 0 || ++ afu->serr_virq != irq_find_mapping(NULL, afu->serr_hwirq)) + return; + + cxl_p1n_write(afu, CXL_PSL_SERR_An, 0x0000000000000000); + cxl_unmap_irq(afu->serr_virq, afu); + cxl_ops->release_one_irq(afu->adapter, afu->serr_hwirq); + kfree(afu->err_irq_name); ++ afu->serr_virq = 0; + } + + int cxl_native_register_psl_irq(struct cxl_afu *afu) +@@ -1131,12 +1136,15 @@ int cxl_native_register_psl_irq(struct c + + void cxl_native_release_psl_irq(struct cxl_afu *afu) + { +- if (afu->native->psl_virq != irq_find_mapping(NULL, afu->native->psl_hwirq)) ++ if (afu->native->psl_virq == 0 || ++ afu->native->psl_virq != ++ irq_find_mapping(NULL, afu->native->psl_hwirq)) + return; + + cxl_unmap_irq(afu->native->psl_virq, afu); + cxl_ops->release_one_irq(afu->adapter, afu->native->psl_hwirq); + kfree(afu->psl_irq_name); ++ afu->native->psl_virq = 0; + } + + static void recover_psl_err(struct cxl_afu *afu, u64 errstat) diff --git a/queue-4.9/cxl-fix-error-path-on-bad-ioctl.patch b/queue-4.9/cxl-fix-error-path-on-bad-ioctl.patch new file mode 100644 index 00000000000..986b011ffdd --- /dev/null +++ b/queue-4.9/cxl-fix-error-path-on-bad-ioctl.patch @@ -0,0 +1,40 @@ +From cec422c11caeeccae709e9942058b6b644ce434c Mon Sep 17 00:00:00 2001 +From: Frederic Barrat +Date: Tue, 6 Jun 2017 11:43:41 +0200 +Subject: cxl: Fix error path on bad ioctl + +From: Frederic Barrat + +commit cec422c11caeeccae709e9942058b6b644ce434c upstream. + +Fix error path if we can't copy user structure on CXL_IOCTL_START_WORK +ioctl. We shouldn't unlock the context status mutex as it was not +locked (yet). + +Fixes: 0712dc7e73e5 ("cxl: Fix issues when unmapping contexts") +Signed-off-by: Frederic Barrat +Reviewed-by: Vaibhav Jain +Reviewed-by: Andrew Donnellan +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/cxl/file.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +--- a/drivers/misc/cxl/file.c ++++ b/drivers/misc/cxl/file.c +@@ -155,11 +155,8 @@ static long afu_ioctl_start_work(struct + + /* Do this outside the status_mutex to avoid a circular dependency with + * the locking in cxl_mmap_fault() */ +- if (copy_from_user(&work, uwork, +- sizeof(struct cxl_ioctl_start_work))) { +- rc = -EFAULT; +- goto out; +- } ++ if (copy_from_user(&work, uwork, sizeof(work))) ++ return -EFAULT; + + mutex_lock(&ctx->status_mutex); + if (ctx->status != OPENED) { diff --git a/queue-4.9/fix-ufs_isblockset.patch b/queue-4.9/fix-ufs_isblockset.patch new file mode 100644 index 00000000000..19e8f6e3b08 --- /dev/null +++ b/queue-4.9/fix-ufs_isblockset.patch @@ -0,0 +1,41 @@ +From 414cf7186dbec29bd946c138d6b5c09da5955a08 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Thu, 8 Jun 2017 18:15:18 -0400 +Subject: fix ufs_isblockset() + +From: Al Viro + +commit 414cf7186dbec29bd946c138d6b5c09da5955a08 upstream. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ufs/util.h | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/fs/ufs/util.h ++++ b/fs/ufs/util.h +@@ -473,15 +473,19 @@ static inline unsigned _ubh_find_last_ze + static inline int _ubh_isblockset_(struct ufs_sb_private_info * uspi, + struct ufs_buffer_head * ubh, unsigned begin, unsigned block) + { ++ u8 mask; + switch (uspi->s_fpb) { + case 8: + return (*ubh_get_addr (ubh, begin + block) == 0xff); + case 4: +- return (*ubh_get_addr (ubh, begin + (block >> 1)) == (0x0f << ((block & 0x01) << 2))); ++ mask = 0x0f << ((block & 0x01) << 2); ++ return (*ubh_get_addr (ubh, begin + (block >> 1)) & mask) == mask; + case 2: +- return (*ubh_get_addr (ubh, begin + (block >> 2)) == (0x03 << ((block & 0x03) << 1))); ++ mask = 0x03 << ((block & 0x03) << 1); ++ return (*ubh_get_addr (ubh, begin + (block >> 2)) & mask) == mask; + case 1: +- return (*ubh_get_addr (ubh, begin + (block >> 3)) == (0x01 << (block & 0x07))); ++ mask = 0x01 << (block & 0x07); ++ return (*ubh_get_addr (ubh, begin + (block >> 3)) & mask) == mask; + } + return 0; + } diff --git a/queue-4.9/series b/queue-4.9/series index 6aa1dd5e299..edda98703a8 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -72,3 +72,14 @@ drm-msm-expose-our-reservation-object-when-exporting-a-dmabuf.patch ahci-acer-sa5-271-ssd-not-detected-fix.patch cgroup-prevent-kill_css-from-being-called-more-than-once.patch input-elantech-add-fujitsu-lifebook-e546-e557-to-force-crc_enabled.patch +cpuset-consider-dying-css-as-offline.patch +ufs-restore-proper-tail-allocation.patch +fix-ufs_isblockset.patch +ufs-restore-maintaining-i_blocks.patch +ufs-set-correct-s_maxsize.patch +ufs_extend_tail-fix-the-braino-in-calling-conventions-of-ufs_new_fragments.patch +ufs_getfrag_block-we-only-grab-truncate_mutex-on-block-creation-path.patch +cxl-fix-error-path-on-bad-ioctl.patch +cxl-avoid-double-free_irq-for-psl-slice-interrupts.patch +btrfs-use-correct-types-for-page-indices-in-btrfs_page_exists_in_range.patch +btrfs-fix-memory-leak-in-update_space_info-failure-path.patch diff --git a/queue-4.9/ufs-restore-maintaining-i_blocks.patch b/queue-4.9/ufs-restore-maintaining-i_blocks.patch new file mode 100644 index 00000000000..0f138b925d5 --- /dev/null +++ b/queue-4.9/ufs-restore-maintaining-i_blocks.patch @@ -0,0 +1,104 @@ +From eb315d2ae614493fd1ebb026c75a80573d84f7ad Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Thu, 8 Jun 2017 21:15:03 -0400 +Subject: ufs: restore maintaining ->i_blocks + +From: Al Viro + +commit eb315d2ae614493fd1ebb026c75a80573d84f7ad upstream. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/stat.c | 1 + + fs/ufs/balloc.c | 26 +++++++++++++++++++++++++- + 2 files changed, 26 insertions(+), 1 deletion(-) + +--- a/fs/stat.c ++++ b/fs/stat.c +@@ -454,6 +454,7 @@ void __inode_add_bytes(struct inode *ino + inode->i_bytes -= 512; + } + } ++EXPORT_SYMBOL(__inode_add_bytes); + + void inode_add_bytes(struct inode *inode, loff_t bytes) + { +--- a/fs/ufs/balloc.c ++++ b/fs/ufs/balloc.c +@@ -81,7 +81,8 @@ void ufs_free_fragments(struct inode *in + ufs_error (sb, "ufs_free_fragments", + "bit already cleared for fragment %u", i); + } +- ++ ++ inode_sub_bytes(inode, count << uspi->s_fshift); + fs32_add(sb, &ucg->cg_cs.cs_nffree, count); + uspi->cs_total.cs_nffree += count; + fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, count); +@@ -183,6 +184,7 @@ do_more: + ufs_error(sb, "ufs_free_blocks", "freeing free fragment"); + } + ubh_setblock(UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); ++ inode_sub_bytes(inode, uspi->s_fpb << uspi->s_fshift); + if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) + ufs_clusteracct (sb, ucpi, blkno, 1); + +@@ -494,6 +496,20 @@ u64 ufs_new_fragments(struct inode *inod + return 0; + } + ++static bool try_add_frags(struct inode *inode, unsigned frags) ++{ ++ unsigned size = frags * i_blocksize(inode); ++ spin_lock(&inode->i_lock); ++ __inode_add_bytes(inode, size); ++ if (unlikely((u32)inode->i_blocks != inode->i_blocks)) { ++ __inode_sub_bytes(inode, size); ++ spin_unlock(&inode->i_lock); ++ return false; ++ } ++ spin_unlock(&inode->i_lock); ++ return true; ++} ++ + static u64 ufs_add_fragments(struct inode *inode, u64 fragment, + unsigned oldcount, unsigned newcount) + { +@@ -530,6 +546,9 @@ static u64 ufs_add_fragments(struct inod + for (i = oldcount; i < newcount; i++) + if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_freeoff, fragno + i)) + return 0; ++ ++ if (!try_add_frags(inode, count)) ++ return 0; + /* + * Block can be extended + */ +@@ -647,6 +666,7 @@ cg_found: + ubh_setbit (UCPI_UBH(ucpi), ucpi->c_freeoff, goal + i); + i = uspi->s_fpb - count; + ++ inode_sub_bytes(inode, i << uspi->s_fshift); + fs32_add(sb, &ucg->cg_cs.cs_nffree, i); + uspi->cs_total.cs_nffree += i; + fs32_add(sb, &UFS_SB(sb)->fs_cs(cgno).cs_nffree, i); +@@ -657,6 +677,8 @@ cg_found: + result = ufs_bitmap_search (sb, ucpi, goal, allocsize); + if (result == INVBLOCK) + return 0; ++ if (!try_add_frags(inode, count)) ++ return 0; + for (i = 0; i < count; i++) + ubh_clrbit (UCPI_UBH(ucpi), ucpi->c_freeoff, result + i); + +@@ -716,6 +738,8 @@ norot: + return INVBLOCK; + ucpi->c_rotor = result; + gotit: ++ if (!try_add_frags(inode, uspi->s_fpb)) ++ return 0; + blkno = ufs_fragstoblks(result); + ubh_clrblock (UCPI_UBH(ucpi), ucpi->c_freeoff, blkno); + if ((UFS_SB(sb)->s_flags & UFS_CG_MASK) == UFS_CG_44BSD) diff --git a/queue-4.9/ufs-restore-proper-tail-allocation.patch b/queue-4.9/ufs-restore-proper-tail-allocation.patch new file mode 100644 index 00000000000..c857c9d5cd4 --- /dev/null +++ b/queue-4.9/ufs-restore-proper-tail-allocation.patch @@ -0,0 +1,27 @@ +From 8785d84d002c2ce0f68fbcd6c2c86be859802c7e Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Thu, 8 Jun 2017 02:42:03 -0400 +Subject: ufs: restore proper tail allocation + +From: Al Viro + +commit 8785d84d002c2ce0f68fbcd6c2c86be859802c7e upstream. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ufs/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ufs/inode.c ++++ b/fs/ufs/inode.c +@@ -284,7 +284,7 @@ ufs_inode_getfrag(struct inode *inode, u + goal += uspi->s_fpb; + } + tmp = ufs_new_fragments(inode, p, ufs_blknum(new_fragment), +- goal, uspi->s_fpb, err, locked_page); ++ goal, nfrags, err, locked_page); + + if (!tmp) { + *err = -ENOSPC; diff --git a/queue-4.9/ufs-set-correct-s_maxsize.patch b/queue-4.9/ufs-set-correct-s_maxsize.patch new file mode 100644 index 00000000000..9537be42b46 --- /dev/null +++ b/queue-4.9/ufs-set-correct-s_maxsize.patch @@ -0,0 +1,50 @@ +From 6b0d144fa758869bdd652c50aa41aaf601232550 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Thu, 8 Jun 2017 21:15:45 -0400 +Subject: ufs: set correct ->s_maxsize + +From: Al Viro + +commit 6b0d144fa758869bdd652c50aa41aaf601232550 upstream. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ufs/super.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/fs/ufs/super.c ++++ b/fs/ufs/super.c +@@ -746,6 +746,23 @@ static void ufs_put_super(struct super_b + return; + } + ++static u64 ufs_max_bytes(struct super_block *sb) ++{ ++ struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; ++ int bits = uspi->s_apbshift; ++ u64 res; ++ ++ if (bits > 21) ++ res = ~0ULL; ++ else ++ res = UFS_NDADDR + (1LL << bits) + (1LL << (2*bits)) + ++ (1LL << (3*bits)); ++ ++ if (res >= (MAX_LFS_FILESIZE >> uspi->s_bshift)) ++ return MAX_LFS_FILESIZE; ++ return res << uspi->s_bshift; ++} ++ + static int ufs_fill_super(struct super_block *sb, void *data, int silent) + { + struct ufs_sb_info * sbi; +@@ -1211,6 +1228,7 @@ magic_found: + "fast symlink size (%u)\n", uspi->s_maxsymlinklen); + uspi->s_maxsymlinklen = maxsymlen; + } ++ sb->s_maxbytes = ufs_max_bytes(sb); + sb->s_max_links = UFS_LINK_MAX; + + inode = ufs_iget(sb, UFS_ROOTINO); diff --git a/queue-4.9/ufs_extend_tail-fix-the-braino-in-calling-conventions-of-ufs_new_fragments.patch b/queue-4.9/ufs_extend_tail-fix-the-braino-in-calling-conventions-of-ufs_new_fragments.patch new file mode 100644 index 00000000000..8f9c1ead761 --- /dev/null +++ b/queue-4.9/ufs_extend_tail-fix-the-braino-in-calling-conventions-of-ufs_new_fragments.patch @@ -0,0 +1,31 @@ +From 940ef1a0ed939c2ca029fca715e25e7778ce1e34 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Thu, 8 Jun 2017 23:27:12 -0400 +Subject: ufs_extend_tail(): fix the braino in calling conventions of ufs_new_fragments() + +From: Al Viro + +commit 940ef1a0ed939c2ca029fca715e25e7778ce1e34 upstream. + +... and it really needs splitting into "new" and "extend" cases, but that's for +later + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ufs/inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ufs/inode.c ++++ b/fs/ufs/inode.c +@@ -235,7 +235,8 @@ ufs_extend_tail(struct inode *inode, u64 + + p = ufs_get_direct_data_ptr(uspi, ufsi, block); + tmp = ufs_new_fragments(inode, p, lastfrag, ufs_data_ptr_to_cpu(sb, p), +- new_size, err, locked_page); ++ new_size - (lastfrag & uspi->s_fpbmask), err, ++ locked_page); + return tmp != 0; + } + diff --git a/queue-4.9/ufs_getfrag_block-we-only-grab-truncate_mutex-on-block-creation-path.patch b/queue-4.9/ufs_getfrag_block-we-only-grab-truncate_mutex-on-block-creation-path.patch new file mode 100644 index 00000000000..0926fb5f5e3 --- /dev/null +++ b/queue-4.9/ufs_getfrag_block-we-only-grab-truncate_mutex-on-block-creation-path.patch @@ -0,0 +1,29 @@ +From 006351ac8ead0d4a67dd3845e3ceffe650a23212 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Thu, 8 Jun 2017 23:28:53 -0400 +Subject: ufs_getfrag_block(): we only grab ->truncate_mutex on block creation path + +From: Al Viro + +commit 006351ac8ead0d4a67dd3845e3ceffe650a23212 upstream. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ufs/inode.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/ufs/inode.c ++++ b/fs/ufs/inode.c +@@ -403,7 +403,9 @@ static int ufs_getfrag_block(struct inod + + if (!create) { + phys64 = ufs_frag_map(inode, offsets, depth); +- goto out; ++ if (phys64) ++ map_bh(bh_result, sb, phys64 + frag); ++ return 0; + } + + /* This code entered only while writing ....? */