From: Greg Kroah-Hartman Date: Mon, 17 May 2021 07:43:22 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v5.4.120~68 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=522a61ee5ea8020013c6e8df222a3ec1b1173ff1;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: iomap-fix-sub-page-uptodate-handling.patch --- diff --git a/queue-5.4/blk-mq-swap-two-calls-in-blk_mq_exit_queue.patch b/queue-5.4/blk-mq-swap-two-calls-in-blk_mq_exit_queue.patch index fec52c4ff1d..a4c05dce1f6 100644 --- a/queue-5.4/blk-mq-swap-two-calls-in-blk_mq_exit_queue.patch +++ b/queue-5.4/blk-mq-swap-two-calls-in-blk_mq_exit_queue.patch @@ -24,14 +24,12 @@ Link: https://lore.kernel.org/r/20210513171529.7977-1-bvanassche@acm.org Signed-off-by: Jens Axboe Signed-off-by: Sasha Levin --- - block/blk-mq.c | 6 ++++-- + block/blk-mq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) -diff --git a/block/blk-mq.c b/block/blk-mq.c -index 057a634396a9..0674f53c6052 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c -@@ -2970,10 +2970,12 @@ EXPORT_SYMBOL(blk_mq_init_allocated_queue); +@@ -2970,10 +2970,12 @@ EXPORT_SYMBOL(blk_mq_init_allocated_queu /* tags can _not_ be used after returning from blk_mq_exit_queue */ void blk_mq_exit_queue(struct request_queue *q) { @@ -46,6 +44,3 @@ index 057a634396a9..0674f53c6052 100644 } static int __blk_mq_alloc_rq_maps(struct blk_mq_tag_set *set) --- -2.30.2 - diff --git a/queue-5.4/iomap-fix-sub-page-uptodate-handling.patch b/queue-5.4/iomap-fix-sub-page-uptodate-handling.patch new file mode 100644 index 00000000000..c5576dd3cf8 --- /dev/null +++ b/queue-5.4/iomap-fix-sub-page-uptodate-handling.patch @@ -0,0 +1,94 @@ +From 1cea335d1db1ce6ab71b3d2f94a807112b738a0f Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Wed, 4 Dec 2019 09:33:52 -0800 +Subject: iomap: fix sub-page uptodate handling + +From: Christoph Hellwig + +commit 1cea335d1db1ce6ab71b3d2f94a807112b738a0f upstream. + +bio completions can race when a page spans more than one file system +block. Add a spinlock to synchronize marking the page uptodate. + +Fixes: 9dc55f1389f9 ("iomap: add support for sub-pagesize buffered I/O without buffer heads") +Reported-by: Jan Stancek +Signed-off-by: Christoph Hellwig +Reviewed-by: Dave Chinner +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Cc: "Matthew Wilcox (Oracle)" +Signed-off-by: Greg Kroah-Hartman +--- + fs/iomap/buffered-io.c | 34 ++++++++++++++++++++++++---------- + include/linux/iomap.h | 1 + + 2 files changed, 25 insertions(+), 10 deletions(-) + +--- a/fs/iomap/buffered-io.c ++++ b/fs/iomap/buffered-io.c +@@ -30,6 +30,7 @@ iomap_page_create(struct inode *inode, s + iop = kmalloc(sizeof(*iop), GFP_NOFS | __GFP_NOFAIL); + atomic_set(&iop->read_count, 0); + atomic_set(&iop->write_count, 0); ++ spin_lock_init(&iop->uptodate_lock); + bitmap_zero(iop->uptodate, PAGE_SIZE / SECTOR_SIZE); + + /* +@@ -118,25 +119,38 @@ iomap_adjust_read_range(struct inode *in + } + + static void +-iomap_set_range_uptodate(struct page *page, unsigned off, unsigned len) ++iomap_iop_set_range_uptodate(struct page *page, unsigned off, unsigned len) + { + struct iomap_page *iop = to_iomap_page(page); + struct inode *inode = page->mapping->host; + unsigned first = off >> inode->i_blkbits; + unsigned last = (off + len - 1) >> inode->i_blkbits; +- unsigned int i; + bool uptodate = true; ++ unsigned long flags; ++ unsigned int i; + +- if (iop) { +- for (i = 0; i < PAGE_SIZE / i_blocksize(inode); i++) { +- if (i >= first && i <= last) +- set_bit(i, iop->uptodate); +- else if (!test_bit(i, iop->uptodate)) +- uptodate = false; +- } ++ spin_lock_irqsave(&iop->uptodate_lock, flags); ++ for (i = 0; i < PAGE_SIZE / i_blocksize(inode); i++) { ++ if (i >= first && i <= last) ++ set_bit(i, iop->uptodate); ++ else if (!test_bit(i, iop->uptodate)) ++ uptodate = false; + } + +- if (uptodate && !PageError(page)) ++ if (uptodate) ++ SetPageUptodate(page); ++ spin_unlock_irqrestore(&iop->uptodate_lock, flags); ++} ++ ++static void ++iomap_set_range_uptodate(struct page *page, unsigned off, unsigned len) ++{ ++ if (PageError(page)) ++ return; ++ ++ if (page_has_private(page)) ++ iomap_iop_set_range_uptodate(page, off, len); ++ else + SetPageUptodate(page); + } + +--- a/include/linux/iomap.h ++++ b/include/linux/iomap.h +@@ -139,6 +139,7 @@ loff_t iomap_apply(struct inode *inode, + struct iomap_page { + atomic_t read_count; + atomic_t write_count; ++ spinlock_t uptodate_lock; + DECLARE_BITMAP(uptodate, PAGE_SIZE / 512); + }; + diff --git a/queue-5.4/series b/queue-5.4/series index 732b6d883f2..45a6c3441dc 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -109,3 +109,4 @@ acpi-scan-fix-a-memory-leak-in-an-error-handling-pat.patch kyber-fix-out-of-bounds-access-when-preempted.patch nbd-fix-null-pointer-in-flush_workqueue.patch blk-mq-swap-two-calls-in-blk_mq_exit_queue.patch +iomap-fix-sub-page-uptodate-handling.patch