--- /dev/null
+From 70e7af244f24c94604ef6eca32ad297632018583 Mon Sep 17 00:00:00 2001
+From: Omar Sandoval <osandov@fb.com>
+Date: Fri, 2 Jun 2017 01:20:01 -0700
+Subject: Btrfs: fix delalloc accounting leak caused by u32 overflow
+
+From: Omar Sandoval <osandov@fb.com>
+
+commit 70e7af244f24c94604ef6eca32ad297632018583 upstream.
+
+btrfs_calc_trans_metadata_size() does an unsigned 32-bit multiplication,
+which can overflow if num_items >= 4 GB / (nodesize * BTRFS_MAX_LEVEL * 2).
+For a nodesize of 16kB, this overflow happens at 16k items. Usually,
+num_items is a small constant passed to btrfs_start_transaction(), but
+we also use btrfs_calc_trans_metadata_size() for metadata reservations
+for extent items in btrfs_delalloc_{reserve,release}_metadata().
+
+In drop_outstanding_extents(), num_items is calculated as
+inode->reserved_extents - inode->outstanding_extents. The difference
+between these two counters is usually small, but if many delalloc
+extents are reserved and then the outstanding extents are merged in
+btrfs_merge_extent_hook(), the difference can become large enough to
+overflow in btrfs_calc_trans_metadata_size().
+
+The overflow manifests itself as a leak of a multiple of 4 GB in
+delalloc_block_rsv and the metadata bytes_may_use counter. This in turn
+can cause early ENOSPC errors. Additionally, these WARN_ONs in
+extent-tree.c will be hit when unmounting:
+
+ WARN_ON(fs_info->delalloc_block_rsv.size > 0);
+ WARN_ON(fs_info->delalloc_block_rsv.reserved > 0);
+ WARN_ON(space_info->bytes_pinned > 0 ||
+ space_info->bytes_reserved > 0 ||
+ space_info->bytes_may_use > 0);
+
+Fix it by casting nodesize to a u64 so that
+btrfs_calc_trans_metadata_size() does a full 64-bit multiplication.
+While we're here, do the same in btrfs_calc_trunc_metadata_size(); this
+can't overflow with any existing uses, but it's better to be safe here
+than have another hard-to-debug problem later on.
+
+Signed-off-by: Omar Sandoval <osandov@fb.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Chris Mason <clm@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/ctree.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -2547,7 +2547,7 @@ u64 btrfs_csum_bytes_to_leaves(struct bt
+ static inline u64 btrfs_calc_trans_metadata_size(struct btrfs_fs_info *fs_info,
+ unsigned num_items)
+ {
+- return fs_info->nodesize * BTRFS_MAX_LEVEL * 2 * num_items;
++ return (u64)fs_info->nodesize * BTRFS_MAX_LEVEL * 2 * num_items;
+ }
+
+ /*
+@@ -2557,7 +2557,7 @@ static inline u64 btrfs_calc_trans_metad
+ static inline u64 btrfs_calc_trunc_metadata_size(struct btrfs_fs_info *fs_info,
+ unsigned num_items)
+ {
+- return fs_info->nodesize * BTRFS_MAX_LEVEL * num_items;
++ return (u64)fs_info->nodesize * BTRFS_MAX_LEVEL * num_items;
+ }
+
+ int btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans,
--- /dev/null
+From 896533a7da929136d0432713f02a3edffece2826 Mon Sep 17 00:00:00 2001
+From: Jeff Mahoney <jeffm@suse.com>
+Date: Wed, 17 May 2017 09:49:37 -0400
+Subject: btrfs: fix memory leak in update_space_info failure path
+
+From: Jeff Mahoney <jeffm@suse.com>
+
+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 <jeffm@suse.com>
+Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/extent-tree.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -3983,6 +3983,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;
+ }
--- /dev/null
+From a9b3311ef36b670909ea4443f306c8318082c8f0 Mon Sep 17 00:00:00 2001
+From: Jeff Mahoney <jeffm@suse.com>
+Date: Wed, 17 May 2017 11:38:34 -0400
+Subject: btrfs: fix race with relocation recovery and fs_root setup
+
+From: Jeff Mahoney <jeffm@suse.com>
+
+commit a9b3311ef36b670909ea4443f306c8318082c8f0 upstream.
+
+If we have to recover relocation during mount, we'll ultimately have to
+evict the orphan inode. That goes through the reservation dance, where
+priority_reclaim_metadata_space and flush_space expect fs_info->fs_root
+to be valid. That's the next thing to be set up during mount, so we
+crash, almost always in flush_space trying to join the transaction
+but priority_reclaim_metadata_space is possible as well. This call
+path has been problematic in the past WRT whether ->fs_root is valid
+yet. Commit 957780eb278 (Btrfs: introduce ticketed enospc
+infrastructure) added new users that are called in the direct path
+instead of the async path that had already been worked around.
+
+The thing is that we don't actually need the fs_root, specifically, for
+anything. We either use it to determine whether the root is the
+chunk_root for use in choosing an allocation profile or as a root to pass
+btrfs_join_transaction before immediately committing it. Anything that
+isn't the chunk root works in the former case and any root works in
+the latter.
+
+A simple fix is to use a root we know will always be there: the
+extent_root.
+
+Fixes: 957780eb278 (Btrfs: introduce ticketed enospc infrastructure)
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/extent-tree.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4835,7 +4835,7 @@ static int may_commit_transaction(struct
+ spin_unlock(&delayed_rsv->lock);
+
+ commit:
+- trans = btrfs_join_transaction(fs_info->fs_root);
++ trans = btrfs_join_transaction(fs_info->extent_root);
+ if (IS_ERR(trans))
+ return -ENOSPC;
+
+@@ -4853,7 +4853,7 @@ static int flush_space(struct btrfs_fs_i
+ struct btrfs_space_info *space_info, u64 num_bytes,
+ u64 orig_bytes, int state)
+ {
+- struct btrfs_root *root = fs_info->fs_root;
++ struct btrfs_root *root = fs_info->extent_root;
+ struct btrfs_trans_handle *trans;
+ int nr;
+ int ret = 0;
+@@ -5053,7 +5053,7 @@ static void priority_reclaim_metadata_sp
+ int flush_state = FLUSH_DELAYED_ITEMS_NR;
+
+ spin_lock(&space_info->lock);
+- to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info->fs_root,
++ to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info->extent_root,
+ space_info);
+ if (!to_reclaim) {
+ spin_unlock(&space_info->lock);
--- /dev/null
+From cc2b702c52094b637a351d7491ac5200331d0445 Mon Sep 17 00:00:00 2001
+From: David Sterba <dsterba@suse.com>
+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 <dsterba@suse.com>
+
+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 <bo.li.liu@oracle.com>
+Fixes: fc4adbff823f7 ("btrfs: Drop EXTENT_UPTODATE check in hole punching and direct locking")
+Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/inode.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -7359,8 +7359,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;
+
--- /dev/null
+From 41c25707d21716826e3c1f60967f5550610ec1c9 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Wed, 24 May 2017 12:03:48 -0400
+Subject: cpuset: consider dying css as offline
+
+From: Tejun Heo <tj@kernel.org>
+
+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 <tj@kernel.org>
+Reported-by: Daniel Jordan <daniel.m.jordan@oracle.com>
+Link: http://lkml.kernel.org/r/327ca1f5-7957-fbb9-9e5f-9ba149d40ba2@oracle.com
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/cgroup.h | 20 ++++++++++++++++++++
+ kernel/cgroup/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/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -176,9 +176,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)
--- /dev/null
+From b3aa20ba2ba8072b73bd799605b8c98927b7056c Mon Sep 17 00:00:00 2001
+From: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
+Date: Fri, 2 Jun 2017 22:26:48 +0530
+Subject: cxl: Avoid double free_irq() for psl,slice interrupts
+
+From: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
+
+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 <vaibhav@linux.vnet.ibm.com>
+Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
+Acked-by: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -1075,13 +1075,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)
+@@ -1111,13 +1114,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)
+@@ -1140,12 +1145,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)
--- /dev/null
+From cec422c11caeeccae709e9942058b6b644ce434c Mon Sep 17 00:00:00 2001
+From: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
+Date: Tue, 6 Jun 2017 11:43:41 +0200
+Subject: cxl: Fix error path on bad ioctl
+
+From: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
+
+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 <fbarrat@linux.vnet.ibm.com>
+Reviewed-by: Vaibhav Jain <vaibhav@linux.vnet.ibm.com>
+Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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
+@@ -158,11 +158,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) {
--- /dev/null
+From babef37dccbaa49249a22bae9150686815d7be71 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Fri, 9 Jun 2017 16:20:34 -0400
+Subject: excessive checks in ufs_write_failed() and ufs_evict_inode()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit babef37dccbaa49249a22bae9150686815d7be71 upstream.
+
+As it is, short copy in write() to append-only file will fail
+to truncate the excessive allocated blocks. As the matter of
+fact, all checks in ufs_truncate_blocks() are either redundant
+or wrong for that caller. As for the only other caller
+(ufs_evict_inode()), we only need the file type checks there.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ufs/inode.c | 18 +++++-------------
+ 1 file changed, 5 insertions(+), 13 deletions(-)
+
+--- a/fs/ufs/inode.c
++++ b/fs/ufs/inode.c
+@@ -844,7 +844,9 @@ void ufs_evict_inode(struct inode * inod
+ truncate_inode_pages_final(&inode->i_data);
+ if (want_delete) {
+ inode->i_size = 0;
+- if (inode->i_blocks)
++ if (inode->i_blocks &&
++ (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
++ S_ISLNK(inode->i_mode)))
+ ufs_truncate_blocks(inode);
+ }
+
+@@ -1103,7 +1105,7 @@ out:
+ return err;
+ }
+
+-static void __ufs_truncate_blocks(struct inode *inode)
++static void ufs_truncate_blocks(struct inode *inode)
+ {
+ struct ufs_inode_info *ufsi = UFS_I(inode);
+ struct super_block *sb = inode->i_sb;
+@@ -1186,7 +1188,7 @@ static int ufs_truncate(struct inode *in
+
+ truncate_setsize(inode, size);
+
+- __ufs_truncate_blocks(inode);
++ ufs_truncate_blocks(inode);
+ inode->i_mtime = inode->i_ctime = current_time(inode);
+ mark_inode_dirty(inode);
+ out:
+@@ -1194,16 +1196,6 @@ out:
+ return err;
+ }
+
+-static void ufs_truncate_blocks(struct inode *inode)
+-{
+- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+- S_ISLNK(inode->i_mode)))
+- return;
+- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
+- return;
+- __ufs_truncate_blocks(inode);
+-}
+-
+ int ufs_setattr(struct dentry *dentry, struct iattr *attr)
+ {
+ struct inode *inode = d_inode(dentry);
--- /dev/null
+From 414cf7186dbec29bd946c138d6b5c09da5955a08 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Thu, 8 Jun 2017 18:15:18 -0400
+Subject: fix ufs_isblockset()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 414cf7186dbec29bd946c138d6b5c09da5955a08 upstream.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
rc-core-race-condition-during-ir_raw_event_register.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
+excessive-checks-in-ufs_write_failed-and-ufs_evict_inode.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
+btrfs-fix-race-with-relocation-recovery-and-fs_root-setup.patch
+btrfs-fix-delalloc-accounting-leak-caused-by-u32-overflow.patch
--- /dev/null
+From eb315d2ae614493fd1ebb026c75a80573d84f7ad Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Thu, 8 Jun 2017 21:15:03 -0400
+Subject: ufs: restore maintaining ->i_blocks
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit eb315d2ae614493fd1ebb026c75a80573d84f7ad upstream.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/stat.c | 1 +
+ fs/ufs/balloc.c | 26 +++++++++++++++++++++++++-
+ 2 files changed, 26 insertions(+), 1 deletion(-)
+
+--- a/fs/stat.c
++++ b/fs/stat.c
+@@ -586,6 +586,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
+@@ -82,7 +82,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);
+@@ -184,6 +185,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)
--- /dev/null
+From 8785d84d002c2ce0f68fbcd6c2c86be859802c7e Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Thu, 8 Jun 2017 02:42:03 -0400
+Subject: ufs: restore proper tail allocation
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 8785d84d002c2ce0f68fbcd6c2c86be859802c7e upstream.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From 6b0d144fa758869bdd652c50aa41aaf601232550 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Thu, 8 Jun 2017 21:15:45 -0400
+Subject: ufs: set correct ->s_maxsize
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 6b0d144fa758869bdd652c50aa41aaf601232550 upstream.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 940ef1a0ed939c2ca029fca715e25e7778ce1e34 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+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 <viro@zeniv.linux.org.uk>
+
+commit 940ef1a0ed939c2ca029fca715e25e7778ce1e34 upstream.
+
+... and it really needs splitting into "new" and "extend" cases, but that's for
+later
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+
--- /dev/null
+From 006351ac8ead0d4a67dd3845e3ceffe650a23212 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+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 <viro@zeniv.linux.org.uk>
+
+commit 006351ac8ead0d4a67dd3845e3ceffe650a23212 upstream.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 ....? */