From: Greg Kroah-Hartman Date: Mon, 29 Jul 2024 12:27:04 +0000 (+0200) Subject: 6.10-stable patches X-Git-Tag: v6.1.103~58 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=78c0358cd3dcbc6158bf2d3ac9560364a677bc2c;p=thirdparty%2Fkernel%2Fstable-queue.git 6.10-stable patches added patches: asoc-fsl-fsl_qmc_audio-check-devm_kasprintf-returned-value.patch dmaengine-fsl-edma-change-the-memory-access-from-local-into-remote-mode-in-i.mx-8qm.patch f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch f2fs-fix-to-force-buffered-io-on-inline_data-inode.patch f2fs-use-meta-inode-for-gc-of-atomic-file.patch f2fs-use-meta-inode-for-gc-of-cow-file.patch fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch mm-page_alloc-fix-pcp-count-race-between-drain_pages_zone-vs-__rmqueue_pcplist.patch nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch --- diff --git a/queue-6.10/asoc-fsl-fsl_qmc_audio-check-devm_kasprintf-returned-value.patch b/queue-6.10/asoc-fsl-fsl_qmc_audio-check-devm_kasprintf-returned-value.patch new file mode 100644 index 00000000000..77538f3f7d7 --- /dev/null +++ b/queue-6.10/asoc-fsl-fsl_qmc_audio-check-devm_kasprintf-returned-value.patch @@ -0,0 +1,35 @@ +From e62599902327d27687693f6e5253a5d56583db58 Mon Sep 17 00:00:00 2001 +From: Herve Codina +Date: Mon, 1 Jul 2024 13:30:28 +0200 +Subject: ASoC: fsl: fsl_qmc_audio: Check devm_kasprintf() returned value + +From: Herve Codina + +commit e62599902327d27687693f6e5253a5d56583db58 upstream. + +devm_kasprintf() can return a NULL pointer on failure but this returned +value is not checked. + +Fix this lack and check the returned value. + +Fixes: 075c7125b11c ("ASoC: fsl: Add support for QMC audio") +Cc: stable@vger.kernel.org +Signed-off-by: Herve Codina +Link: https://patch.msgid.link/20240701113038.55144-2-herve.codina@bootlin.com +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/fsl/fsl_qmc_audio.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/soc/fsl/fsl_qmc_audio.c ++++ b/sound/soc/fsl/fsl_qmc_audio.c +@@ -604,6 +604,8 @@ static int qmc_audio_dai_parse(struct qm + + qmc_dai->name = devm_kasprintf(qmc_audio->dev, GFP_KERNEL, "%s.%d", + np->parent->name, qmc_dai->id); ++ if (!qmc_dai->name) ++ return -ENOMEM; + + qmc_dai->qmc_chan = devm_qmc_chan_get_byphandle(qmc_audio->dev, np, + "fsl,qmc-chan"); diff --git a/queue-6.10/dmaengine-fsl-edma-change-the-memory-access-from-local-into-remote-mode-in-i.mx-8qm.patch b/queue-6.10/dmaengine-fsl-edma-change-the-memory-access-from-local-into-remote-mode-in-i.mx-8qm.patch new file mode 100644 index 00000000000..4799a0e45a4 --- /dev/null +++ b/queue-6.10/dmaengine-fsl-edma-change-the-memory-access-from-local-into-remote-mode-in-i.mx-8qm.patch @@ -0,0 +1,79 @@ +From 8ddad558997002ce67980e30c9e8dfaa696e163b Mon Sep 17 00:00:00 2001 +From: Joy Zou +Date: Fri, 10 May 2024 11:09:34 +0800 +Subject: dmaengine: fsl-edma: change the memory access from local into remote mode in i.MX 8QM + +From: Joy Zou + +commit 8ddad558997002ce67980e30c9e8dfaa696e163b upstream. + +Fix the issue where MEM_TO_MEM fail on i.MX8QM due to the requirement +that both source and destination addresses need pass through the IOMMU. +Typically, peripheral FIFO addresses bypass the IOMMU, necessitating +only one of the source or destination to go through it. + +Set "is_remote" to true to ensure both source and destination +addresses pass through the IOMMU. + +iMX8 Spec define "Local" and "Remote" bus as below. +Local bus: bypass IOMMU to directly access other peripheral register, +such as FIFO. +Remote bus: go through IOMMU to access system memory. + +The test fail log as follow: +[ 66.268506] dmatest: dma0chan0-copy0: result #1: 'test timed out' with src_off=0x100 dst_off=0x80 len=0x3ec0 (0) +[ 66.278785] dmatest: dma0chan0-copy0: summary 1 tests, 1 failures 0.32 iops 4 KB/s (0) + +Fixes: 72f5801a4e2b ("dmaengine: fsl-edma: integrate v3 support") +Signed-off-by: Joy Zou +Cc: stable@vger.kernel.org +Reviewed-by: Frank Li +Link: https://lore.kernel.org/r/20240510030959.703663-1-joy.zou@nxp.com +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman +--- + drivers/dma/fsl-edma-common.c | 3 +++ + drivers/dma/fsl-edma-common.h | 1 + + drivers/dma/fsl-edma-main.c | 2 +- + 3 files changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/dma/fsl-edma-common.c ++++ b/drivers/dma/fsl-edma-common.c +@@ -758,6 +758,8 @@ struct dma_async_tx_descriptor *fsl_edma + fsl_desc->iscyclic = false; + + fsl_chan->is_sw = true; ++ if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_MEM_REMOTE) ++ fsl_chan->is_remote = true; + + /* To match with copy_align and max_seg_size so 1 tcd is enough */ + fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[0].vtcd, dma_src, dma_dst, +@@ -837,6 +839,7 @@ void fsl_edma_free_chan_resources(struct + fsl_chan->tcd_pool = NULL; + fsl_chan->is_sw = false; + fsl_chan->srcid = 0; ++ fsl_chan->is_remote = false; + if (fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_HAS_CHCLK) + clk_disable_unprepare(fsl_chan->clk); + } +--- a/drivers/dma/fsl-edma-common.h ++++ b/drivers/dma/fsl-edma-common.h +@@ -194,6 +194,7 @@ struct fsl_edma_desc { + #define FSL_EDMA_DRV_HAS_PD BIT(5) + #define FSL_EDMA_DRV_HAS_CHCLK BIT(6) + #define FSL_EDMA_DRV_HAS_CHMUX BIT(7) ++#define FSL_EDMA_DRV_MEM_REMOTE BIT(8) + /* control and status register is in tcd address space, edma3 reg layout */ + #define FSL_EDMA_DRV_SPLIT_REG BIT(9) + #define FSL_EDMA_DRV_BUS_8BYTE BIT(10) +--- a/drivers/dma/fsl-edma-main.c ++++ b/drivers/dma/fsl-edma-main.c +@@ -342,7 +342,7 @@ static struct fsl_edma_drvdata imx7ulp_d + }; + + static struct fsl_edma_drvdata imx8qm_data = { +- .flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3, ++ .flags = FSL_EDMA_DRV_HAS_PD | FSL_EDMA_DRV_EDMA3 | FSL_EDMA_DRV_MEM_REMOTE, + .chreg_space_sz = 0x10000, + .chreg_off = 0x10000, + .setup_irq = fsl_edma3_irq_init, diff --git a/queue-6.10/f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch b/queue-6.10/f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch new file mode 100644 index 00000000000..cdb828bbceb --- /dev/null +++ b/queue-6.10/f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch @@ -0,0 +1,58 @@ +From a8eb3de28e7a365690c61161e7a07a4fc7c60bbf Mon Sep 17 00:00:00 2001 +From: Chao Yu +Date: Mon, 3 Jun 2024 09:07:45 +0800 +Subject: f2fs: fix return value of f2fs_convert_inline_inode() + +From: Chao Yu + +commit a8eb3de28e7a365690c61161e7a07a4fc7c60bbf upstream. + +If device is readonly, make f2fs_convert_inline_inode() +return EROFS instead of zero, otherwise it may trigger +panic during writeback of inline inode's dirty page as +below: + + f2fs_write_single_data_page+0xbb6/0x1e90 fs/f2fs/data.c:2888 + f2fs_write_cache_pages fs/f2fs/data.c:3187 [inline] + __f2fs_write_data_pages fs/f2fs/data.c:3342 [inline] + f2fs_write_data_pages+0x1efe/0x3a90 fs/f2fs/data.c:3369 + do_writepages+0x359/0x870 mm/page-writeback.c:2634 + filemap_fdatawrite_wbc+0x125/0x180 mm/filemap.c:397 + __filemap_fdatawrite_range mm/filemap.c:430 [inline] + file_write_and_wait_range+0x1aa/0x290 mm/filemap.c:788 + f2fs_do_sync_file+0x68a/0x1ae0 fs/f2fs/file.c:276 + generic_write_sync include/linux/fs.h:2806 [inline] + f2fs_file_write_iter+0x7bd/0x24e0 fs/f2fs/file.c:4977 + call_write_iter include/linux/fs.h:2114 [inline] + new_sync_write fs/read_write.c:497 [inline] + vfs_write+0xa72/0xc90 fs/read_write.c:590 + ksys_write+0x1a0/0x2c0 fs/read_write.c:643 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf5/0x240 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Cc: stable@vger.kernel.org +Reported-by: syzbot+848062ba19c8782ca5c8@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-f2fs-devel/000000000000d103ce06174d7ec3@google.com +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/inline.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/fs/f2fs/inline.c ++++ b/fs/f2fs/inline.c +@@ -203,8 +203,10 @@ int f2fs_convert_inline_inode(struct ino + struct page *ipage, *page; + int err = 0; + +- if (!f2fs_has_inline_data(inode) || +- f2fs_hw_is_readonly(sbi) || f2fs_readonly(sbi->sb)) ++ if (f2fs_hw_is_readonly(sbi) || f2fs_readonly(sbi->sb)) ++ return -EROFS; ++ ++ if (!f2fs_has_inline_data(inode)) + return 0; + + err = f2fs_dquot_initialize(inode); diff --git a/queue-6.10/f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch b/queue-6.10/f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch new file mode 100644 index 00000000000..b5fa717f660 --- /dev/null +++ b/queue-6.10/f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch @@ -0,0 +1,79 @@ +From 192b8fb8d1c8ca3c87366ebbef599fa80bb626b8 Mon Sep 17 00:00:00 2001 +From: Chao Yu +Date: Tue, 4 Jun 2024 15:56:36 +0800 +Subject: f2fs: fix to don't dirty inode for readonly filesystem + +From: Chao Yu + +commit 192b8fb8d1c8ca3c87366ebbef599fa80bb626b8 upstream. + +syzbot reports f2fs bug as below: + +kernel BUG at fs/f2fs/inode.c:933! +RIP: 0010:f2fs_evict_inode+0x1576/0x1590 fs/f2fs/inode.c:933 +Call Trace: + evict+0x2a4/0x620 fs/inode.c:664 + dispose_list fs/inode.c:697 [inline] + evict_inodes+0x5f8/0x690 fs/inode.c:747 + generic_shutdown_super+0x9d/0x2c0 fs/super.c:675 + kill_block_super+0x44/0x90 fs/super.c:1667 + kill_f2fs_super+0x303/0x3b0 fs/f2fs/super.c:4894 + deactivate_locked_super+0xc1/0x130 fs/super.c:484 + cleanup_mnt+0x426/0x4c0 fs/namespace.c:1256 + task_work_run+0x24a/0x300 kernel/task_work.c:180 + ptrace_notify+0x2cd/0x380 kernel/signal.c:2399 + ptrace_report_syscall include/linux/ptrace.h:411 [inline] + ptrace_report_syscall_exit include/linux/ptrace.h:473 [inline] + syscall_exit_work kernel/entry/common.c:251 [inline] + syscall_exit_to_user_mode_prepare kernel/entry/common.c:278 [inline] + __syscall_exit_to_user_mode_work kernel/entry/common.c:283 [inline] + syscall_exit_to_user_mode+0x15c/0x280 kernel/entry/common.c:296 + do_syscall_64+0x50/0x110 arch/x86/entry/common.c:88 + entry_SYSCALL_64_after_hwframe+0x63/0x6b + +The root cause is: +- do_sys_open + - f2fs_lookup + - __f2fs_find_entry + - f2fs_i_depth_write + - f2fs_mark_inode_dirty_sync + - f2fs_dirty_inode + - set_inode_flag(inode, FI_DIRTY_INODE) + +- umount + - kill_f2fs_super + - kill_block_super + - generic_shutdown_super + - sync_filesystem + : sb is readonly, skip sync_filesystem() + - evict_inodes + - iput + - f2fs_evict_inode + - f2fs_bug_on(sbi, is_inode_flag_set(inode, FI_DIRTY_INODE)) + : trigger kernel panic + +When we try to repair i_current_depth in readonly filesystem, let's +skip dirty inode to avoid panic in later f2fs_evict_inode(). + +Cc: stable@vger.kernel.org +Reported-by: syzbot+31e4659a3fe953aec2f4@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/linux-f2fs-devel/000000000000e890bc0609a55cff@google.com +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/inode.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/f2fs/inode.c ++++ b/fs/f2fs/inode.c +@@ -29,6 +29,9 @@ void f2fs_mark_inode_dirty_sync(struct i + if (is_inode_flag_set(inode, FI_NEW_INODE)) + return; + ++ if (f2fs_readonly(F2FS_I_SB(inode)->sb)) ++ return; ++ + if (f2fs_inode_dirtied(inode, sync)) + return; + diff --git a/queue-6.10/f2fs-fix-to-force-buffered-io-on-inline_data-inode.patch b/queue-6.10/f2fs-fix-to-force-buffered-io-on-inline_data-inode.patch new file mode 100644 index 00000000000..49296185a52 --- /dev/null +++ b/queue-6.10/f2fs-fix-to-force-buffered-io-on-inline_data-inode.patch @@ -0,0 +1,39 @@ +From 5c8764f8679e659c5cb295af7d32279002d13735 Mon Sep 17 00:00:00 2001 +From: Chao Yu +Date: Thu, 23 May 2024 21:29:48 +0800 +Subject: f2fs: fix to force buffered IO on inline_data inode + +From: Chao Yu + +commit 5c8764f8679e659c5cb295af7d32279002d13735 upstream. + +It will return all zero data when DIO reading from inline_data inode, it +is because f2fs_iomap_begin() assign iomap->type w/ IOMAP_HOLE incorrectly +for this case. + +We can let iomap framework handle inline data via assigning iomap->type +and iomap->inline_data correctly, however, it will be a little bit +complicated when handling race case in between direct IO and buffered IO. + +So, let's force to use buffered IO to fix this issue. + +Cc: stable@vger.kernel.org +Reported-by: Barry Song +Signed-off-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/file.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -825,6 +825,8 @@ static bool f2fs_force_buffered_io(struc + return true; + if (f2fs_compressed_file(inode)) + return true; ++ if (f2fs_has_inline_data(inode)) ++ return true; + + /* disallow direct IO if any of devices has unaligned blksize */ + if (f2fs_is_multi_device(sbi) && !sbi->aligned_blksize) diff --git a/queue-6.10/f2fs-use-meta-inode-for-gc-of-atomic-file.patch b/queue-6.10/f2fs-use-meta-inode-for-gc-of-atomic-file.patch new file mode 100644 index 00000000000..8e65581fc41 --- /dev/null +++ b/queue-6.10/f2fs-use-meta-inode-for-gc-of-atomic-file.patch @@ -0,0 +1,148 @@ +From b40a2b00370931b0c50148681dd7364573e52e6b Mon Sep 17 00:00:00 2001 +From: Sunmin Jeong +Date: Wed, 10 Jul 2024 20:51:17 +0900 +Subject: f2fs: use meta inode for GC of atomic file + +From: Sunmin Jeong + +commit b40a2b00370931b0c50148681dd7364573e52e6b upstream. + +The page cache of the atomic file keeps new data pages which will be +stored in the COW file. It can also keep old data pages when GCing the +atomic file. In this case, new data can be overwritten by old data if a +GC thread sets the old data page as dirty after new data page was +evicted. + +Also, since all writes to the atomic file are redirected to COW inodes, +GC for the atomic file is not working well as below. + +f2fs_gc(gc_type=FG_GC) + - select A as a victim segment + do_garbage_collect + - iget atomic file's inode for block B + move_data_page + f2fs_do_write_data_page + - use dn of cow inode + - set fio->old_blkaddr from cow inode + - seg_freed is 0 since block B is still valid + - goto gc_more and A is selected as victim again + +To solve the problem, let's separate GC writes and updates in the atomic +file by using the meta inode for GC writes. + +Fixes: 3db1de0e582c ("f2fs: change the current atomic write way") +Cc: stable@vger.kernel.org #v5.19+ +Reviewed-by: Sungjong Seo +Reviewed-by: Yeongjin Gil +Signed-off-by: Sunmin Jeong +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/data.c | 4 ++-- + fs/f2fs/f2fs.h | 7 ++++++- + fs/f2fs/gc.c | 6 +++--- + fs/f2fs/segment.c | 6 +++--- + 4 files changed, 14 insertions(+), 9 deletions(-) + +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -2688,7 +2688,7 @@ got_it: + } + + /* wait for GCed page writeback via META_MAPPING */ +- if (fio->post_read) ++ if (fio->meta_gc) + f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); + + /* +@@ -2783,7 +2783,7 @@ int f2fs_write_single_data_page(struct p + .submitted = 0, + .compr_blocks = compr_blocks, + .need_lock = compr_blocks ? LOCK_DONE : LOCK_RETRY, +- .post_read = f2fs_post_read_required(inode) ? 1 : 0, ++ .meta_gc = f2fs_meta_inode_gc_required(inode) ? 1 : 0, + .io_type = io_type, + .io_wbc = wbc, + .bio = bio, +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -1210,7 +1210,7 @@ struct f2fs_io_info { + unsigned int in_list:1; /* indicate fio is in io_list */ + unsigned int is_por:1; /* indicate IO is from recovery or not */ + unsigned int encrypted:1; /* indicate file is encrypted */ +- unsigned int post_read:1; /* require post read */ ++ unsigned int meta_gc:1; /* require meta inode GC */ + enum iostat_type io_type; /* io type */ + struct writeback_control *io_wbc; /* writeback control */ + struct bio **bio; /* bio for ipu */ +@@ -4261,6 +4261,11 @@ static inline bool f2fs_post_read_requir + f2fs_compressed_file(inode); + } + ++static inline bool f2fs_meta_inode_gc_required(struct inode *inode) ++{ ++ return f2fs_post_read_required(inode) || f2fs_is_atomic_file(inode); ++} ++ + /* + * compress.c + */ +--- a/fs/f2fs/gc.c ++++ b/fs/f2fs/gc.c +@@ -1579,7 +1579,7 @@ next_step: + start_bidx = f2fs_start_bidx_of_node(nofs, inode) + + ofs_in_node; + +- if (f2fs_post_read_required(inode)) { ++ if (f2fs_meta_inode_gc_required(inode)) { + int err = ra_data_block(inode, start_bidx); + + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); +@@ -1630,7 +1630,7 @@ next_step: + + start_bidx = f2fs_start_bidx_of_node(nofs, inode) + + ofs_in_node; +- if (f2fs_post_read_required(inode)) ++ if (f2fs_meta_inode_gc_required(inode)) + err = move_data_block(inode, start_bidx, + gc_type, segno, off); + else +@@ -1638,7 +1638,7 @@ next_step: + segno, off); + + if (!err && (gc_type == FG_GC || +- f2fs_post_read_required(inode))) ++ f2fs_meta_inode_gc_required(inode))) + submitted++; + + if (locked) { +--- a/fs/f2fs/segment.c ++++ b/fs/f2fs/segment.c +@@ -3828,7 +3828,7 @@ int f2fs_inplace_write_data(struct f2fs_ + goto drop_bio; + } + +- if (fio->post_read) ++ if (fio->meta_gc) + f2fs_truncate_meta_inode_pages(sbi, fio->new_blkaddr, 1); + + stat_inc_inplace_blocks(fio->sbi); +@@ -3998,7 +3998,7 @@ void f2fs_wait_on_block_writeback(struct + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct page *cpage; + +- if (!f2fs_post_read_required(inode)) ++ if (!f2fs_meta_inode_gc_required(inode)) + return; + + if (!__is_valid_data_blkaddr(blkaddr)) +@@ -4017,7 +4017,7 @@ void f2fs_wait_on_block_writeback_range( + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + block_t i; + +- if (!f2fs_post_read_required(inode)) ++ if (!f2fs_meta_inode_gc_required(inode)) + return; + + for (i = 0; i < len; i++) diff --git a/queue-6.10/f2fs-use-meta-inode-for-gc-of-cow-file.patch b/queue-6.10/f2fs-use-meta-inode-for-gc-of-cow-file.patch new file mode 100644 index 00000000000..bfee5ea8a3c --- /dev/null +++ b/queue-6.10/f2fs-use-meta-inode-for-gc-of-cow-file.patch @@ -0,0 +1,148 @@ +From f18d0076933689775fe7faeeb10ee93ff01be6ab Mon Sep 17 00:00:00 2001 +From: Sunmin Jeong +Date: Wed, 10 Jul 2024 20:51:43 +0900 +Subject: f2fs: use meta inode for GC of COW file + +From: Sunmin Jeong + +commit f18d0076933689775fe7faeeb10ee93ff01be6ab upstream. + +In case of the COW file, new updates and GC writes are already +separated to page caches of the atomic file and COW file. As some cases +that use the meta inode for GC, there are some race issues between a +foreground thread and GC thread. + +To handle them, we need to take care when to invalidate and wait +writeback of GC pages in COW files as the case of using the meta inode. +Also, a pointer from the COW inode to the original inode is required to +check the state of original pages. + +For the former, we can solve the problem by using the meta inode for GC +of COW files. Then let's get a page from the original inode in +move_data_block when GCing the COW file to avoid race condition. + +Fixes: 3db1de0e582c ("f2fs: change the current atomic write way") +Cc: stable@vger.kernel.org #v5.19+ +Reviewed-by: Sungjong Seo +Reviewed-by: Yeongjin Gil +Signed-off-by: Sunmin Jeong +Reviewed-by: Chao Yu +Signed-off-by: Jaegeuk Kim +Signed-off-by: Greg Kroah-Hartman +--- + fs/f2fs/data.c | 2 +- + fs/f2fs/f2fs.h | 13 +++++++++++-- + fs/f2fs/file.c | 3 +++ + fs/f2fs/gc.c | 7 +++++-- + fs/f2fs/inline.c | 2 +- + fs/f2fs/inode.c | 3 ++- + 6 files changed, 23 insertions(+), 7 deletions(-) + +--- a/fs/f2fs/data.c ++++ b/fs/f2fs/data.c +@@ -2601,7 +2601,7 @@ bool f2fs_should_update_outplace(struct + return true; + if (IS_NOQUOTA(inode)) + return true; +- if (f2fs_is_atomic_file(inode)) ++ if (f2fs_used_in_atomic_write(inode)) + return true; + /* rewrite low ratio compress data w/ OPU mode to avoid fragmentation */ + if (f2fs_compressed_file(inode) && +--- a/fs/f2fs/f2fs.h ++++ b/fs/f2fs/f2fs.h +@@ -842,7 +842,11 @@ struct f2fs_inode_info { + struct task_struct *atomic_write_task; /* store atomic write task */ + struct extent_tree *extent_tree[NR_EXTENT_CACHES]; + /* cached extent_tree entry */ +- struct inode *cow_inode; /* copy-on-write inode for atomic write */ ++ union { ++ struct inode *cow_inode; /* copy-on-write inode for atomic write */ ++ struct inode *atomic_inode; ++ /* point to atomic_inode, available only for cow_inode */ ++ }; + + /* avoid racing between foreground op and gc */ + struct f2fs_rwsem i_gc_rwsem[2]; +@@ -4261,9 +4265,14 @@ static inline bool f2fs_post_read_requir + f2fs_compressed_file(inode); + } + ++static inline bool f2fs_used_in_atomic_write(struct inode *inode) ++{ ++ return f2fs_is_atomic_file(inode) || f2fs_is_cow_file(inode); ++} ++ + static inline bool f2fs_meta_inode_gc_required(struct inode *inode) + { +- return f2fs_post_read_required(inode) || f2fs_is_atomic_file(inode); ++ return f2fs_post_read_required(inode) || f2fs_used_in_atomic_write(inode); + } + + /* +--- a/fs/f2fs/file.c ++++ b/fs/f2fs/file.c +@@ -2143,6 +2143,9 @@ static int f2fs_ioc_start_atomic_write(s + + set_inode_flag(fi->cow_inode, FI_COW_FILE); + clear_inode_flag(fi->cow_inode, FI_INLINE_DATA); ++ ++ /* Set the COW inode's atomic_inode to the atomic inode */ ++ F2FS_I(fi->cow_inode)->atomic_inode = inode; + } else { + /* Reuse the already created COW inode */ + ret = f2fs_do_truncate_blocks(fi->cow_inode, 0, true); +--- a/fs/f2fs/gc.c ++++ b/fs/f2fs/gc.c +@@ -1171,7 +1171,8 @@ static bool is_alive(struct f2fs_sb_info + static int ra_data_block(struct inode *inode, pgoff_t index) + { + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); +- struct address_space *mapping = inode->i_mapping; ++ struct address_space *mapping = f2fs_is_cow_file(inode) ? ++ F2FS_I(inode)->atomic_inode->i_mapping : inode->i_mapping; + struct dnode_of_data dn; + struct page *page; + struct f2fs_io_info fio = { +@@ -1260,6 +1261,8 @@ put_page: + static int move_data_block(struct inode *inode, block_t bidx, + int gc_type, unsigned int segno, int off) + { ++ struct address_space *mapping = f2fs_is_cow_file(inode) ? ++ F2FS_I(inode)->atomic_inode->i_mapping : inode->i_mapping; + struct f2fs_io_info fio = { + .sbi = F2FS_I_SB(inode), + .ino = inode->i_ino, +@@ -1282,7 +1285,7 @@ static int move_data_block(struct inode + CURSEG_ALL_DATA_ATGC : CURSEG_COLD_DATA; + + /* do not read out */ +- page = f2fs_grab_cache_page(inode->i_mapping, bidx, false); ++ page = f2fs_grab_cache_page(mapping, bidx, false); + if (!page) + return -ENOMEM; + +--- a/fs/f2fs/inline.c ++++ b/fs/f2fs/inline.c +@@ -16,7 +16,7 @@ + + static bool support_inline_data(struct inode *inode) + { +- if (f2fs_is_atomic_file(inode)) ++ if (f2fs_used_in_atomic_write(inode)) + return false; + if (!S_ISREG(inode->i_mode) && !S_ISLNK(inode->i_mode)) + return false; +--- a/fs/f2fs/inode.c ++++ b/fs/f2fs/inode.c +@@ -816,8 +816,9 @@ void f2fs_evict_inode(struct inode *inod + + f2fs_abort_atomic_write(inode, true); + +- if (fi->cow_inode) { ++ if (fi->cow_inode && f2fs_is_cow_file(fi->cow_inode)) { + clear_inode_flag(fi->cow_inode, FI_COW_FILE); ++ F2FS_I(fi->cow_inode)->atomic_inode = NULL; + iput(fi->cow_inode); + fi->cow_inode = NULL; + } diff --git a/queue-6.10/fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch b/queue-6.10/fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch new file mode 100644 index 00000000000..2d345c6d1ee --- /dev/null +++ b/queue-6.10/fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch @@ -0,0 +1,36 @@ +From 2fef55d8f78383c8e6d6d4c014b9597375132696 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Wed, 29 May 2024 14:40:52 +0800 +Subject: fs/ntfs3: Update log->page_{mask,bits} if log->page_size changed + +From: Huacai Chen + +commit 2fef55d8f78383c8e6d6d4c014b9597375132696 upstream. + +If an NTFS file system is mounted to another system with different +PAGE_SIZE from the original system, log->page_size will change in +log_replay(), but log->page_{mask,bits} don't change correspondingly. +This will cause a panic because "u32 bytes = log->page_size - page_off" +will get a negative value in the later read_log_page(). + +Cc: stable@vger.kernel.org +Fixes: b46acd6a6a627d876898e ("fs/ntfs3: Add NTFS journal") +Signed-off-by: Huacai Chen +Signed-off-by: Konstantin Komarov +Signed-off-by: Greg Kroah-Hartman +--- + fs/ntfs3/fslog.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/ntfs3/fslog.c ++++ b/fs/ntfs3/fslog.c +@@ -3922,6 +3922,9 @@ check_restart_area: + goto out; + } + ++ log->page_mask = log->page_size - 1; ++ log->page_bits = blksize_bits(log->page_size); ++ + /* If the file size has shrunk then we won't mount it. */ + if (log->l_size < le64_to_cpu(ra2->l_size)) { + err = -EINVAL; diff --git a/queue-6.10/mm-page_alloc-fix-pcp-count-race-between-drain_pages_zone-vs-__rmqueue_pcplist.patch b/queue-6.10/mm-page_alloc-fix-pcp-count-race-between-drain_pages_zone-vs-__rmqueue_pcplist.patch new file mode 100644 index 00000000000..ce169eb4fcc --- /dev/null +++ b/queue-6.10/mm-page_alloc-fix-pcp-count-race-between-drain_pages_zone-vs-__rmqueue_pcplist.patch @@ -0,0 +1,93 @@ +From 66eca1021a42856d6af2a9802c99e160278aed91 Mon Sep 17 00:00:00 2001 +From: Li Zhijian +Date: Tue, 23 Jul 2024 14:44:28 +0800 +Subject: mm/page_alloc: fix pcp->count race between drain_pages_zone() vs __rmqueue_pcplist() + +From: Li Zhijian + +commit 66eca1021a42856d6af2a9802c99e160278aed91 upstream. + +It's expected that no page should be left in pcp_list after calling +zone_pcp_disable() in offline_pages(). Previously, it's observed that +offline_pages() gets stuck [1] due to some pages remaining in pcp_list. + +Cause: +There is a race condition between drain_pages_zone() and __rmqueue_pcplist() +involving the pcp->count variable. See below scenario: + + CPU0 CPU1 + ---------------- --------------- + spin_lock(&pcp->lock); + __rmqueue_pcplist() { +zone_pcp_disable() { + /* list is empty */ + if (list_empty(list)) { + /* add pages to pcp_list */ + alloced = rmqueue_bulk() + mutex_lock(&pcp_batch_high_lock) + ... + __drain_all_pages() { + drain_pages_zone() { + /* read pcp->count, it's 0 here */ + count = READ_ONCE(pcp->count) + /* 0 means nothing to drain */ + /* update pcp->count */ + pcp->count += alloced << order; + ... + ... + spin_unlock(&pcp->lock); + +In this case, after calling zone_pcp_disable() though, there are still some +pages in pcp_list. And these pages in pcp_list are neither movable nor +isolated, offline_pages() gets stuck as a result. + +Solution: +Expand the scope of the pcp->lock to also protect pcp->count in +drain_pages_zone(), to ensure no pages are left in the pcp list after +zone_pcp_disable() + +[1] https://lore.kernel.org/linux-mm/6a07125f-e720-404c-b2f9-e55f3f166e85@fujitsu.com/ + +Link: https://lkml.kernel.org/r/20240723064428.1179519-1-lizhijian@fujitsu.com +Fixes: 4b23a68f9536 ("mm/page_alloc: protect PCP lists with a spinlock") +Signed-off-by: Li Zhijian +Reported-by: Yao Xingtao +Reviewed-by: Vlastimil Babka +Cc: David Hildenbrand +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + mm/page_alloc.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -2323,16 +2323,20 @@ void drain_zone_pages(struct zone *zone, + static void drain_pages_zone(unsigned int cpu, struct zone *zone) + { + struct per_cpu_pages *pcp = per_cpu_ptr(zone->per_cpu_pageset, cpu); +- int count = READ_ONCE(pcp->count); +- +- while (count) { +- int to_drain = min(count, pcp->batch << CONFIG_PCP_BATCH_SCALE_MAX); +- count -= to_drain; ++ int count; + ++ do { + spin_lock(&pcp->lock); +- free_pcppages_bulk(zone, to_drain, pcp, 0); ++ count = pcp->count; ++ if (count) { ++ int to_drain = min(count, ++ pcp->batch << CONFIG_PCP_BATCH_SCALE_MAX); ++ ++ free_pcppages_bulk(zone, to_drain, pcp, 0); ++ count -= to_drain; ++ } + spin_unlock(&pcp->lock); +- } ++ } while (count); + } + + /* diff --git a/queue-6.10/nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch b/queue-6.10/nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch new file mode 100644 index 00000000000..0928da9c028 --- /dev/null +++ b/queue-6.10/nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch @@ -0,0 +1,97 @@ +From 4811f7af6090e8f5a398fbdd766f903ef6c0d787 Mon Sep 17 00:00:00 2001 +From: Ryusuke Konishi +Date: Thu, 25 Jul 2024 14:20:07 +0900 +Subject: nilfs2: handle inconsistent state in nilfs_btnode_create_block() + +From: Ryusuke Konishi + +commit 4811f7af6090e8f5a398fbdd766f903ef6c0d787 upstream. + +Syzbot reported that a buffer state inconsistency was detected in +nilfs_btnode_create_block(), triggering a kernel bug. + +It is not appropriate to treat this inconsistency as a bug; it can occur +if the argument block address (the buffer index of the newly created +block) is a virtual block number and has been reallocated due to +corruption of the bitmap used to manage its allocation state. + +So, modify nilfs_btnode_create_block() and its callers to treat it as a +possible filesystem error, rather than triggering a kernel bug. + +Link: https://lkml.kernel.org/r/20240725052007.4562-1-konishi.ryusuke@gmail.com +Fixes: a60be987d45d ("nilfs2: B-tree node cache") +Signed-off-by: Ryusuke Konishi +Reported-by: syzbot+89cc4f2324ed37988b60@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=89cc4f2324ed37988b60 +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman +--- + fs/nilfs2/btnode.c | 25 ++++++++++++++++++++----- + fs/nilfs2/btree.c | 4 ++-- + 2 files changed, 22 insertions(+), 7 deletions(-) + +--- a/fs/nilfs2/btnode.c ++++ b/fs/nilfs2/btnode.c +@@ -51,12 +51,21 @@ nilfs_btnode_create_block(struct address + + bh = nilfs_grab_buffer(inode, btnc, blocknr, BIT(BH_NILFS_Node)); + if (unlikely(!bh)) +- return NULL; ++ return ERR_PTR(-ENOMEM); + + if (unlikely(buffer_mapped(bh) || buffer_uptodate(bh) || + buffer_dirty(bh))) { +- brelse(bh); +- BUG(); ++ /* ++ * The block buffer at the specified new address was already ++ * in use. This can happen if it is a virtual block number ++ * and has been reallocated due to corruption of the bitmap ++ * used to manage its allocation state (if not, the buffer ++ * clearing of an abandoned b-tree node is missing somewhere). ++ */ ++ nilfs_error(inode->i_sb, ++ "state inconsistency probably due to duplicate use of b-tree node block address %llu (ino=%lu)", ++ (unsigned long long)blocknr, inode->i_ino); ++ goto failed; + } + memset(bh->b_data, 0, i_blocksize(inode)); + bh->b_bdev = inode->i_sb->s_bdev; +@@ -67,6 +76,12 @@ nilfs_btnode_create_block(struct address + folio_unlock(bh->b_folio); + folio_put(bh->b_folio); + return bh; ++ ++failed: ++ folio_unlock(bh->b_folio); ++ folio_put(bh->b_folio); ++ brelse(bh); ++ return ERR_PTR(-EIO); + } + + int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr, +@@ -217,8 +232,8 @@ retry: + } + + nbh = nilfs_btnode_create_block(btnc, newkey); +- if (!nbh) +- return -ENOMEM; ++ if (IS_ERR(nbh)) ++ return PTR_ERR(nbh); + + BUG_ON(nbh == obh); + ctxt->newbh = nbh; +--- a/fs/nilfs2/btree.c ++++ b/fs/nilfs2/btree.c +@@ -63,8 +63,8 @@ static int nilfs_btree_get_new_block(con + struct buffer_head *bh; + + bh = nilfs_btnode_create_block(btnc, ptr); +- if (!bh) +- return -ENOMEM; ++ if (IS_ERR(bh)) ++ return PTR_ERR(bh); + + set_buffer_nilfs_volatile(bh); + *bhp = bh; diff --git a/queue-6.10/scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch b/queue-6.10/scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch new file mode 100644 index 00000000000..8915780ac4c --- /dev/null +++ b/queue-6.10/scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch @@ -0,0 +1,39 @@ +From ce2065c4cc4f05635413f63f6dc038d7d4842e31 Mon Sep 17 00:00:00 2001 +From: Saurav Kashyap +Date: Wed, 10 Jul 2024 22:40:50 +0530 +Subject: scsi: qla2xxx: Return ENOBUFS if sg_cnt is more than one for ELS cmds + +From: Saurav Kashyap + +commit ce2065c4cc4f05635413f63f6dc038d7d4842e31 upstream. + +Firmware only supports single DSDs in ELS Pass-through IOCB (0x53h), sg cnt +is decided by the SCSI ML. User is not aware of the cause of an acutal +error. + +Return the appropriate return code that will be decoded by API and +application and proper error message will be displayed to user. + +Fixes: 6e98016ca077 ("[SCSI] qla2xxx: Re-organized BSG interface specific code.") +Cc: stable@vger.kernel.org +Signed-off-by: Saurav Kashyap +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20240710171057.35066-5-njavali@marvell.com +Reviewed-by: Himanshu Madhani +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_bsg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/qla2xxx/qla_bsg.c ++++ b/drivers/scsi/qla2xxx/qla_bsg.c +@@ -324,7 +324,7 @@ qla2x00_process_els(struct bsg_job *bsg_ + "request_sg_cnt=%x reply_sg_cnt=%x.\n", + bsg_job->request_payload.sg_cnt, + bsg_job->reply_payload.sg_cnt); +- rval = -EPERM; ++ rval = -ENOBUFS; + goto done; + } + diff --git a/queue-6.10/series b/queue-6.10/series index 7e50fc1bd4d..b461cdee0ef 100644 --- a/queue-6.10/series +++ b/queue-6.10/series @@ -645,3 +645,14 @@ dev-parport-fix-the-array-out-of-bounds-risk.patch hostfs-fix-dev_t-handling.patch efi-libstub-zero-initialize-heap-allocated-struct-screen_info.patch erofs-fix-race-in-z_erofs_get_gbuf.patch +mm-page_alloc-fix-pcp-count-race-between-drain_pages_zone-vs-__rmqueue_pcplist.patch +fs-ntfs3-update-log-page_-mask-bits-if-log-page_size-changed.patch +scsi-qla2xxx-return-enobufs-if-sg_cnt-is-more-than-one-for-els-cmds.patch +asoc-fsl-fsl_qmc_audio-check-devm_kasprintf-returned-value.patch +f2fs-fix-to-force-buffered-io-on-inline_data-inode.patch +f2fs-fix-to-don-t-dirty-inode-for-readonly-filesystem.patch +f2fs-fix-return-value-of-f2fs_convert_inline_inode.patch +f2fs-use-meta-inode-for-gc-of-atomic-file.patch +f2fs-use-meta-inode-for-gc-of-cow-file.patch +dmaengine-fsl-edma-change-the-memory-access-from-local-into-remote-mode-in-i.mx-8qm.patch +nilfs2-handle-inconsistent-state-in-nilfs_btnode_create_block.patch