Home Home > GIT Browse > SLE15-AZURE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKernel Build Daemon <kbuild@suse.de>2019-06-13 07:05:18 +0200
committerKernel Build Daemon <kbuild@suse.de>2019-06-13 07:05:18 +0200
commite86c1f917eb8948675a61556903b860e550247d2 (patch)
treece74015b5be7c4c6785c3b7475e82ce0c5be397b
parent5f19f9618b89ae448c3d15e687f70e1d458a0c4b (diff)
parentfc4854cd818c73aab0fc7ae84c3bddd2aa9e0ec9 (diff)
Merge branch 'SLE15' into SLE15-AZURE
-rw-r--r--patches.drivers/scsi-mpt3sas_ctl-fix-double-fetch-bug-in-ctl_ioctl_main45
-rw-r--r--patches.fixes/efi-x86-Add-missing-error-handling-to-old_memmap-1-1.patch91
-rw-r--r--patches.fixes/xfs-do-not-set-the-page-uptodate-in-xfs_writepage_ma.patch59
-rw-r--r--patches.fixes/xfs-don-t-clear-imap_valid-for-a-non-uptodate-buffer.patch56
-rw-r--r--patches.fixes/xfs-don-t-look-at-buffer-heads-in-xfs_add_to_ioend.patch166
-rw-r--r--patches.fixes/xfs-don-t-use-XFS_BMAPI_ENTRIRE-in-xfs_get_blocks.patch37
-rw-r--r--patches.fixes/xfs-don-t-use-XFS_BMAPI_IGSTATE-in-xfs_map_blocks.patch58
-rw-r--r--patches.fixes/xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cach.patch64
-rw-r--r--patches.fixes/xfs-fix-s_maxbytes-overflow-problems.patch58
-rw-r--r--patches.fixes/xfs-make-xfs_writepage_map-extent-map-centric.patch261
-rw-r--r--patches.fixes/xfs-minor-cleanup-for-xfs_get_blocks.patch51
-rw-r--r--patches.fixes/xfs-move-all-writeback-buffer_head-manipulation-into.patch77
-rw-r--r--patches.fixes/xfs-refactor-the-tail-of-xfs_writepage_map.patch113
-rw-r--r--patches.fixes/xfs-remove-XFS_IO_INVALID.patch79
-rw-r--r--patches.fixes/xfs-remove-the-imap_valid-flag.patch179
-rw-r--r--patches.fixes/xfs-remove-unused-parameter-from-xfs_writepage_map.patch52
-rw-r--r--patches.fixes/xfs-remove-xfs_map_cow.patch322
-rw-r--r--patches.fixes/xfs-remove-xfs_reflink_find_cow_mapping.patch130
-rw-r--r--patches.fixes/xfs-remove-xfs_reflink_trim_irec_to_next_cow.patch115
-rw-r--r--patches.fixes/xfs-remove-xfs_start_page_writeback.patch102
-rw-r--r--patches.fixes/xfs-rename-the-offset-variable-in-xfs_writepage_map.patch94
-rw-r--r--patches.fixes/xfs-simplify-xfs_map_blocks-by-using-xfs_iext_lookup.patch70
-rw-r--r--patches.fixes/xfs-skip-CoW-writes-past-EOF-when-writeback-races-wi.patch56
-rw-r--r--patches.fixes/xfs-xfs_reflink_convert_cow-memory-allocation-deadlo.patch83
-rw-r--r--series.conf26
25 files changed, 2444 insertions, 0 deletions
diff --git a/patches.drivers/scsi-mpt3sas_ctl-fix-double-fetch-bug-in-ctl_ioctl_main b/patches.drivers/scsi-mpt3sas_ctl-fix-double-fetch-bug-in-ctl_ioctl_main
new file mode 100644
index 0000000000..0523dab948
--- /dev/null
+++ b/patches.drivers/scsi-mpt3sas_ctl-fix-double-fetch-bug-in-ctl_ioctl_main
@@ -0,0 +1,45 @@
+From: Gen Zhang <blackgod016574@gmail.com>
+Date: Thu, 30 May 2019 09:10:30 +0800
+Subject: scsi: mpt3sas_ctl: fix double-fetch bug in _ctl_ioctl_main()
+Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
+Git-commit: 86e5aca7fa2927060839f3e3b40c8bd65a7e8d1e
+Patch-mainline: Queued in subsystem maintainer repo
+References: bsc#1136922 cve-2019-12456
+
+In _ctl_ioctl_main(), 'ioctl_header' is fetched the first time from
+userspace. 'ioctl_header.ioc_number' is then checked. The legal result is
+saved to 'ioc'. Then, in condition MPT3COMMAND, the whole struct is fetched
+again from the userspace. Then _ctl_do_mpt_command() is called, 'ioc' and
+'karg' as inputs.
+
+However, a malicious user can change the 'ioc_number' between the two
+fetches, which will cause a potential security issues. Moreover, a
+malicious user can provide a valid 'ioc_number' to pass the check in first
+fetch, and then modify it in the second fetch.
+
+To fix this, we need to recheck the 'ioc_number' in the second fetch.
+
+Signed-off-by: Gen Zhang <blackgod016574@gmail.com>
+Acked-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/mpt3sas/mpt3sas_ctl.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+index b2bb47c14d35..5181c03e82a6 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+@@ -2319,6 +2319,10 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
+ break;
+ }
+
++ if (karg.hdr.ioc_number != ioctl_header.ioc_number) {
++ ret = -EINVAL;
++ break;
++ }
+ if (_IOC_SIZE(cmd) == sizeof(struct mpt3_ioctl_command)) {
+ uarg = arg;
+ ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf);
+
diff --git a/patches.fixes/efi-x86-Add-missing-error-handling-to-old_memmap-1-1.patch b/patches.fixes/efi-x86-Add-missing-error-handling-to-old_memmap-1-1.patch
new file mode 100644
index 0000000000..ed9eea5716
--- /dev/null
+++ b/patches.fixes/efi-x86-Add-missing-error-handling-to-old_memmap-1-1.patch
@@ -0,0 +1,91 @@
+From 4e78921ba4dd0aca1cc89168f45039add4183f8e Mon Sep 17 00:00:00 2001
+From: Gen Zhang <blackgod016574@gmail.com>
+Date: Sat, 25 May 2019 13:25:58 +0200
+Subject: [PATCH] efi/x86/Add missing error handling to old_memmap 1:1 mapping code
+Git-commit: 4e78921ba4dd0aca1cc89168f45039add4183f8e
+Patch-mainline: v5.2-rc3
+References: CVE-2019-12380,bsc#1136598
+
+The old_memmap flow in efi_call_phys_prolog() performs numerous memory
+allocations, and either does not check for failure at all, or it does
+but fails to propagate it back to the caller, which may end up calling
+into the firmware with an incomplete 1:1 mapping.
+
+So let's fix this by returning NULL from efi_call_phys_prolog() on
+memory allocation failures only, and by handling this condition in the
+caller. Also, clean up any half baked sets of page tables that we may
+have created before returning with a NULL return value.
+
+Note that any failure at this level will trigger a panic() two levels
+up, so none of this makes a huge difference, but it is a nice cleanup
+nonetheless.
+
+[ardb: update commit log, add efi_call_phys_epilog() call on error path]
+
+Signed-off-by: Gen Zhang <blackgod016574@gmail.com>
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rob Bradford <robert.bradford@intel.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-efi@vger.kernel.org
+Link: http://lkml.kernel.org/r/20190525112559.7917-2-ard.biesheuvel@linaro.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/x86/platform/efi/efi.c | 2 ++
+ arch/x86/platform/efi/efi_64.c | 10 ++++++++--
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/platform/efi/efi.c
++++ b/arch/x86/platform/efi/efi.c
+@@ -85,6 +85,8 @@ static efi_status_t __init phys_efi_set_
+ pgd_t *save_pgd;
+
+ save_pgd = efi_call_phys_prolog();
++ if (!save_pgd)
++ return EFI_ABORTED;
+
+ /* Disable interrupts around EFI calls: */
+ local_irq_save(flags);
+--- a/arch/x86/platform/efi/efi_64.c
++++ b/arch/x86/platform/efi/efi_64.c
+@@ -90,6 +90,8 @@ pgd_t * __init efi_call_phys_prolog(void
+
+ n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
+ save_pgd = kmalloc_array(n_pgds, sizeof(*save_pgd), GFP_KERNEL);
++ if (!save_pgd)
++ return NULL;
+
+ /*
+ * Build 1:1 identity mapping for efi=old_map usage. Note that
+@@ -108,7 +110,7 @@ pgd_t * __init efi_call_phys_prolog(void
+ p4d = p4d_alloc(&init_mm, pgd_efi, addr_pgd);
+ if (!p4d) {
+ pr_err("Failed to allocate p4d table!\n");
+- goto out;
++ goto error;
+ }
+
+ for (i = 0; i < PTRS_PER_P4D; i++) {
+@@ -118,7 +120,7 @@ pgd_t * __init efi_call_phys_prolog(void
+ pud = pud_alloc(&init_mm, p4d_efi, addr_p4d);
+ if (!pud) {
+ pr_err("Failed to allocate pud table!\n");
+- goto out;
++ goto error;
+ }
+
+ for (j = 0; j < PTRS_PER_PUD; j++) {
+@@ -141,6 +143,10 @@ out:
+ __flush_tlb_all();
+
+ return save_pgd;
++
++error:
++ efi_call_phys_epilog(save_pgd);
++ return NULL;
+ }
+
+ void __init efi_call_phys_epilog(pgd_t *save_pgd)
diff --git a/patches.fixes/xfs-do-not-set-the-page-uptodate-in-xfs_writepage_ma.patch b/patches.fixes/xfs-do-not-set-the-page-uptodate-in-xfs_writepage_ma.patch
new file mode 100644
index 0000000000..737d04da7f
--- /dev/null
+++ b/patches.fixes/xfs-do-not-set-the-page-uptodate-in-xfs_writepage_ma.patch
@@ -0,0 +1,59 @@
+From 91cdfd1761659f338e673aca72af3d0d50b88847 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:25:58 -0700
+Subject: [PATCH] xfs: do not set the page uptodate in xfs_writepage_map
+Git-commit: 91cdfd1761659f338e673aca72af3d0d50b88847
+Patch-mainline: v4.19-rc1
+References: bsc#1138003
+
+We already track the page uptodate status based on the buffer uptodate
+status, which is updated whenever reading or zeroing blocks.
+
+This code has been there since commit a ptool commit in 2002, which
+claims to:
+
+ "merge" the 2.4 fsx fix for block size < page size to 2.5. This needed
+ major changes to actually fit.
+
+and isn't present in other writepage implementations.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -928,7 +928,6 @@
+ uint64_t offset;
+ int error = 0;
+ int count = 0;
+- int uptodate = 1;
+ unsigned int new_type;
+
+ bh = head = page_buffers(page);
+@@ -936,8 +935,6 @@
+ do {
+ if (offset >= end_offset)
+ break;
+- if (!buffer_uptodate(bh))
+- uptodate = 0;
+
+ /*
+ * set_page_dirty dirties all buffers in a page, independent
+@@ -1001,9 +998,6 @@
+
+ } while (offset += len, ((bh = bh->b_this_page) != head));
+
+- if (uptodate && bh == head)
+- SetPageUptodate(page);
+-
+ ASSERT(wpc->ioend || list_empty(&submit_list));
+
+ out:
+
diff --git a/patches.fixes/xfs-don-t-clear-imap_valid-for-a-non-uptodate-buffer.patch b/patches.fixes/xfs-don-t-clear-imap_valid-for-a-non-uptodate-buffer.patch
new file mode 100644
index 0000000000..5078956a9b
--- /dev/null
+++ b/patches.fixes/xfs-don-t-clear-imap_valid-for-a-non-uptodate-buffer.patch
@@ -0,0 +1,56 @@
+From c57371a16d074bb4eafe6b73f29360085ecb2064 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:25:58 -0700
+Subject: [PATCH] xfs: don't clear imap_valid for a non-uptodate buffers
+Git-commit: c57371a16d074bb4eafe6b73f29360085ecb2064
+Patch-mainline: v4.19-rc1
+References: bsc#1138018
+
+Finding a buffer that isn't uptodate doesn't invalidate the mapping for
+any given block. The last_sector check will already take care of starting
+another ioend as soon as we find any non-update buffer, and if the current
+mapping doesn't include the next uptodate buffer the xfs_imap_valid check
+will take care of it.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index df80a383ccd8..1d1cb917cc6e 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -863,10 +863,8 @@ xfs_writepage_map(
+ * meaningless for holes (!mapped && uptodate), so skip
+ * buffers covering holes here.
+ */
+- if (!buffer_mapped(bh) && buffer_uptodate(bh)) {
+- wpc->imap_valid = false;
++ if (!buffer_mapped(bh) && buffer_uptodate(bh))
+ continue;
+- }
+
+ if (buffer_unwritten(bh))
+ new_type = XFS_IO_UNWRITTEN;
+@@ -879,11 +877,8 @@ xfs_writepage_map(
+ ASSERT(buffer_mapped(bh));
+ /*
+ * This buffer is not uptodate and will not be
+- * written to disk. Ensure that we will put any
+- * subsequent writeable buffers into a new
+- * ioend.
++ * written to disk.
+ */
+- wpc->imap_valid = false;
+ continue;
+ }
+
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-don-t-look-at-buffer-heads-in-xfs_add_to_ioend.patch b/patches.fixes/xfs-don-t-look-at-buffer-heads-in-xfs_add_to_ioend.patch
new file mode 100644
index 0000000000..5c28e7b2ba
--- /dev/null
+++ b/patches.fixes/xfs-don-t-look-at-buffer-heads-in-xfs_add_to_ioend.patch
@@ -0,0 +1,166 @@
+From 3faed667644d787c3cf6f977f80bac7a013eb045 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:26:02 -0700
+Subject: [PATCH] xfs: don't look at buffer heads in xfs_add_to_ioend
+Git-commit: 3faed667644d787c3cf6f977f80bac7a013eb045
+Patch-mainline: v4.19-rc1
+References: bsc#1138013
+
+Calculate all information for the bio based on the passed in information
+without requiring a buffer_head structure.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 68 +++++++++++++++++++++++++-----------------------------
+ 1 file changed, 32 insertions(+), 36 deletions(-)
+
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -44,7 +44,6 @@
+ struct xfs_bmbt_irec imap;
+ unsigned int io_type;
+ struct xfs_ioend *ioend;
+- sector_t last_block;
+ };
+
+ void
+@@ -546,11 +545,6 @@
+ unlock_page(page);
+ }
+
+-static inline int xfs_bio_add_buffer(struct bio *bio, struct buffer_head *bh)
+-{
+- return bio_add_page(bio, bh->b_page, bh->b_size, bh_offset(bh));
+-}
+-
+ /*
+ * Submit the bio for an ioend. We are passed an ioend with a bio attached to
+ * it, and we submit that bio. The ioend may be used for multiple bio
+@@ -615,27 +609,20 @@
+ return 0;
+ }
+
+-static void
+-xfs_init_bio_from_bh(
+- struct bio *bio,
+- struct buffer_head *bh)
+-{
+- bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9);
+- bio_set_dev(bio, bh->b_bdev);
+-}
+-
+ static struct xfs_ioend *
+ xfs_alloc_ioend(
+ struct inode *inode,
+ unsigned int type,
+ xfs_off_t offset,
+- struct buffer_head *bh)
++ struct block_device *bdev,
++ sector_t sector)
+ {
+ struct xfs_ioend *ioend;
+ struct bio *bio;
+
+ bio = bio_alloc_bioset(GFP_NOFS, BIO_MAX_PAGES, xfs_ioend_bioset);
+- xfs_init_bio_from_bh(bio, bh);
++ bio_set_dev(bio, bdev);
++ bio->bi_iter.bi_sector = sector;
+
+ ioend = container_of(bio, struct xfs_ioend, io_inline_bio);
+ INIT_LIST_HEAD(&ioend->io_list);
+@@ -660,13 +647,14 @@
+ xfs_chain_bio(
+ struct xfs_ioend *ioend,
+ struct writeback_control *wbc,
+- struct buffer_head *bh)
++ struct block_device *bdev,
++ sector_t sector)
+ {
+ struct bio *new;
+
+ new = bio_alloc(GFP_NOFS, BIO_MAX_PAGES);
+- xfs_init_bio_from_bh(new, bh);
+-
++ bio_set_dev(new, bdev);
++ new->bi_iter.bi_sector = sector;
+ bio_chain(ioend->io_bio, new);
+ bio_get(ioend->io_bio); /* for xfs_destroy_ioend */
+ ioend->io_bio->bi_opf = REQ_OP_WRITE | wbc_to_write_flags(wbc);
+@@ -675,39 +663,45 @@
+ }
+
+ /*
+- * Test to see if we've been building up a completion structure for
+- * earlier buffers -- if so, we try to append to this ioend if we
+- * can, otherwise we finish off any current ioend and start another.
+- * Return the ioend we finished off so that the caller can submit it
+- * once it has finished processing the dirty page.
++ * Test to see if we have an existing ioend structure that we could append to
++ * first, otherwise finish off the current ioend and start another.
+ */
+ STATIC void
+ xfs_add_to_ioend(
+ struct inode *inode,
+- struct buffer_head *bh,
+ xfs_off_t offset,
++ struct page *page,
+ struct xfs_writepage_ctx *wpc,
+ struct writeback_control *wbc,
+ struct list_head *iolist)
+ {
++ struct xfs_inode *ip = XFS_I(inode);
++ struct xfs_mount *mp = ip->i_mount;
++ struct block_device *bdev = xfs_find_bdev_for_inode(inode);
++ unsigned len = i_blocksize(inode);
++ unsigned poff = offset & (PAGE_SIZE - 1);
++ sector_t sector;
++
++ sector = xfs_fsb_to_db(ip, wpc->imap.br_startblock) +
++ ((offset - XFS_FSB_TO_B(mp, wpc->imap.br_startoff)) >> 9);
++
+ if (!wpc->ioend || wpc->io_type != wpc->ioend->io_type ||
+- bh->b_blocknr != wpc->last_block + 1 ||
++ sector != bio_end_sector(wpc->ioend->io_bio) ||
+ offset != wpc->ioend->io_offset + wpc->ioend->io_size) {
+ if (wpc->ioend)
+ list_add(&wpc->ioend->io_list, iolist);
+- wpc->ioend = xfs_alloc_ioend(inode, wpc->io_type, offset, bh);
++ wpc->ioend = xfs_alloc_ioend(inode, wpc->io_type, offset,
++ bdev, sector);
+ }
+
+ /*
+- * If the buffer doesn't fit into the bio we need to allocate a new
+- * one. This shouldn't happen more than once for a given buffer.
++ * If the block doesn't fit into the bio we need to allocate a new
++ * one. This shouldn't happen more than once for a given block.
+ */
+- while (xfs_bio_add_buffer(wpc->ioend->io_bio, bh) != bh->b_size)
+- xfs_chain_bio(wpc->ioend, wbc, bh);
++ while (bio_add_page(wpc->ioend->io_bio, page, len, poff) != len)
++ xfs_chain_bio(wpc->ioend, wbc, bdev, sector);
+
+- wpc->ioend->io_size += bh->b_size;
+- wpc->last_block = bh->b_blocknr;
+- xfs_start_buffer_writeback(bh);
++ wpc->ioend->io_size += len;
+ }
+
+ STATIC void
+@@ -948,7 +942,9 @@
+
+ lock_buffer(bh);
+ xfs_map_at_offset(inode, bh, &wpc->imap, file_offset);
+- xfs_add_to_ioend(inode, bh, file_offset, wpc, wbc, &submit_list);
++ xfs_add_to_ioend(inode, file_offset, page, wpc, wbc,
++ &submit_list);
++ xfs_start_buffer_writeback(bh);
+ count++;
+ }
+
+
diff --git a/patches.fixes/xfs-don-t-use-XFS_BMAPI_ENTRIRE-in-xfs_get_blocks.patch b/patches.fixes/xfs-don-t-use-XFS_BMAPI_ENTRIRE-in-xfs_get_blocks.patch
new file mode 100644
index 0000000000..6f22f5db8b
--- /dev/null
+++ b/patches.fixes/xfs-don-t-use-XFS_BMAPI_ENTRIRE-in-xfs_get_blocks.patch
@@ -0,0 +1,37 @@
+From 7d9df3c1631b0cb7eb4e59c934271adf0ead2f55 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Tue, 13 Mar 2018 23:15:31 -0700
+Subject: [PATCH] xfs: don't use XFS_BMAPI_ENTRIRE in xfs_get_blocks
+Git-commit: 7d9df3c1631b0cb7eb4e59c934271adf0ead2f55
+Patch-mainline: v4.17-rc1
+References: bsc#1137999
+
+There is no reason to get a mapping bigger than what we were asked for.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index a0afb6411417..c79a3ca20ef8 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -1331,8 +1331,8 @@ xfs_get_blocks(
+ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size);
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
+
+- error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
+- &imap, &nimaps, XFS_BMAPI_ENTIRE);
++ error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb, &imap,
++ &nimaps, 0);
+ if (error)
+ goto out_unlock;
+
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-don-t-use-XFS_BMAPI_IGSTATE-in-xfs_map_blocks.patch b/patches.fixes/xfs-don-t-use-XFS_BMAPI_IGSTATE-in-xfs_map_blocks.patch
new file mode 100644
index 0000000000..820f964236
--- /dev/null
+++ b/patches.fixes/xfs-don-t-use-XFS_BMAPI_IGSTATE-in-xfs_map_blocks.patch
@@ -0,0 +1,58 @@
+From a7b28f72ab90fe7a2f438360df5f6fda4237afdc Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:25:59 -0700
+Subject: [PATCH] xfs: don't use XFS_BMAPI_IGSTATE in xfs_map_blocks
+Git-commit: a7b28f72ab90fe7a2f438360df5f6fda4237afdc
+Patch-mainline: v4.19-rc1
+References: bsc#1138005
+
+We want to be able to use the extent state as a reliably indicator for
+the type of I/O, and stop using the buffer head state. For this we
+need to stop using the XFS_BMAPI_IGSTATE so that we don't see merged
+extents of different types.
+
+Based on a patch from Dave Chinner.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 1d1cb917cc6e..6b6150683343 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -373,7 +373,6 @@ xfs_map_blocks(
+ ssize_t count = i_blocksize(inode);
+ xfs_fileoff_t offset_fsb, end_fsb;
+ int error = 0;
+- int bmapi_flags = XFS_BMAPI_ENTIRE;
+ int nimaps = 1;
+
+ if (XFS_FORCED_SHUTDOWN(mp))
+@@ -393,8 +392,6 @@ xfs_map_blocks(
+ return 0;
+
+ ASSERT(type != XFS_IO_COW);
+- if (type == XFS_IO_UNWRITTEN)
+- bmapi_flags |= XFS_BMAPI_IGSTATE;
+
+ xfs_ilock(ip, XFS_ILOCK_SHARED);
+ ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
+@@ -406,7 +403,7 @@ xfs_map_blocks(
+ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
+ error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
+- imap, &nimaps, bmapi_flags);
++ imap, &nimaps, XFS_BMAPI_ENTIRE);
+ /*
+ * Truncate an overwrite extent if there's a pending CoW
+ * reservation before the end of this extent. This forces us
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cach.patch b/patches.fixes/xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cach.patch
new file mode 100644
index 0000000000..00e34e863c
--- /dev/null
+++ b/patches.fixes/xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cach.patch
@@ -0,0 +1,64 @@
+From aa6ee4ab69293969867ab09b57546d226ace3d7a Mon Sep 17 00:00:00 2001
+From: Brian Foster <bfoster@redhat.com>
+Date: Fri, 1 Feb 2019 09:36:36 -0800
+Subject: [PATCH] xfs: eof trim writeback mapping as soon as it is cached
+Git-commit: aa6ee4ab69293969867ab09b57546d226ace3d7a
+Patch-mainline: v5.0-rc6
+References: bsc#1138019
+
+The cached writeback mapping is EOF trimmed to try and avoid races
+between post-eof block management and writeback that result in
+sending cached data to a stale location. The cached mapping is
+currently trimmed on the validation check, which leaves a race
+window between the time the mapping is cached and when it is trimmed
+against the current inode size.
+
+For example, if a new mapping is cached by delalloc conversion on a
+blocksize == page size fs, we could cycle various locks, perform
+memory allocations, etc. in the writeback codepath before the
+associated mapping is eventually trimmed to i_size. This leaves
+enough time for a post-eof truncate and file append before the
+cached mapping is trimmed. The former event essentially invalidates
+a range of the cached mapping and the latter bumps the inode size
+such the trim on the next writepage event won't trim all of the
+invalid blocks. fstest generic/464 reproduces this scenario
+occasionally and causes a lost writeback and stale delalloc blocks
+warning on inode inactivation.
+
+To work around this problem, trim the cached writeback mapping as
+soon as it is cached in addition to on subsequent validation checks.
+This is a minor tweak to tighten the race window as much as possible
+until a proper invalidation mechanism is available.
+
+Fixes: 40214d128e07 ("xfs: trim writepage mapping to within eof")
+Cc: <stable@vger.kernel.org> # v4.14+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -495,6 +495,7 @@
+ }
+
+ wpc->imap = imap;
++ xfs_trim_extent_eof(&wpc->imap, ip);
+ trace_xfs_map_blocks_found(ip, offset, count, wpc->io_type, &imap);
+ return 0;
+ allocate_blocks:
+@@ -502,6 +503,7 @@
+ if (error)
+ return error;
+ wpc->imap = imap;
++ xfs_trim_extent_eof(&wpc->imap, ip);
+ trace_xfs_map_blocks_alloc(ip, offset, count, wpc->io_type, &imap);
+ return 0;
+ }
+
diff --git a/patches.fixes/xfs-fix-s_maxbytes-overflow-problems.patch b/patches.fixes/xfs-fix-s_maxbytes-overflow-problems.patch
new file mode 100644
index 0000000000..8fb4a0282c
--- /dev/null
+++ b/patches.fixes/xfs-fix-s_maxbytes-overflow-problems.patch
@@ -0,0 +1,58 @@
+From b4d8ad7fd3a18e6d92d4ebe858185c704604a57d Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Fri, 22 Dec 2017 13:14:34 -0800
+Subject: [PATCH] xfs: fix s_maxbytes overflow problems
+Git-commit: b4d8ad7fd3a18e6d92d4ebe858185c704604a57d
+Patch-mainline: v4.15-rc7
+References: bsc#1137996
+
+Fix some integer overflow problems if offset + count happen to be large
+enough to cause an integer overflow.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 4 ++--
+ fs/xfs/xfs_iomap.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 21e2d70884e1..4fc526a27a94 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -399,7 +399,7 @@ xfs_map_blocks(
+ (ip->i_df.if_flags & XFS_IFEXTENTS));
+ ASSERT(offset <= mp->m_super->s_maxbytes);
+
+- if ((xfs_ufsize_t)offset + count > mp->m_super->s_maxbytes)
++ if (offset > mp->m_super->s_maxbytes - count)
+ count = mp->m_super->s_maxbytes - offset;
+ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
+@@ -1312,7 +1312,7 @@ xfs_get_blocks(
+ lockmode = xfs_ilock_data_map_shared(ip);
+
+ ASSERT(offset <= mp->m_super->s_maxbytes);
+- if ((xfs_ufsize_t)offset + size > mp->m_super->s_maxbytes)
++ if (offset > mp->m_super->s_maxbytes - size)
+ size = mp->m_super->s_maxbytes - offset;
+ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size);
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
+diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
+index 7ab52a8bc0a9..66e1edbfb2b2 100644
+--- a/fs/xfs/xfs_iomap.c
++++ b/fs/xfs/xfs_iomap.c
+@@ -1006,7 +1006,7 @@ xfs_file_iomap_begin(
+ }
+
+ ASSERT(offset <= mp->m_super->s_maxbytes);
+- if ((xfs_fsize_t)offset + length > mp->m_super->s_maxbytes)
++ if (offset > mp->m_super->s_maxbytes - length)
+ length = mp->m_super->s_maxbytes - offset;
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
+ end_fsb = XFS_B_TO_FSB(mp, offset + length);
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-make-xfs_writepage_map-extent-map-centric.patch b/patches.fixes/xfs-make-xfs_writepage_map-extent-map-centric.patch
new file mode 100644
index 0000000000..a3005e1a61
--- /dev/null
+++ b/patches.fixes/xfs-make-xfs_writepage_map-extent-map-centric.patch
@@ -0,0 +1,261 @@
+From e2f6ad4624dfbde3a6c42c0cfbfc5553d93c3cae Mon Sep 17 00:00:00 2001
+From: Dave Chinner <dchinner@redhat.com>
+Date: Wed, 11 Jul 2018 22:26:00 -0700
+Subject: [PATCH] xfs: make xfs_writepage_map extent map centric
+Git-commit: e2f6ad4624dfbde3a6c42c0cfbfc5553d93c3cae
+Patch-mainline: v4.19-rc1
+References: bsc#1138009
+
+xfs_writepage_map() iterates over the bufferheads on a page to decide
+what sort of IO to do and what actions to take. However, when it comes
+to reflink and deciding when it needs to execute a COW operation, we no
+longer look at the bufferhead state but instead we ignore than and look
+up internal state held in the COW fork extent list.
+
+This means xfs_writepage_map() is somewhat confused. It does stuff, then
+ignores it, then tries to handle the impedence mismatch by shovelling the
+results inside the existing mapping code. It works, but it's a bit of a
+mess and it makes it hard to fix the cached map bug that the writepage
+code currently has.
+
+To unify the two different mechanisms, we first have to choose a direction.
+That's already been set - we're de-emphasising bufferheads so they are no
+longer a control structure as we need to do taht to allow for eventual
+removal. Hence we need to move away from looking at bufferhead state to
+determine what operations we need to perform.
+
+We can't completely get rid of bufferheads yet - they do contain some
+state that is absolutely necessary, such as whether that part of the page
+contains valid data or not (buffer_uptodate()). Other state in the
+bufferhead is redundant:
+
+ BH_dirty - the page is dirty, so we can ignore this and just
+ write it
+ BH_delay - we have delalloc extent info in the DATA fork extent
+ tree
+ BH_unwritten - same as BH_delay
+ BH_mapped - indicates we've already used it once for IO and it is
+ mapped to a disk address. Needs to be ignored for COW
+ blocks.
+
+The BH_mapped flag is an interesting case - it's supposed to indicate that
+it's already mapped to disk and so we can just use it "as is". In theory,
+we don't even have to do an extent lookup to find where to write it too,
+but we have to do that anyway to determine we are actually writing over a
+valid extent. Hence it's not even serving the purpose of avoiding a an
+extent lookup during writeback, and so we can pretty much ignore it.
+Especially as we have to ignore it for COW operations...
+
+Therefore, use the extent map as the source of information to tell us
+what actions we need to take and what sort of IO we should perform. The
+first step is to have xfs_map_blocks() set the io type according to what
+it looks up. This means it can easily handle both normal overwrite and
+COW cases. The only thing we also need to add is the ability to return
+hole mappings.
+
+We need to return and cache hole mappings now for the case of multiple
+blocks per page. We no longer use the BH_mapped to indicate a block over
+a hole, so we have to get that info from xfs_map_blocks(). We cache it so
+that holes that span two pages don't need separate lookups. This allows us
+to avoid ever doing write IO over a hole, too.
+
+Now that we have xfs_map_blocks() returning both a cached map and the type
+of IO we need to perform, we can rewrite xfs_writepage_map() to drop all
+the bufferhead control. It's also much simplified because it doesn't need
+to explicitly handle COW operations. Instead of iterating bufferheads, it
+iterates blocks within the page and then looks up what per-block state is
+required from the appropriate bufferhead. It then validates the cached
+map, and if it's not valid, we get a new map. If we don't get a valid map
+or it's over a hole, we skip the block.
+
+At this point, we have to remap the bufferhead via xfs_map_at_offset().
+As previously noted, we had to do this even if the buffer was already
+mapped as the mapping would be stale for XFS_IO_DELALLOC, XFS_IO_UNWRITTEN
+and XFS_IO_COW IO types. With xfs_map_blocks() now controlling the type,
+even XFS_IO_OVERWRITE types need remapping, as converted-but-not-yet-
+written delalloc extents beyond EOF can be reported at XFS_IO_OVERWRITE.
+Bufferheads that span such regions still need their BH_Delay flags cleared
+and their block numbers calculated, so we now unconditionally map each
+bufferhead before submission.
+
+But wait! There's more - remember the old "treat unwritten extents as
+holes on read" hack? Yeah, that means we can have a dirty page with
+unmapped, unwritten bufferheads that contain data! What makes these so
+special is that the unwritten "hole" bufferheads do not have a valid block
+device pointer, so if we attempt to write them xfs_add_to_ioend() blows
+up. So we make xfs_map_at_offset() do the "realtime or data device"
+lookup from the inode and ignore what was or wasn't put into the
+bufferhead when the buffer was instantiated.
+
+The astute reader will have realised by now that this code treats
+unwritten extents in multiple-blocks-per-page situations differently.
+If we get any combination of unwritten blocks on a dirty page that contain
+valid data in the page, we're going to convert them to real extents. This
+can actually be a win, because it means that pages with interleaving
+unwritten and written blocks will get converted to a single written extent
+with zeros replacing the interspersed unwritten blocks. This is actually
+good for reducing extent list and conversion overhead, and it means we
+issue a contiguous IO instead of lots of little ones. The downside is
+that we use up a little extra IO bandwidth. Neither of these seem like a
+bad thing given that spinning disks are seek sensitive, and SSDs/pmem have
+bandwidth to burn and the lower Io latency/CPU overhead of fewer, larger
+IOs will result in better performance on them...
+
+As a result of all this, the only state we actually care about from the
+bufferhead is a single flag - BH_Uptodate. We still use the bufferhead to
+pass some information to the bio via xfs_add_to_ioend(), but that is
+trivial to separate and pass explicitly. This means we really only need
+1 bit of state per block per page from the buffered write path in the
+writeback path. Everything else we do with the bufferhead is purely to
+make the buffered IO front end continue to work correctly. i.e we've
+pretty much marginalised bufferheads in the writeback path completely.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+[hch: forward port, refactor and split off bits into other commits]
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 88 ++++++++++++++++++++++--------------------------------
+ 1 file changed, 36 insertions(+), 52 deletions(-)
+
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -454,19 +454,19 @@
+ } else if (imap.br_startblock == HOLESTARTBLOCK) {
+ /* landed in a hole */
+ wpc->io_type = XFS_IO_HOLE;
+- }
++ } else {
++ if (isnullstartblock(imap.br_startblock)) {
++ /* got a delalloc extent */
++ wpc->io_type = XFS_IO_DELALLOC;
++ goto allocate_blocks;
++ }
+
+- if (wpc->io_type == XFS_IO_DELALLOC &&
+- (!nimaps || isnullstartblock(imap.br_startblock)))
+- goto allocate_blocks;
+-
+-#ifdef DEBUG
+- if (wpc->io_type == XFS_IO_UNWRITTEN) {
+- ASSERT(nimaps);
+- ASSERT(imap.br_startblock != HOLESTARTBLOCK);
+- ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
++ if (imap.br_state == XFS_EXT_UNWRITTEN)
++ wpc->io_type = XFS_IO_UNWRITTEN;
++ else
++ wpc->io_type = XFS_IO_OVERWRITE;
+ }
+-#endif
++
+ wpc->imap = imap;
+ trace_xfs_map_blocks_found(ip, offset, count, wpc->io_type, &imap);
+ return 0;
+@@ -745,6 +745,14 @@
+ set_buffer_mapped(bh);
+ clear_buffer_delay(bh);
+ clear_buffer_unwritten(bh);
++
++ /*
++ * If this is a realtime file, data may be on a different device.
++ * to that pointed to from the buffer_head b_bdev currently. We can't
++ * trust that the bufferhead has a already been mapped correctly, so
++ * set the bdev now.
++ */
++ bh->b_bdev = xfs_find_bdev_for_inode(inode);
+ }
+
+ /*
+@@ -900,58 +908,35 @@
+ {
+ LIST_HEAD(submit_list);
+ struct xfs_ioend *ioend, *next;
+- struct buffer_head *bh, *head;
++ struct buffer_head *bh;
+ ssize_t len = i_blocksize(inode);
+ uint64_t file_offset; /* file offset of page */
++ unsigned poffset; /* offset into page */
+ int error = 0;
+ int count = 0;
+- unsigned int new_type;
+
+- bh = head = page_buffers(page);
++ /*
++ * Walk the blocks on the page, and if we run off the end of the current
++ * map or find the current map invalid, grab a new one. We only use
++ * bufferheads here to check per-block state - they no longer control
++ * the iteration through the page. This allows us to replace the
++ * bufferhead with some other state tracking mechanism in future.
++ */
+ file_offset = page_offset(page);
+- do {
++ bh = page_buffers(page);
++ for (poffset = 0;
++ poffset < PAGE_SIZE;
++ poffset += len, file_offset += len, bh = bh->b_this_page) {
++ /* past the range we are writing, so nothing more to write. */
+ if (file_offset >= end_offset)
+ break;
+
+- /*
+- * set_page_dirty dirties all buffers in a page, independent
+- * of their state. The dirty state however is entirely
+- * meaningless for holes (!mapped && uptodate), so skip
+- * buffers covering holes here.
+- */
+- if (!buffer_mapped(bh) && buffer_uptodate(bh))
+- continue;
+-
+- if (buffer_unwritten(bh))
+- new_type = XFS_IO_UNWRITTEN;
+- else if (buffer_delay(bh))
+- new_type = XFS_IO_DELALLOC;
+- else if (buffer_uptodate(bh))
+- new_type = XFS_IO_OVERWRITE;
+- else {
++ if (!buffer_uptodate(bh)) {
+ if (PageUptodate(page))
+ ASSERT(buffer_mapped(bh));
+- /*
+- * This buffer is not uptodate and will not be
+- * written to disk.
+- */
+ continue;
+ }
+
+- /*
+- * If we already have a valid COW mapping keep using it.
+- */
+- if (wpc->io_type == XFS_IO_COW &&
+- xfs_imap_valid(inode, &wpc->imap, file_offset)) {
+- wpc->imap_valid = true;
+- new_type = XFS_IO_COW;
+- }
+-
+- if (wpc->io_type != new_type) {
+- wpc->io_type = new_type;
+- wpc->imap_valid = false;
+- }
+-
+ if (wpc->imap_valid)
+ wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap,
+ file_offset);
+@@ -976,11 +961,10 @@
+ continue;
+
+ lock_buffer(bh);
+- if (wpc->io_type != XFS_IO_OVERWRITE)
+- xfs_map_at_offset(inode, bh, &wpc->imap, file_offset);
++ xfs_map_at_offset(inode, bh, &wpc->imap, file_offset);
+ xfs_add_to_ioend(inode, bh, file_offset, wpc, wbc, &submit_list);
+ count++;
+- } while (file_offset += len, ((bh = bh->b_this_page) != head));
++ }
+
+ ASSERT(wpc->ioend || list_empty(&submit_list));
+
+
diff --git a/patches.fixes/xfs-minor-cleanup-for-xfs_get_blocks.patch b/patches.fixes/xfs-minor-cleanup-for-xfs_get_blocks.patch
new file mode 100644
index 0000000000..5e5bc4e7f8
--- /dev/null
+++ b/patches.fixes/xfs-minor-cleanup-for-xfs_get_blocks.patch
@@ -0,0 +1,51 @@
+From 1d4352de511f4c9b6f4466c8fd4cfc25b14869b7 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Tue, 13 Mar 2018 23:15:32 -0700
+Subject: [PATCH] xfs: minor cleanup for xfs_get_blocks
+Git-commit: 1d4352de511f4c9b6f4466c8fd4cfc25b14869b7
+Patch-mainline: v4.17-rc1
+References: bsc#1138000
+
+Simplify the control flow a bit in preparation for O_ATOMIC-related
+changes.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index c79a3ca20ef8..19eadc807056 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -1335,17 +1335,16 @@ xfs_get_blocks(
+ &nimaps, 0);
+ if (error)
+ goto out_unlock;
+-
+- if (nimaps) {
+- trace_xfs_get_blocks_found(ip, offset, size,
+- imap.br_state == XFS_EXT_UNWRITTEN ?
+- XFS_IO_UNWRITTEN : XFS_IO_OVERWRITE, &imap);
+- xfs_iunlock(ip, lockmode);
+- } else {
++ if (!nimaps) {
+ trace_xfs_get_blocks_notfound(ip, offset, size);
+ goto out_unlock;
+ }
+
++ trace_xfs_get_blocks_found(ip, offset, size,
++ imap.br_state == XFS_EXT_UNWRITTEN ?
++ XFS_IO_UNWRITTEN : XFS_IO_OVERWRITE, &imap);
++ xfs_iunlock(ip, lockmode);
++
+ /* trim mapping down to size requested */
+ xfs_map_trim_size(inode, iblock, bh_result, &imap, offset, size);
+
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-move-all-writeback-buffer_head-manipulation-into.patch b/patches.fixes/xfs-move-all-writeback-buffer_head-manipulation-into.patch
new file mode 100644
index 0000000000..6eaa73f074
--- /dev/null
+++ b/patches.fixes/xfs-move-all-writeback-buffer_head-manipulation-into.patch
@@ -0,0 +1,77 @@
+From 6d465e895343225e3ad35fe10d7b3e9f2f18faec Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:26:03 -0700
+Subject: [PATCH] xfs: move all writeback buffer_head manipulation into
+ xfs_map_at_offset
+Git-commit: 6d465e895343225e3ad35fe10d7b3e9f2f18faec
+Patch-mainline: v4.19-rc1
+References: bsc#1138014
+
+This keeps it in a single place so it can be made otional more easily.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 22 +++++-----------------
+ 1 file changed, 5 insertions(+), 17 deletions(-)
+
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -507,21 +507,6 @@
+ }
+
+ STATIC void
+-xfs_start_buffer_writeback(
+- struct buffer_head *bh)
+-{
+- ASSERT(buffer_mapped(bh));
+- ASSERT(buffer_locked(bh));
+- ASSERT(!buffer_delay(bh));
+- ASSERT(!buffer_unwritten(bh));
+-
+- bh->b_end_io = NULL;
+- set_buffer_async_write(bh);
+- set_buffer_uptodate(bh);
+- clear_buffer_dirty(bh);
+-}
+-
+-STATIC void
+ xfs_start_page_writeback(
+ struct page *page,
+ int clear_dirty)
+@@ -738,6 +723,7 @@
+ ASSERT(imap->br_startblock != HOLESTARTBLOCK);
+ ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
+
++ lock_buffer(bh);
+ xfs_map_buffer(inode, bh, imap, offset);
+ set_buffer_mapped(bh);
+ clear_buffer_delay(bh);
+@@ -750,6 +736,10 @@
+ * set the bdev now.
+ */
+ bh->b_bdev = xfs_find_bdev_for_inode(inode);
++ bh->b_end_io = NULL;
++ set_buffer_async_write(bh);
++ set_buffer_uptodate(bh);
++ clear_buffer_dirty(bh);
+ }
+
+ /*
+@@ -940,11 +930,9 @@
+ if (wpc->io_type == XFS_IO_HOLE)
+ continue;
+
+- lock_buffer(bh);
+ xfs_map_at_offset(inode, bh, &wpc->imap, file_offset);
+ xfs_add_to_ioend(inode, file_offset, page, wpc, wbc,
+ &submit_list);
+- xfs_start_buffer_writeback(bh);
+ count++;
+ }
+
+
diff --git a/patches.fixes/xfs-refactor-the-tail-of-xfs_writepage_map.patch b/patches.fixes/xfs-refactor-the-tail-of-xfs_writepage_map.patch
new file mode 100644
index 0000000000..ed1b2f742b
--- /dev/null
+++ b/patches.fixes/xfs-refactor-the-tail-of-xfs_writepage_map.patch
@@ -0,0 +1,113 @@
+From 8e1f065bea1b1c128c92ef7e386779a23cd5d342 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:26:04 -0700
+Subject: [PATCH] xfs: refactor the tail of xfs_writepage_map
+Git-commit: 8e1f065bea1b1c128c92ef7e386779a23cd5d342
+Patch-mainline: v4.19-rc1
+References: bsc#1138016
+
+Rejuggle how we deal with the different error vs non-error and have
+ioends vs not have ioend cases to keep the fast path streamlined, and
+the duplicate code at a minimum.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 65 +++++++++++++++++++++++++++----------------------------
+ 1 file changed, 32 insertions(+), 33 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index af9224ea4ebf..c8e0d3055153 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -854,7 +854,14 @@ xfs_writepage_map(
+ * submission of outstanding ioends on the writepage context so they are
+ * treated correctly on error.
+ */
+- if (count) {
++ if (unlikely(error)) {
++ if (!count) {
++ xfs_aops_discard_page(page);
++ ClearPageUptodate(page);
++ unlock_page(page);
++ goto done;
++ }
++
+ /*
+ * If the page was not fully cleaned, we need to ensure that the
+ * higher layers come back to it correctly. That means we need
+@@ -863,43 +870,35 @@ xfs_writepage_map(
+ * so another attempt to write this page in this writeback sweep
+ * will be made.
+ */
+- if (error) {
+- set_page_writeback_keepwrite(page);
+- } else {
+- clear_page_dirty_for_io(page);
+- set_page_writeback(page);
+- }
+- unlock_page(page);
+-
+- /*
+- * Preserve the original error if there was one, otherwise catch
+- * submission errors here and propagate into subsequent ioend
+- * submissions.
+- */
+- list_for_each_entry_safe(ioend, next, &submit_list, io_list) {
+- int error2;
+-
+- list_del_init(&ioend->io_list);
+- error2 = xfs_submit_ioend(wbc, ioend, error);
+- if (error2 && !error)
+- error = error2;
+- }
+- } else if (error) {
+- xfs_aops_discard_page(page);
+- ClearPageUptodate(page);
+- unlock_page(page);
++ set_page_writeback_keepwrite(page);
+ } else {
+- /*
+- * We can end up here with no error and nothing to write if we
+- * race with a partial page truncate on a sub-page block sized
+- * filesystem. In that case we need to mark the page clean.
+- */
+ clear_page_dirty_for_io(page);
+ set_page_writeback(page);
+- unlock_page(page);
+- end_page_writeback(page);
+ }
+
++ unlock_page(page);
++
++ /*
++ * Preserve the original error if there was one, otherwise catch
++ * submission errors here and propagate into subsequent ioend
++ * submissions.
++ */
++ list_for_each_entry_safe(ioend, next, &submit_list, io_list) {
++ int error2;
++
++ list_del_init(&ioend->io_list);
++ error2 = xfs_submit_ioend(wbc, ioend, error);
++ if (error2 && !error)
++ error = error2;
++ }
++
++ /*
++ * We can end up here with no error and nothing to write if we race with
++ * a partial page truncate on a sub-page block sized filesystem.
++ */
++ if (!count)
++ end_page_writeback(page);
++done:
+ mapping_set_error(page->mapping, error);
+ return error;
+ }
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-remove-XFS_IO_INVALID.patch b/patches.fixes/xfs-remove-XFS_IO_INVALID.patch
new file mode 100644
index 0000000000..9c99f252b0
--- /dev/null
+++ b/patches.fixes/xfs-remove-XFS_IO_INVALID.patch
@@ -0,0 +1,79 @@
+From 97e5a6e6dc44b9ea660f85de084f6e38cb5cf39c Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Thu, 18 Oct 2018 17:17:50 +1100
+Subject: [PATCH] xfs: remove XFS_IO_INVALID
+Git-commit: 97e5a6e6dc44b9ea660f85de084f6e38cb5cf39c
+Patch-mainline: v4.20-rc1
+References: bsc#1138017
+
+The invalid state isn't any different from a hole, so merge the two
+states. Use the more descriptive hole name, but keep it as the first
+value of the enum to catch uninitialized fields.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Signed-off-by: Dave Chinner <david@fromorbit.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 4 ++--
+ fs/xfs/xfs_aops.h | 14 ++++++--------
+ 2 files changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 49f5f5896a43..338b9d9984e0 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -917,7 +917,7 @@ xfs_vm_writepage(
+ struct writeback_control *wbc)
+ {
+ struct xfs_writepage_ctx wpc = {
+- .io_type = XFS_IO_INVALID,
++ .io_type = XFS_IO_HOLE,
+ };
+ int ret;
+
+@@ -933,7 +933,7 @@ xfs_vm_writepages(
+ struct writeback_control *wbc)
+ {
+ struct xfs_writepage_ctx wpc = {
+- .io_type = XFS_IO_INVALID,
++ .io_type = XFS_IO_HOLE,
+ };
+ int ret;
+
+diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h
+index 9af867951a10..494b4338446e 100644
+--- a/fs/xfs/xfs_aops.h
++++ b/fs/xfs/xfs_aops.h
+@@ -12,21 +12,19 @@ extern struct bio_set xfs_ioend_bioset;
+ * Types of I/O for bmap clustering and I/O completion tracking.
+ */
+ enum {
+- XFS_IO_INVALID, /* initial state */
++ XFS_IO_HOLE, /* covers region without any block allocation */
+ XFS_IO_DELALLOC, /* covers delalloc region */
+ XFS_IO_UNWRITTEN, /* covers allocated but uninitialized data */
+ XFS_IO_OVERWRITE, /* covers already allocated extent */
+ XFS_IO_COW, /* covers copy-on-write extent */
+- XFS_IO_HOLE, /* covers region without any block allocation */
+ };
+
+ #define XFS_IO_TYPES \
+- { XFS_IO_INVALID, "invalid" }, \
+- { XFS_IO_DELALLOC, "delalloc" }, \
+- { XFS_IO_UNWRITTEN, "unwritten" }, \
+- { XFS_IO_OVERWRITE, "overwrite" }, \
+- { XFS_IO_COW, "CoW" }, \
+- { XFS_IO_HOLE, "hole" }
++ { XFS_IO_HOLE, "hole" }, \
++ { XFS_IO_DELALLOC, "delalloc" }, \
++ { XFS_IO_UNWRITTEN, "unwritten" }, \
++ { XFS_IO_OVERWRITE, "overwrite" }, \
++ { XFS_IO_COW, "CoW" }
+
+ /*
+ * Structure for buffered I/O completions.
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-remove-the-imap_valid-flag.patch b/patches.fixes/xfs-remove-the-imap_valid-flag.patch
new file mode 100644
index 0000000000..41d88d2a53
--- /dev/null
+++ b/patches.fixes/xfs-remove-the-imap_valid-flag.patch
@@ -0,0 +1,179 @@
+From 889c65b3f60af4c840896478fc6151363ffa279f Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:26:02 -0700
+Subject: [PATCH] xfs: remove the imap_valid flag
+Git-commit: 889c65b3f60af4c840896478fc6151363ffa279f
+Patch-mainline: v4.19-rc1
+References: bsc#1138012
+
+Simplify the way we check for a valid imap - we know we have a valid
+mapping after xfs_map_blocks returned successfully, and we know we can
+call xfs_imap_valid on any imap, as it will always fail on a
+zero-initialized map.
+
+We can also remove the xfs_imap_valid function and fold it into
+xfs_map_blocks now.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 89 ++++++++++++++++++++++++-------------------------------
+ 1 file changed, 38 insertions(+), 51 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 0bfcc2d06658..09092f10cff3 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -30,7 +30,6 @@
+ */
+ struct xfs_writepage_ctx {
+ struct xfs_bmbt_irec imap;
+- bool imap_valid;
+ unsigned int io_type;
+ struct xfs_ioend *ioend;
+ sector_t last_block;
+@@ -370,15 +369,47 @@ xfs_map_blocks(
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ ssize_t count = i_blocksize(inode);
+- xfs_fileoff_t offset_fsb, end_fsb;
++ xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset), end_fsb;
+ struct xfs_bmbt_irec imap;
+ int whichfork = XFS_DATA_FORK;
+ struct xfs_iext_cursor icur;
++ bool imap_valid;
+ int error = 0;
+
++ /*
++ * We have to make sure the cached mapping is within EOF to protect
++ * against eofblocks trimming on file release leaving us with a stale
++ * mapping. Otherwise, a page for a subsequent file extending buffered
++ * write could get picked up by this writeback cycle and written to the
++ * wrong blocks.
++ *
++ * Note that what we really want here is a generic mapping invalidation
++ * mechanism to protect us from arbitrary extent modifying contexts, not
++ * just eofblocks.
++ */
++ xfs_trim_extent_eof(&wpc->imap, ip);
++
++ /*
++ * COW fork blocks can overlap data fork blocks even if the blocks
++ * aren't shared. COW I/O always takes precedent, so we must always
++ * check for overlap on reflink inodes unless the mapping is already a
++ * COW one.
++ */
++ imap_valid = offset_fsb >= wpc->imap.br_startoff &&
++ offset_fsb < wpc->imap.br_startoff + wpc->imap.br_blockcount;
++ if (imap_valid &&
++ (!xfs_is_reflink_inode(ip) || wpc->io_type == XFS_IO_COW))
++ return 0;
++
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return -EIO;
+
++ /*
++ * If we don't have a valid map, now it's time to get a new one for this
++ * offset. This will convert delayed allocations (including COW ones)
++ * into real extents. If we return without a valid map, it means we
++ * landed in a hole and we skip the block.
++ */
+ xfs_ilock(ip, XFS_ILOCK_SHARED);
+ ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
+ (ip->i_df.if_flags & XFS_IFEXTENTS));
+@@ -387,7 +418,6 @@ xfs_map_blocks(
+ if (offset > mp->m_super->s_maxbytes - count)
+ count = mp->m_super->s_maxbytes - offset;
+ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
+- offset_fsb = XFS_B_TO_FSBT(mp, offset);
+
+ /*
+ * Check if this is offset is covered by a COW extents, and if yes use
+@@ -420,7 +450,7 @@ xfs_map_blocks(
+ /*
+ * Map valid and no COW extent in the way? We're done.
+ */
+- if (wpc->imap_valid) {
++ if (imap_valid) {
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+ return 0;
+ }
+@@ -465,31 +495,6 @@ xfs_map_blocks(
+ return 0;
+ }
+
+-STATIC bool
+-xfs_imap_valid(
+- struct inode *inode,
+- struct xfs_bmbt_irec *imap,
+- xfs_off_t offset)
+-{
+- offset >>= inode->i_blkbits;
+-
+- /*
+- * We have to make sure the cached mapping is within EOF to protect
+- * against eofblocks trimming on file release leaving us with a stale
+- * mapping. Otherwise, a page for a subsequent file extending buffered
+- * write could get picked up by this writeback cycle and written to the
+- * wrong blocks.
+- *
+- * Note that what we really want here is a generic mapping invalidation
+- * mechanism to protect us from arbitrary extent modifying contexts, not
+- * just eofblocks.
+- */
+- xfs_trim_extent_eof(imap, XFS_I(inode));
+-
+- return offset >= imap->br_startoff &&
+- offset < imap->br_startoff + imap->br_blockcount;
+-}
+-
+ STATIC void
+ xfs_start_buffer_writeback(
+ struct buffer_head *bh)
+@@ -856,27 +861,10 @@ xfs_writepage_map(
+ continue;
+ }
+
+- if (wpc->imap_valid)
+- wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap,
+- file_offset);
+-
+- /*
+- * COW fork blocks can overlap data fork blocks even if the
+- * blocks aren't shared. COW I/O always takes precedent, so we
+- * must always check for overlap on reflink inodes unless the
+- * mapping is already a COW one.
+- */
+- if (!wpc->imap_valid ||
+- (xfs_is_reflink_inode(XFS_I(inode)) &&
+- wpc->io_type != XFS_IO_COW)) {
+- error = xfs_map_blocks(wpc, inode, file_offset);
+- if (error)
+- goto out;
+- wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap,
+- file_offset);
+- }
+-
+- if (!wpc->imap_valid || wpc->io_type == XFS_IO_HOLE)
++ error = xfs_map_blocks(wpc, inode, file_offset);
++ if (error)
++ break;
++ if (wpc->io_type == XFS_IO_HOLE)
+ continue;
+
+ lock_buffer(bh);
+@@ -887,7 +875,6 @@ xfs_writepage_map(
+
+ ASSERT(wpc->ioend || list_empty(&submit_list));
+
+-out:
+ /*
+ * On error, we have to fail the ioend here because we have locked
+ * buffers in the ioend. If we don't do this, we'll deadlock
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-remove-unused-parameter-from-xfs_writepage_map.patch b/patches.fixes/xfs-remove-unused-parameter-from-xfs_writepage_map.patch
new file mode 100644
index 0000000000..f557a94f8c
--- /dev/null
+++ b/patches.fixes/xfs-remove-unused-parameter-from-xfs_writepage_map.patch
@@ -0,0 +1,52 @@
+From 2d5f4b5bebccfe983715ebc9255151e611234643 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Mon, 27 Nov 2017 09:50:22 -0800
+Subject: [PATCH] xfs: remove unused parameter from xfs_writepage_map
+Git-commit: 2d5f4b5bebccfe983715ebc9255151e611234643
+Patch-mainline: v4.15-rc2
+References: bsc#1137995
+
+The first thing that xfs_writepage_map does is clobber the offset
+parameter. Since we never use the passed-in value, turn the parameter
+into a local variable. This gets rid of an UBSAN warning in generic/466.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index b0cccf8a81a8..21e2d70884e1 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -896,13 +896,13 @@ xfs_writepage_map(
+ struct writeback_control *wbc,
+ struct inode *inode,
+ struct page *page,
+- loff_t offset,
+- uint64_t end_offset)
++ uint64_t end_offset)
+ {
+ LIST_HEAD(submit_list);
+ struct xfs_ioend *ioend, *next;
+ struct buffer_head *bh, *head;
+ ssize_t len = i_blocksize(inode);
++ uint64_t offset;
+ int error = 0;
+ int count = 0;
+ int uptodate = 1;
+@@ -1146,7 +1146,7 @@ xfs_do_writepage(
+ end_offset = offset;
+ }
+
+- return xfs_writepage_map(wpc, wbc, inode, page, offset, end_offset);
++ return xfs_writepage_map(wpc, wbc, inode, page, end_offset);
+
+ redirty:
+ redirty_page_for_writepage(wbc, page);
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-remove-xfs_map_cow.patch b/patches.fixes/xfs-remove-xfs_map_cow.patch
new file mode 100644
index 0000000000..0d9b9e0a2e
--- /dev/null
+++ b/patches.fixes/xfs-remove-xfs_map_cow.patch
@@ -0,0 +1,322 @@
+From 5c665e5b5af6b8ad3e38ee73cb495ec695bcf589 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:25:59 -0700
+Subject: [PATCH] xfs: remove xfs_map_cow
+Git-commit: 5c665e5b5af6b8ad3e38ee73cb495ec695bcf589
+Patch-mainline: v4.19-rc1
+References: bsc#1138007
+
+We can handle the existing cow mapping case as a special case directly
+in xfs_writepage_map, and share code for allocating delalloc blocks
+with regular I/O in xfs_map_blocks. This means we need to always
+call xfs_map_blocks for reflink inodes, but we can still skip most of
+the work if it turns out that there is no COW mapping overlapping the
+current block.
+
+As a subtle detail we need to start caching holes in the wpc to deal
+with the case of COW reservations between EOF. But we'll need that
+infrastructure later anyway, so this is no big deal.
+
+Based on a patch from Dave Chinner.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 195 ++++++++++++++++++++++++++----------------------------
+ fs/xfs/xfs_aops.h | 4 -
+ 2 files changed, 100 insertions(+), 99 deletions(-)
+
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -375,70 +375,107 @@
+
+ STATIC int
+ xfs_map_blocks(
++ struct xfs_writepage_ctx *wpc,
+ struct inode *inode,
+- loff_t offset,
+- struct xfs_bmbt_irec *imap,
+- int type)
++ loff_t offset)
+ {
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ ssize_t count = i_blocksize(inode);
+- xfs_fileoff_t offset_fsb, end_fsb;
++ xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset), end_fsb;
++ struct xfs_bmbt_irec imap;
++ int whichfork = XFS_DATA_FORK;
+ int error = 0;
+ int nimaps = 1;
+
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return -EIO;
+
+- /*
+- * Truncate can race with writeback since writeback doesn't take the
+- * iolock and truncate decreases the file size before it starts
+- * truncating the pages between new_size and old_size. Therefore, we
+- * can end up in the situation where writeback gets a CoW fork mapping
+- * but the truncate makes the mapping invalid and we end up in here
+- * trying to get a new mapping. Bail out here so that we simply never
+- * get a valid mapping and so we drop the write altogether. The page
+- * truncation will kill the contents anyway.
+- */
+- if (type == XFS_IO_COW && offset > i_size_read(inode))
+- return 0;
+-
+- ASSERT(type != XFS_IO_COW);
+-
+ xfs_ilock(ip, XFS_ILOCK_SHARED);
+ ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE ||
+ (ip->i_df.if_flags & XFS_IFEXTENTS));
+ ASSERT(offset <= mp->m_super->s_maxbytes);
+
++ if (xfs_is_reflink_inode(ip) &&
++ xfs_reflink_find_cow_mapping(ip, offset, &imap)) {
++ xfs_iunlock(ip, XFS_ILOCK_SHARED);
++ /*
++ * Truncate can race with writeback since writeback doesn't
++ * take the iolock and truncate decreases the file size before
++ * it starts truncating the pages between new_size and old_size.
++ * Therefore, we can end up in the situation where writeback
++ * gets a CoW fork mapping but the truncate makes the mapping
++ * invalid and we end up in here trying to get a new mapping.
++ * bail out here so that we simply never get a valid mapping
++ * and so we drop the write altogether. The page truncation
++ * will kill the contents anyway.
++ */
++ if (offset > i_size_read(inode)) {
++ wpc->io_type = XFS_IO_HOLE;
++ return 0;
++ }
++ whichfork = XFS_COW_FORK;
++ wpc->io_type = XFS_IO_COW;
++ goto allocate_blocks;
++ }
++
++ /*
++ * Map valid and no COW extent in the way? We're done.
++ */
++ if (wpc->imap_valid) {
++ xfs_iunlock(ip, XFS_ILOCK_SHARED);
++ return 0;
++ }
++
++ /*
++ * If we don't have a valid map, now it's time to get a new one for this
++ * offset. This will convert delayed allocations (including COW ones)
++ * into real extents.
++ */
+ if (offset > mp->m_super->s_maxbytes - count)
+ count = mp->m_super->s_maxbytes - offset;
+ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
+ error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
+- imap, &nimaps, XFS_BMAPI_ENTIRE);
++ &imap, &nimaps, XFS_BMAPI_ENTIRE);
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+-
+ if (error)
+ return error;
+
+- if (type == XFS_IO_DELALLOC &&
+- (!nimaps || isnullstartblock(imap->br_startblock))) {
+- error = xfs_iomap_write_allocate(ip, XFS_DATA_FORK, offset,
+- imap);
+- if (!error)
+- trace_xfs_map_blocks_alloc(ip, offset, count, type, imap);
+- return error;
++ if (!nimaps) {
++ /*
++ * Lookup returns no match? Beyond eof? regardless,
++ * return it as a hole so we don't write it
++ */
++ imap.br_startoff = offset_fsb;
++ imap.br_blockcount = end_fsb - offset_fsb;
++ imap.br_startblock = HOLESTARTBLOCK;
++ wpc->io_type = XFS_IO_HOLE;
++ } else if (imap.br_startblock == HOLESTARTBLOCK) {
++ /* landed in a hole */
++ wpc->io_type = XFS_IO_HOLE;
+ }
+
++ if (wpc->io_type == XFS_IO_DELALLOC &&
++ (!nimaps || isnullstartblock(imap.br_startblock)))
++ goto allocate_blocks;
++
+ #ifdef DEBUG
+- if (type == XFS_IO_UNWRITTEN) {
++ if (wpc->io_type == XFS_IO_UNWRITTEN) {
+ ASSERT(nimaps);
+- ASSERT(imap->br_startblock != HOLESTARTBLOCK);
+- ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
++ ASSERT(imap.br_startblock != HOLESTARTBLOCK);
++ ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
+ }
+ #endif
+- if (nimaps)
+- trace_xfs_map_blocks_found(ip, offset, count, type, imap);
++ wpc->imap = imap;
++ trace_xfs_map_blocks_found(ip, offset, count, wpc->io_type, &imap);
++ return 0;
++allocate_blocks:
++ error = xfs_iomap_write_allocate(ip, whichfork, offset, &imap);
++ if (error)
++ return error;
++ wpc->imap = imap;
++ trace_xfs_map_blocks_alloc(ip, offset, count, wpc->io_type, &imap);
+ return 0;
+ }
+
+@@ -837,56 +874,6 @@
+ return;
+ }
+
+-static int
+-xfs_map_cow(
+- struct xfs_writepage_ctx *wpc,
+- struct inode *inode,
+- loff_t offset,
+- unsigned int *new_type)
+-{
+- struct xfs_inode *ip = XFS_I(inode);
+- struct xfs_bmbt_irec imap;
+- bool is_cow = false;
+- int error;
+-
+- /*
+- * If we already have a valid COW mapping keep using it.
+- */
+- if (wpc->io_type == XFS_IO_COW) {
+- wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap, offset);
+- if (wpc->imap_valid) {
+- *new_type = XFS_IO_COW;
+- return 0;
+- }
+- }
+-
+- /*
+- * Else we need to check if there is a COW mapping at this offset.
+- */
+- xfs_ilock(ip, XFS_ILOCK_SHARED);
+- is_cow = xfs_reflink_find_cow_mapping(ip, offset, &imap);
+- xfs_iunlock(ip, XFS_ILOCK_SHARED);
+-
+- if (!is_cow)
+- return 0;
+-
+- /*
+- * And if the COW mapping has a delayed extent here we need to
+- * allocate real space for it now.
+- */
+- if (isnullstartblock(imap.br_startblock)) {
+- error = xfs_iomap_write_allocate(ip, XFS_COW_FORK, offset,
+- &imap);
+- if (error)
+- return error;
+- }
+-
+- wpc->io_type = *new_type = XFS_IO_COW;
+- wpc->imap_valid = true;
+- wpc->imap = imap;
+- return 0;
+-}
+-
+ /*
+ * We implement an immediate ioend submission policy here to avoid needing to
+ * chain multiple ioends and hence nest mempool allocations which can violate
+@@ -915,7 +902,7 @@
+ struct xfs_ioend *ioend, *next;
+ struct buffer_head *bh, *head;
+ ssize_t len = i_blocksize(inode);
+- uint64_t offset;
++ uint64_t offset; /* file offset of page */
+ int error = 0;
+ int count = 0;
+ unsigned int new_type;
+@@ -951,10 +938,13 @@
+ continue;
+ }
+
+- if (xfs_is_reflink_inode(XFS_I(inode))) {
+- error = xfs_map_cow(wpc, inode, offset, &new_type);
+- if (error)
+- goto out;
++ /*
++ * If we already have a valid COW mapping keep using it.
++ */
++ if (wpc->io_type == XFS_IO_COW &&
++ xfs_imap_valid(inode, &wpc->imap, offset)) {
++ wpc->imap_valid = true;
++ new_type = XFS_IO_COW;
+ }
+
+ if (wpc->io_type != new_type) {
+@@ -965,22 +955,31 @@
+ if (wpc->imap_valid)
+ wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap,
+ offset);
+- if (!wpc->imap_valid) {
+- error = xfs_map_blocks(inode, offset, &wpc->imap,
+- wpc->io_type);
++
++ /*
++ * COW fork blocks can overlap data fork blocks even if the
++ * blocks aren't shared. COW I/O always takes precedent, so we
++ * must always check for overlap on reflink inodes unless the
++ * mapping is already a COW one.
++ */
++ if (!wpc->imap_valid ||
++ (xfs_is_reflink_inode(XFS_I(inode)) &&
++ wpc->io_type != XFS_IO_COW)) {
++ error = xfs_map_blocks(wpc, inode, offset);
+ if (error)
+ goto out;
+ wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap,
+ offset);
+ }
+- if (wpc->imap_valid) {
+- lock_buffer(bh);
+- if (wpc->io_type != XFS_IO_OVERWRITE)
+- xfs_map_at_offset(inode, bh, &wpc->imap, offset);
+- xfs_add_to_ioend(inode, bh, offset, wpc, wbc, &submit_list);
+- count++;
+- }
+
++ if (!wpc->imap_valid || wpc->io_type == XFS_IO_HOLE)
++ continue;
++
++ lock_buffer(bh);
++ if (wpc->io_type != XFS_IO_OVERWRITE)
++ xfs_map_at_offset(inode, bh, &wpc->imap, offset);
++ xfs_add_to_ioend(inode, bh, offset, wpc, wbc, &submit_list);
++ count++;
+ } while (offset += len, ((bh = bh->b_this_page) != head));
+
+ ASSERT(wpc->ioend || list_empty(&submit_list));
+--- a/fs/xfs/xfs_aops.h
++++ b/fs/xfs/xfs_aops.h
+@@ -29,6 +29,7 @@
+ XFS_IO_UNWRITTEN, /* covers allocated but uninitialized data */
+ XFS_IO_OVERWRITE, /* covers already allocated extent */
+ XFS_IO_COW, /* covers copy-on-write extent */
++ XFS_IO_HOLE, /* covers region without any block allocation */
+ };
+
+ #define XFS_IO_TYPES \
+@@ -36,7 +37,8 @@
+ { XFS_IO_DELALLOC, "delalloc" }, \
+ { XFS_IO_UNWRITTEN, "unwritten" }, \
+ { XFS_IO_OVERWRITE, "overwrite" }, \
+- { XFS_IO_COW, "CoW" }
++ { XFS_IO_COW, "CoW" }, \
++ { XFS_IO_HOLE, "hole" }
+
+ /*
+ * Structure for buffered I/O completions.
+
diff --git a/patches.fixes/xfs-remove-xfs_reflink_find_cow_mapping.patch b/patches.fixes/xfs-remove-xfs_reflink_find_cow_mapping.patch
new file mode 100644
index 0000000000..7b9971abc8
--- /dev/null
+++ b/patches.fixes/xfs-remove-xfs_reflink_find_cow_mapping.patch
@@ -0,0 +1,130 @@
+From 060d4eaa0bf30a8fc2d189e4d4922f6e9027857b Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:26:01 -0700
+Subject: [PATCH] xfs: remove xfs_reflink_find_cow_mapping
+Git-commit: 060d4eaa0bf30a8fc2d189e4d4922f6e9027857b
+Patch-mainline: v4.19-rc1
+References: bsc#1138010
+
+We only have one caller left, and open coding the simple extent list
+lookup in it allows us to make the code both more understandable and
+reuse calculations and variables already present.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 19 +++++++++++++------
+ fs/xfs/xfs_reflink.c | 29 -----------------------------
+ fs/xfs/xfs_reflink.h | 2 --
+ fs/xfs/xfs_trace.h | 1 -
+ 4 files changed, 13 insertions(+), 38 deletions(-)
+
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -382,9 +382,10 @@
+ struct xfs_inode *ip = XFS_I(inode);
+ struct xfs_mount *mp = ip->i_mount;
+ ssize_t count = i_blocksize(inode);
+- xfs_fileoff_t offset_fsb = XFS_B_TO_FSBT(mp, offset), end_fsb;
++ xfs_fileoff_t offset_fsb, end_fsb;
+ struct xfs_bmbt_irec imap;
+ int whichfork = XFS_DATA_FORK;
++ struct xfs_iext_cursor icur;
+ int error = 0;
+ int nimaps = 1;
+
+@@ -396,8 +397,18 @@
+ (ip->i_df.if_flags & XFS_IFEXTENTS));
+ ASSERT(offset <= mp->m_super->s_maxbytes);
+
++ if (offset > mp->m_super->s_maxbytes - count)
++ count = mp->m_super->s_maxbytes - offset;
++ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
++ offset_fsb = XFS_B_TO_FSBT(mp, offset);
++
++ /*
++ * Check if this is offset is covered by a COW extents, and if yes use
++ * it directly instead of looking up anything in the data fork.
++ */
+ if (xfs_is_reflink_inode(ip) &&
+- xfs_reflink_find_cow_mapping(ip, offset, &imap)) {
++ xfs_iext_lookup_extent(ip, ip->i_cowfp, offset_fsb, &icur, &imap) &&
++ imap.br_startoff <= offset_fsb) {
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+ /*
+ * Truncate can race with writeback since writeback doesn't
+@@ -432,10 +443,6 @@
+ * offset. This will convert delayed allocations (including COW ones)
+ * into real extents.
+ */
+- if (offset > mp->m_super->s_maxbytes - count)
+- count = mp->m_super->s_maxbytes - offset;
+- end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count);
+- offset_fsb = XFS_B_TO_FSBT(mp, offset);
+ error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
+ &imap, &nimaps, XFS_BMAPI_ENTIRE);
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+--- a/fs/xfs/xfs_reflink.c
++++ b/fs/xfs/xfs_reflink.c
+@@ -476,35 +476,6 @@
+ }
+
+ /*
+- * Find the CoW reservation for a given byte offset of a file.
+- */
+-bool
+-xfs_reflink_find_cow_mapping(
+- struct xfs_inode *ip,
+- xfs_off_t offset,
+- struct xfs_bmbt_irec *imap)
+-{
+- struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
+- xfs_fileoff_t offset_fsb;
+- struct xfs_bmbt_irec got;
+- struct xfs_iext_cursor icur;
+-
+- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED));
+- ASSERT(xfs_is_reflink_inode(ip));
+-
+- offset_fsb = XFS_B_TO_FSBT(ip->i_mount, offset);
+- if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got))
+- return false;
+- if (got.br_startoff > offset_fsb)
+- return false;
+-
+- trace_xfs_reflink_find_cow_mapping(ip, offset, 1, XFS_IO_OVERWRITE,
+- &got);
+- *imap = got;
+- return true;
+-}
+-
+-/*
+ * Cancel CoW reservations for some block range of an inode.
+ *
+ * If cancel_real is true this function cancels all COW fork extents for the
+--- a/fs/xfs/xfs_reflink.h
++++ b/fs/xfs/xfs_reflink.h
+@@ -32,8 +32,6 @@
+ struct xfs_bmbt_irec *imap, bool *shared, uint *lockmode);
+ extern int xfs_reflink_convert_cow(struct xfs_inode *ip, xfs_off_t offset,
+ xfs_off_t count);
+-extern bool xfs_reflink_find_cow_mapping(struct xfs_inode *ip, xfs_off_t offset,
+- struct xfs_bmbt_irec *imap);
+
+ extern int xfs_reflink_cancel_cow_blocks(struct xfs_inode *ip,
+ struct xfs_trans **tpp, xfs_fileoff_t offset_fsb,
+--- a/fs/xfs/xfs_trace.h
++++ b/fs/xfs/xfs_trace.h
+@@ -3220,7 +3220,6 @@
+ DEFINE_RW_EVENT(xfs_reflink_reserve_cow);
+
+ DEFINE_SIMPLE_IO_EVENT(xfs_reflink_bounce_dio_write);
+-DEFINE_IOMAP_EVENT(xfs_reflink_find_cow_mapping);
+
+ DEFINE_SIMPLE_IO_EVENT(xfs_reflink_cancel_cow_range);
+ DEFINE_SIMPLE_IO_EVENT(xfs_reflink_end_cow);
+
diff --git a/patches.fixes/xfs-remove-xfs_reflink_trim_irec_to_next_cow.patch b/patches.fixes/xfs-remove-xfs_reflink_trim_irec_to_next_cow.patch
new file mode 100644
index 0000000000..8b714f220c
--- /dev/null
+++ b/patches.fixes/xfs-remove-xfs_reflink_trim_irec_to_next_cow.patch
@@ -0,0 +1,115 @@
+From fca8c805425c0d9435097a6c780e95332e54613a Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:25:59 -0700
+Subject: [PATCH] xfs: remove xfs_reflink_trim_irec_to_next_cow
+Git-commit: fca8c805425c0d9435097a6c780e95332e54613a
+Patch-mainline: v4.19-rc1
+References: bsc#1138006
+
+We already have to check for overlapping COW extents everytime we
+come back to a page in xfs_writepage_map / xfs_map_cow, so this
+additional trim is not required.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 7 -------
+ fs/xfs/xfs_reflink.c | 33 ---------------------------------
+ fs/xfs/xfs_reflink.h | 2 --
+ fs/xfs/xfs_trace.h | 1 -
+ 4 files changed, 43 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 6b6150683343..08605432c497 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -404,13 +404,6 @@ xfs_map_blocks(
+ offset_fsb = XFS_B_TO_FSBT(mp, offset);
+ error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
+ imap, &nimaps, XFS_BMAPI_ENTIRE);
+- /*
+- * Truncate an overwrite extent if there's a pending CoW
+- * reservation before the end of this extent. This forces us
+- * to come back to writepage to take care of the CoW.
+- */
+- if (nimaps && type == XFS_IO_OVERWRITE)
+- xfs_reflink_trim_irec_to_next_cow(ip, offset_fsb, imap);
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+
+ if (error)
+diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
+index 592fb2071a03..22c11b98ab26 100644
+--- a/fs/xfs/xfs_reflink.c
++++ b/fs/xfs/xfs_reflink.c
+@@ -500,39 +500,6 @@ xfs_reflink_find_cow_mapping(
+ return true;
+ }
+
+-/*
+- * Trim an extent to end at the next CoW reservation past offset_fsb.
+- */
+-void
+-xfs_reflink_trim_irec_to_next_cow(
+- struct xfs_inode *ip,
+- xfs_fileoff_t offset_fsb,
+- struct xfs_bmbt_irec *imap)
+-{
+- struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
+- struct xfs_bmbt_irec got;
+- struct xfs_iext_cursor icur;
+-
+- if (!xfs_is_reflink_inode(ip))
+- return;
+-
+- /* Find the extent in the CoW fork. */
+- if (!xfs_iext_lookup_extent(ip, ifp, offset_fsb, &icur, &got))
+- return;
+-
+- /* This is the extent before; try sliding up one. */
+- if (got.br_startoff < offset_fsb) {
+- if (!xfs_iext_next_extent(ifp, &icur, &got))
+- return;
+- }
+-
+- if (got.br_startoff >= imap->br_startoff + imap->br_blockcount)
+- return;
+-
+- imap->br_blockcount = got.br_startoff - imap->br_startoff;
+- trace_xfs_reflink_trim_irec(ip, imap);
+-}
+-
+ /*
+ * Cancel CoW reservations for some block range of an inode.
+ *
+diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h
+index 1532827ba911..6f9f98894abc 100644
+--- a/fs/xfs/xfs_reflink.h
++++ b/fs/xfs/xfs_reflink.h
+@@ -20,8 +20,6 @@ extern int xfs_reflink_convert_cow(struct xfs_inode *ip, xfs_off_t offset,
+ xfs_off_t count);
+ extern bool xfs_reflink_find_cow_mapping(struct xfs_inode *ip, xfs_off_t offset,
+ struct xfs_bmbt_irec *imap);
+-extern void xfs_reflink_trim_irec_to_next_cow(struct xfs_inode *ip,
+- xfs_fileoff_t offset_fsb, struct xfs_bmbt_irec *imap);
+
+ extern int xfs_reflink_cancel_cow_blocks(struct xfs_inode *ip,
+ struct xfs_trans **tpp, xfs_fileoff_t offset_fsb,
+diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
+index 972d45d28097..a5b01529ecf6 100644
+--- a/fs/xfs/xfs_trace.h
++++ b/fs/xfs/xfs_trace.h
+@@ -3216,7 +3216,6 @@ DEFINE_RW_EVENT(xfs_reflink_reserve_cow);
+
+ DEFINE_SIMPLE_IO_EVENT(xfs_reflink_bounce_dio_write);
+ DEFINE_IOMAP_EVENT(xfs_reflink_find_cow_mapping);
+-DEFINE_INODE_IREC_EVENT(xfs_reflink_trim_irec);
+
+ DEFINE_SIMPLE_IO_EVENT(xfs_reflink_cancel_cow_range);
+ DEFINE_SIMPLE_IO_EVENT(xfs_reflink_end_cow);
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-remove-xfs_start_page_writeback.patch b/patches.fixes/xfs-remove-xfs_start_page_writeback.patch
new file mode 100644
index 0000000000..096c185e0f
--- /dev/null
+++ b/patches.fixes/xfs-remove-xfs_start_page_writeback.patch
@@ -0,0 +1,102 @@
+From 1b65d3dd2d5e938b035b2ad73d0b47f35b5ef9a0 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:26:03 -0700
+Subject: [PATCH] xfs: remove xfs_start_page_writeback
+Git-commit: 1b65d3dd2d5e938b035b2ad73d0b47f35b5ef9a0
+Patch-mainline: v4.19-rc1
+References: bsc#1138015
+
+This helper only has two callers, one of them with a constant error
+argument. Remove it to make pending changes to the code a little easier.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 46 ++++++++++++++++++++--------------------------
+ 1 file changed, 20 insertions(+), 26 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 71b4ca60ff40..af9224ea4ebf 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -494,30 +494,6 @@ xfs_map_blocks(
+ return 0;
+ }
+
+-STATIC void
+-xfs_start_page_writeback(
+- struct page *page,
+- int clear_dirty)
+-{
+- ASSERT(PageLocked(page));
+- ASSERT(!PageWriteback(page));
+-
+- /*
+- * if the page was not fully cleaned, we need to ensure that the higher
+- * layers come back to it correctly. That means we need to keep the page
+- * dirty, and for WB_SYNC_ALL writeback we need to ensure the
+- * PAGECACHE_TAG_TOWRITE index mark is not removed so another attempt to
+- * write this page in this writeback sweep will be made.
+- */
+- if (clear_dirty) {
+- clear_page_dirty_for_io(page);
+- set_page_writeback(page);
+- } else
+- set_page_writeback_keepwrite(page);
+-
+- unlock_page(page);
+-}
+-
+ /*
+ * Submit the bio for an ioend. We are passed an ioend with a bio attached to
+ * it, and we submit that bio. The ioend may be used for multiple bio
+@@ -858,6 +834,8 @@ xfs_writepage_map(
+ }
+
+ ASSERT(wpc->ioend || list_empty(&submit_list));
++ ASSERT(PageLocked(page));
++ ASSERT(!PageWriteback(page));
+
+ /*
+ * On error, we have to fail the ioend here because we have locked
+@@ -877,7 +855,21 @@ xfs_writepage_map(
+ * treated correctly on error.
+ */
+ if (count) {
+- xfs_start_page_writeback(page, !error);
++ /*
++ * If the page was not fully cleaned, we need to ensure that the
++ * higher layers come back to it correctly. That means we need
++ * to keep the page dirty, and for WB_SYNC_ALL writeback we need
++ * to ensure the PAGECACHE_TAG_TOWRITE index mark is not removed
++ * so another attempt to write this page in this writeback sweep
++ * will be made.
++ */
++ if (error) {
++ set_page_writeback_keepwrite(page);
++ } else {
++ clear_page_dirty_for_io(page);
++ set_page_writeback(page);
++ }
++ unlock_page(page);
+
+ /*
+ * Preserve the original error if there was one, otherwise catch
+@@ -902,7 +894,9 @@ xfs_writepage_map(
+ * race with a partial page truncate on a sub-page block sized
+ * filesystem. In that case we need to mark the page clean.
+ */
+- xfs_start_page_writeback(page, 1);
++ clear_page_dirty_for_io(page);
++ set_page_writeback(page);
++ unlock_page(page);
+ end_page_writeback(page);
+ }
+
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-rename-the-offset-variable-in-xfs_writepage_map.patch b/patches.fixes/xfs-rename-the-offset-variable-in-xfs_writepage_map.patch
new file mode 100644
index 0000000000..13a5b9a42d
--- /dev/null
+++ b/patches.fixes/xfs-rename-the-offset-variable-in-xfs_writepage_map.patch
@@ -0,0 +1,94 @@
+From 6a4c95013608120b2d88be67c6871cb6b86aa5d6 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:26:00 -0700
+Subject: [PATCH] xfs: rename the offset variable in xfs_writepage_map
+Git-commit: 6a4c95013608120b2d88be67c6871cb6b86aa5d6
+Patch-mainline: v4.19-rc1
+References: bsc#1138008
+
+Calling it file_offset makes the usage more clear, especially with
+a new poffset variable that will be added soon for the offset inside
+the page.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 65454a4f4d93..4dc5fcff226e 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -823,15 +823,15 @@ xfs_writepage_map(
+ struct xfs_ioend *ioend, *next;
+ struct buffer_head *bh, *head;
+ ssize_t len = i_blocksize(inode);
+- uint64_t offset; /* file offset of page */
++ uint64_t file_offset; /* file offset of page */
+ int error = 0;
+ int count = 0;
+ unsigned int new_type;
+
+ bh = head = page_buffers(page);
+- offset = page_offset(page);
++ file_offset = page_offset(page);
+ do {
+- if (offset >= end_offset)
++ if (file_offset >= end_offset)
+ break;
+
+ /*
+@@ -863,7 +863,7 @@ xfs_writepage_map(
+ * If we already have a valid COW mapping keep using it.
+ */
+ if (wpc->io_type == XFS_IO_COW &&
+- xfs_imap_valid(inode, &wpc->imap, offset)) {
++ xfs_imap_valid(inode, &wpc->imap, file_offset)) {
+ wpc->imap_valid = true;
+ new_type = XFS_IO_COW;
+ }
+@@ -875,7 +875,7 @@ xfs_writepage_map(
+
+ if (wpc->imap_valid)
+ wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap,
+- offset);
++ file_offset);
+
+ /*
+ * COW fork blocks can overlap data fork blocks even if the
+@@ -886,11 +886,11 @@ xfs_writepage_map(
+ if (!wpc->imap_valid ||
+ (xfs_is_reflink_inode(XFS_I(inode)) &&
+ wpc->io_type != XFS_IO_COW)) {
+- error = xfs_map_blocks(wpc, inode, offset);
++ error = xfs_map_blocks(wpc, inode, file_offset);
+ if (error)
+ goto out;
+ wpc->imap_valid = xfs_imap_valid(inode, &wpc->imap,
+- offset);
++ file_offset);
+ }
+
+ if (!wpc->imap_valid || wpc->io_type == XFS_IO_HOLE)
+@@ -898,10 +898,10 @@ xfs_writepage_map(
+
+ lock_buffer(bh);
+ if (wpc->io_type != XFS_IO_OVERWRITE)
+- xfs_map_at_offset(inode, bh, &wpc->imap, offset);
+- xfs_add_to_ioend(inode, bh, offset, wpc, wbc, &submit_list);
++ xfs_map_at_offset(inode, bh, &wpc->imap, file_offset);
++ xfs_add_to_ioend(inode, bh, file_offset, wpc, wbc, &submit_list);
+ count++;
+- } while (offset += len, ((bh = bh->b_this_page) != head));
++ } while (file_offset += len, ((bh = bh->b_this_page) != head));
+
+ ASSERT(wpc->ioend || list_empty(&submit_list));
+
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-simplify-xfs_map_blocks-by-using-xfs_iext_lookup.patch b/patches.fixes/xfs-simplify-xfs_map_blocks-by-using-xfs_iext_lookup.patch
new file mode 100644
index 0000000000..45baedf91b
--- /dev/null
+++ b/patches.fixes/xfs-simplify-xfs_map_blocks-by-using-xfs_iext_lookup.patch
@@ -0,0 +1,70 @@
+From 3345746ef38bb794ae9d4d0762adf151e452663e Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Wed, 11 Jul 2018 22:26:02 -0700
+Subject: [PATCH] xfs: simplify xfs_map_blocks by using xfs_iext_lookup_extent
+ directly
+Git-commit: 3345746ef38bb794ae9d4d0762adf151e452663e
+Patch-mainline: v4.19-rc1
+References: bsc#1138011
+
+xfs_bmapi_read adds zero value in xfs_map_blocks. Replace it with a
+direct call to the low-level extent lookup function.
+
+Note that we now always pass a 0 length to the trace points as we ask
+for an unspecified len.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 19 +++++--------------
+ 1 file changed, 5 insertions(+), 14 deletions(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 5c5d8c832dcc..0bfcc2d06658 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -375,7 +375,6 @@ xfs_map_blocks(
+ int whichfork = XFS_DATA_FORK;
+ struct xfs_iext_cursor icur;
+ int error = 0;
+- int nimaps = 1;
+
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return -EIO;
+@@ -431,24 +430,16 @@ xfs_map_blocks(
+ * offset. This will convert delayed allocations (including COW ones)
+ * into real extents.
+ */
+- error = xfs_bmapi_read(ip, offset_fsb, end_fsb - offset_fsb,
+- &imap, &nimaps, XFS_BMAPI_ENTIRE);
++ if (!xfs_iext_lookup_extent(ip, &ip->i_df, offset_fsb, &icur, &imap))
++ imap.br_startoff = end_fsb; /* fake a hole past EOF */
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+- if (error)
+- return error;
+
+- if (!nimaps) {
+- /*
+- * Lookup returns no match? Beyond eof? regardless,
+- * return it as a hole so we don't write it
+- */
++ if (imap.br_startoff > offset_fsb) {
++ /* landed in a hole or beyond EOF */
++ imap.br_blockcount = imap.br_startoff - offset_fsb;
+ imap.br_startoff = offset_fsb;
+- imap.br_blockcount = end_fsb - offset_fsb;
+ imap.br_startblock = HOLESTARTBLOCK;
+ wpc->io_type = XFS_IO_HOLE;
+- } else if (imap.br_startblock == HOLESTARTBLOCK) {
+- /* landed in a hole */
+- wpc->io_type = XFS_IO_HOLE;
+ } else {
+ if (isnullstartblock(imap.br_startblock)) {
+ /* got a delalloc extent */
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-skip-CoW-writes-past-EOF-when-writeback-races-wi.patch b/patches.fixes/xfs-skip-CoW-writes-past-EOF-when-writeback-races-wi.patch
new file mode 100644
index 0000000000..10b8c85e0c
--- /dev/null
+++ b/patches.fixes/xfs-skip-CoW-writes-past-EOF-when-writeback-races-wi.patch
@@ -0,0 +1,56 @@
+From 70c57dcd606f218b507372a05e633b23351258f0 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Wed, 24 Jan 2018 20:48:53 -0800
+Subject: [PATCH] xfs: skip CoW writes past EOF when writeback races with
+ truncate
+Git-commit: 70c57dcd606f218b507372a05e633b23351258f0
+Patch-mainline: v4.16-rc1
+References: bsc#1137998
+
+Every so often we blow the ASSERT(type != XFS_IO_COW) in xfs_map_blocks
+when running fsstress, as we do in generic/269. The cause of this is
+writeback racing with truncate -- writeback doesn't take the iolock, so
+truncate can sneak in to decrease i_size and truncate page cache while
+writeback is gathering buffer heads to schedule writeout.
+
+If we hit this race on a block that has a CoW mapping, we'll get a valid
+imap from the CoW fork but the reduced i_size trims the mapping to zero
+length (which makes it invalid), so we call xfs_map_blocks to try again.
+This doesn't do much anyway, since any mapping we get out of that will
+also be invalid, so we might as well skip the assert and just stop.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 2e094c76bd45..9c6a830da0ee 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -390,6 +390,19 @@ xfs_map_blocks(
+ if (XFS_FORCED_SHUTDOWN(mp))
+ return -EIO;
+
++ /*
++ * Truncate can race with writeback since writeback doesn't take the
++ * iolock and truncate decreases the file size before it starts
++ * truncating the pages between new_size and old_size. Therefore, we
++ * can end up in the situation where writeback gets a CoW fork mapping
++ * but the truncate makes the mapping invalid and we end up in here
++ * trying to get a new mapping. Bail out here so that we simply never
++ * get a valid mapping and so we drop the write altogether. The page
++ * truncation will kill the contents anyway.
++ */
++ if (type == XFS_IO_COW && offset > i_size_read(inode))
++ return 0;
++
+ ASSERT(type != XFS_IO_COW);
+ if (type == XFS_IO_UNWRITTEN)
+ bmapi_flags |= XFS_BMAPI_IGSTATE;
+--
+2.16.4
+
diff --git a/patches.fixes/xfs-xfs_reflink_convert_cow-memory-allocation-deadlo.patch b/patches.fixes/xfs-xfs_reflink_convert_cow-memory-allocation-deadlo.patch
new file mode 100644
index 0000000000..256404f7f2
--- /dev/null
+++ b/patches.fixes/xfs-xfs_reflink_convert_cow-memory-allocation-deadlo.patch
@@ -0,0 +1,83 @@
+From 4a2d01b076d231afebbea04647373644e767b453 Mon Sep 17 00:00:00 2001
+From: Dave Chinner <dchinner@redhat.com>
+Date: Thu, 7 Jun 2018 07:46:42 -0700
+Subject: [PATCH] xfs: xfs_reflink_convert_cow() memory allocation deadlock
+Git-commit: 4a2d01b076d231afebbea04647373644e767b453
+Patch-mainline: v4.18-rc1
+References: bsc#1138002
+
+xfs_reflink_convert_cow() manipulates the incore extent list
+in GFP_KERNEL context in the IO submission path whilst holding
+locked pages under writeback. This is a memory reclaim deadlock
+vector. This code is not in a transaction, so any memory allocations
+it makes aren't protected via the memalloc_nofs_save() context that
+transactions carry.
+
+Hence we need to run this call under memalloc_nofs_save() context to
+prevent potential memory allocations from being run as GFP_KERNEL
+and deadlocking.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Allison Henderson <allison.henderson@oracle.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/xfs_aops.c | 11 +++++++++++
+ fs/xfs/xfs_buf.c | 1 -
+ fs/xfs/xfs_linux.h | 1 +
+ 3 files changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
+index 767d53222f31..1eb625fdcb1e 100644
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -531,8 +531,19 @@ xfs_submit_ioend(
+ {
+ /* Convert CoW extents to regular */
+ if (!status && ioend->io_type == XFS_IO_COW) {
++ /*
++ * Yuk. This can do memory allocation, but is not a
++ * transactional operation so everything is done in GFP_KERNEL
++ * context. That can deadlock, because we hold pages in
++ * writeback state and GFP_KERNEL allocations can block on them.
++ * Hence we must operate in nofs conditions here.
++ */
++ unsigned nofs_flag;
++
++ nofs_flag = memalloc_nofs_save();
+ status = xfs_reflink_convert_cow(XFS_I(ioend->io_inode),
+ ioend->io_offset, ioend->io_size);
++ memalloc_nofs_restore(nofs_flag);
+ }
+
+ /* Reserve log space if we might write beyond the on-disk inode size. */
+diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
+index 980bc48979e9..e9c058e3761c 100644
+--- a/fs/xfs/xfs_buf.c
++++ b/fs/xfs/xfs_buf.c
+@@ -21,7 +21,6 @@
+ #include <linux/migrate.h>
+ #include <linux/backing-dev.h>
+ #include <linux/freezer.h>
+-#include <linux/sched/mm.h>
+
+ #include "xfs_format.h"
+ #include "xfs_log_format.h"
+diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
+index ae1e66fa3f61..1631cf4546f2 100644
+--- a/fs/xfs/xfs_linux.h
++++ b/fs/xfs/xfs_linux.h
+@@ -26,6 +26,7 @@ typedef __u32 xfs_nlink_t;
+
+ #include <linux/semaphore.h>
+ #include <linux/mm.h>
++#include <linux/sched/mm.h>
+ #include <linux/kernel.h>
+ #include <linux/blkdev.h>
+ #include <linux/slab.h>
+--
+2.16.4
+
diff --git a/series.conf b/series.conf
index 0dd0034a8c..03bd691407 100644
--- a/series.conf
+++ b/series.conf
@@ -10665,6 +10665,7 @@
patches.arch/0007-arm64-context-Fix-comments-and-remove-pointless-smp_.patch
patches.fixes/xfs-fortify-xfs_alloc_buftarg-error-handling.patch
patches.fixes/xfs-ubsan-fixes.patch
+ patches.fixes/xfs-remove-unused-parameter-from-xfs_writepage_map.patch
patches.fixes/xfs-Properly-retry-failed-dquot-items-in-case-of-err.patch
patches.fixes/SUNRPC-Allow-connect-to-return-EHOSTUNREACH.patch
patches.drivers/hwmon-pmbus-Use-64bit-math-for-DIRECT-format-values.patch
@@ -11319,6 +11320,7 @@
patches.arch/10-x86-pti-rename-bug_cpu_insecure-to-bug_cpu_meltdown.patch
patches.fixes/xfs-quota-fix-missed-destroy-of-qi_tree_lock.patch
patches.fixes/xfs-quota-check-result-of-register_shrinker.patch
+ patches.fixes/xfs-fix-s_maxbytes-overflow-problems.patch
patches.drivers/iommu-arm-smmu-v3-don-t-free-page-table-ops-twice
patches.suse/0001-iommu-arm-smmu-v3-Cope-with-duplicated-Stream-IDs.patch
patches.drivers/Input-elantech-add-new-icbody-type-15
@@ -11935,6 +11937,7 @@
patches.fixes/0004-iomap-report-collisions-between-directio-and-buffere.patch
patches.fixes/xfs-call-xfs_qm_dqattach-before-performing-reflink-o.patch
patches.fixes/xfs-preserve-i_rdev-when-recycling-a-reclaimable-inode.patch
+ patches.fixes/xfs-skip-CoW-writes-past-EOF-when-writeback-races-wi.patch
patches.fixes/xfs-reflink-should-break-pnfs-leases-before-sharing-.patch
patches.fixes/xfs-allow-xfs_lock_two_inodes-to-take-different-EXCL.patch
patches.fixes/xfs-only-grab-shared-inode-locks-for-source-file-dur.patch
@@ -14952,7 +14955,9 @@
patches.fixes/xfs-Remove-dead-code-from-inode-recover-function.patch
patches.fixes/xfs-fix-transaction-allocation-deadlock-in-IO-path.patch
patches.fixes/xfs-convert-XFS_AGFL_SIZE-to-a-helper-function.patch
+ patches.fixes/xfs-don-t-use-XFS_BMAPI_ENTRIRE-in-xfs_get_blocks.patch
patches.fixes/xfs-remove-xfs_zero_range.patch
+ patches.fixes/xfs-minor-cleanup-for-xfs_get_blocks.patch
patches.fixes/xfs-detect-agfl-count-corruption-and-reset-agfl.patch
patches.fixes/xfs-sanity-check-the-unused-space-before-trying-to-u.patch
patches.fixes/xfs-catch-inode-allocation-state-mismatch-corruption.patch
@@ -17464,6 +17469,7 @@
patches.drivers/vfio-type1-Fix-task-tracking-for-QEMU-vCPU-hotplug.patch
patches.suse/0001-vfio-platform-Fix-reset-module-leak-in-error-path.patch
patches.drivers/thermal-exynos-fix-setting-rising_threshold-for-Exyn
+ patches.fixes/xfs-xfs_reflink_convert_cow-memory-allocation-deadlo.patch
patches.suse/xfs-don-t-call-xfs_da_shrink_inode-with-NULL-bp.patch
patches.suse/dm-add-writecache-target.patch
patches.fixes/UBIFS-Fix-potential-integer-overflow-in-allocation
@@ -18183,6 +18189,20 @@
patches.fixes/ext4-reset-error-code-in-ext4_find_entry-in-fallback.patch
patches.fixes/ext4-check-for-NUL-characters-in-extended-attribute-.patch
patches.fixes/ext4-fix-spectre-gadget-in-ext4_mb_regular_allocator.patch
+ patches.fixes/xfs-do-not-set-the-page-uptodate-in-xfs_writepage_ma.patch
+ patches.fixes/xfs-don-t-clear-imap_valid-for-a-non-uptodate-buffer.patch
+ patches.fixes/xfs-don-t-use-XFS_BMAPI_IGSTATE-in-xfs_map_blocks.patch
+ patches.fixes/xfs-remove-xfs_reflink_trim_irec_to_next_cow.patch
+ patches.fixes/xfs-remove-xfs_map_cow.patch
+ patches.fixes/xfs-rename-the-offset-variable-in-xfs_writepage_map.patch
+ patches.fixes/xfs-make-xfs_writepage_map-extent-map-centric.patch
+ patches.fixes/xfs-remove-xfs_reflink_find_cow_mapping.patch
+ patches.fixes/xfs-simplify-xfs_map_blocks-by-using-xfs_iext_lookup.patch
+ patches.fixes/xfs-remove-the-imap_valid-flag.patch
+ patches.fixes/xfs-don-t-look-at-buffer-heads-in-xfs_add_to_ioend.patch
+ patches.fixes/xfs-move-all-writeback-buffer_head-manipulation-into.patch
+ patches.fixes/xfs-remove-xfs_start_page_writeback.patch
+ patches.fixes/xfs-refactor-the-tail-of-xfs_writepage_map.patch
patches.fixes/xfs-detect-and-fix-bad-summary-counts-at-mount.patch
patches.fixes/xfs-refactor-unmount-record-write.patch
patches.fixes/xfs-force-summary-counter-recalc-at-next-mount.patch
@@ -19737,6 +19757,7 @@
patches.suse/btrfs-fix-wrong-dentries-after-fsync-of-file-that-go.patch
patches.fixes/gfs2_meta-mount-can-get-NULL-dev_name.patch
patches.fixes/gfs2-Don-t-leave-s_fs_info-pointing-to-freed-memory-.patch
+ patches.fixes/xfs-remove-XFS_IO_INVALID.patch
patches.fixes/xfs-Fix-xqmstats-offsets-in-proc-fs-xfs-xqmstat.patch
patches.fixes/ext4-fix-EXT4_IOC_SWAP_BOOT.patch
patches.fixes/ext4-initialize-retries-variable-in-ext4_da_write_in.patch
@@ -21243,6 +21264,7 @@
patches.drm/0001-drm-vmwgfx-Fix-setting-of-dma-masks.patch
patches.drm/drm-modes-Prevent-division-by-zero-htotal.patch
patches.drm/drm-sun4i-tcon-Prepare-and-enable-TCON-channel-0-clo.patch
+ patches.fixes/xfs-eof-trim-writeback-mapping-as-soon-as-it-is-cach.patch
patches.drivers/usb-gadget-musb-fix-short-isoc-packets-with-inventra.patch
patches.drivers/usb-dwc3-gadget-Handle-0-xfer-length-for-OUT-EP.patch
patches.drivers/usb-gadget-udc-net2272-Fix-bitwise-and-boolean-opera.patch
@@ -22513,6 +22535,7 @@
patches.drivers/i2c-dev-fix-potential-memory-leak-in-i2cdev_ioctl_rd.patch
patches.arch/KVM-PPC-Book3S-HV-XIVE-Do-not-clear-IRQ-data-of-pass.patch
patches.arch/powerpc-perf-Fix-MMCRA-corruption-by-bhrb_filter.patch
+ patches.fixes/efi-x86-Add-missing-error-handling-to-old_memmap-1-1.patch
patches.fixes/fuse-fallocate-fix-return-with-locked-inode.patch
patches.drivers/hwmon-core-add-thermal-sensors-only-if-dev-of_node-i.patch
patches.drivers/hwmon-pmbus-core-Treat-parameters-as-paged-if-on-mul.patch
@@ -22898,6 +22921,9 @@
# bsc#1131673 kABI fix
patches.kabi/block-kABI-fixes-for-bio_rewind_iter-removal.patch
+ # bsc#1136922
+ patches.drivers/scsi-mpt3sas_ctl-fix-double-fetch-bug-in-ctl_ioctl_main
+
########################################################
# DRM/Video
########################################################