From a279adedbb5206ccadb6b2817838cbb1c834133d Mon Sep 17 00:00:00 2001 From: Yangtao Li Date: Fri, 3 Mar 2023 14:37:31 +0800 Subject: [PATCH 1/5] erofs: mark z_erofs_lzma_init/erofs_pcpubuf_init w/ __init They are used during the erofs module init phase. Let's mark it as __init like any other function. Signed-off-by: Yangtao Li Reviewed-by: Yue Hu Reviewed-by: Gao Xiang Reviewed-by: Chao Yu Link: https://lore.kernel.org/r/20230303063731.66760-1-frank.li@vivo.com Signed-off-by: Gao Xiang --- fs/erofs/decompressor_lzma.c | 2 +- fs/erofs/internal.h | 4 ++-- fs/erofs/pcpubuf.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c index 091fd5adf818..307b37f0b9f5 100644 --- a/fs/erofs/decompressor_lzma.c +++ b/fs/erofs/decompressor_lzma.c @@ -47,7 +47,7 @@ void z_erofs_lzma_exit(void) } } -int z_erofs_lzma_init(void) +int __init z_erofs_lzma_init(void) { unsigned int i; diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index 3f3561d37d1b..1db018f8c2e8 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -486,7 +486,7 @@ static inline void *erofs_vm_map_ram(struct page **pages, unsigned int count) void *erofs_get_pcpubuf(unsigned int requiredpages); void erofs_put_pcpubuf(void *ptr); int erofs_pcpubuf_growsize(unsigned int nrpages); -void erofs_pcpubuf_init(void); +void __init erofs_pcpubuf_init(void); void erofs_pcpubuf_exit(void); int erofs_register_sysfs(struct super_block *sb); @@ -545,7 +545,7 @@ static inline int z_erofs_fill_inode(struct inode *inode) { return -EOPNOTSUPP; #endif /* !CONFIG_EROFS_FS_ZIP */ #ifdef CONFIG_EROFS_FS_ZIP_LZMA -int z_erofs_lzma_init(void); +int __init z_erofs_lzma_init(void); void z_erofs_lzma_exit(void); int z_erofs_load_lzma_config(struct super_block *sb, struct erofs_super_block *dsb, diff --git a/fs/erofs/pcpubuf.c b/fs/erofs/pcpubuf.c index a2efd833d1b6..c7a4b1d77069 100644 --- a/fs/erofs/pcpubuf.c +++ b/fs/erofs/pcpubuf.c @@ -114,7 +114,7 @@ int erofs_pcpubuf_growsize(unsigned int nrpages) return ret; } -void erofs_pcpubuf_init(void) +void __init erofs_pcpubuf_init(void) { int cpu; From 8f121dfb15f7b4ab345992ce96003eb63fd608f4 Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Sun, 5 Mar 2023 21:44:55 +0800 Subject: [PATCH 2/5] erofs: fix wrong kunmap when using LZMA on HIGHMEM platforms As the call trace shown, the root cause is kunmap incorrect pages: BUG: kernel NULL pointer dereference, address: 00000000 CPU: 1 PID: 40 Comm: kworker/u5:0 Not tainted 6.2.0-rc5 #4 Workqueue: erofs_worker z_erofs_decompressqueue_work EIP: z_erofs_lzma_decompress+0x34b/0x8ac z_erofs_decompress+0x12/0x14 z_erofs_decompress_queue+0x7e7/0xb1c z_erofs_decompressqueue_work+0x32/0x60 process_one_work+0x24b/0x4d8 ? process_one_work+0x1a4/0x4d8 worker_thread+0x14c/0x3fc kthread+0xe6/0x10c ? rescuer_thread+0x358/0x358 ? kthread_complete_and_exit+0x18/0x18 ret_from_fork+0x1c/0x28 ---[ end trace 0000000000000000 ]--- The bug is trivial and should be fixed now. It has no impact on !HIGHMEM platforms. Fixes: 622ceaddb764 ("erofs: lzma compression support") Cc: # 5.16+ Reviewed-by: Yue Hu Reviewed-by: Chao Yu Signed-off-by: Gao Xiang Link: https://lore.kernel.org/r/20230305134455.88236-1-hsiangkao@linux.alibaba.com --- fs/erofs/decompressor_lzma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c index 307b37f0b9f5..d38e19c11270 100644 --- a/fs/erofs/decompressor_lzma.c +++ b/fs/erofs/decompressor_lzma.c @@ -278,7 +278,7 @@ int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq, } } if (no < nrpages_out && strm->buf.out) - kunmap(rq->in[no]); + kunmap(rq->out[no]); if (ni < nrpages_in) kunmap(rq->in[ni]); /* 4. push back LZMA stream context to the global list */ From 647dd2c3f0e16b71a1a77897d038164d48eea154 Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Thu, 9 Mar 2023 13:31:47 +0800 Subject: [PATCH 3/5] erofs: Revert "erofs: fix kvcalloc() misuse with __GFP_NOFAIL" Let's revert commit 12724ba38992 ("erofs: fix kvcalloc() misuse with __GFP_NOFAIL") since kvmalloc() already supports __GFP_NOFAIL in commit a421ef303008 ("mm: allow !GFP_KERNEL allocations for kvmalloc"). So the original fix was wrong. Actually there was some issue as [1] discussed, so before that mm fix is landed, the warn could still happen but applying this commit first will cause less. [1] https://lore.kernel.org/r/20230305053035.1911-1-hsiangkao@linux.alibaba.com Fixes: 12724ba38992 ("erofs: fix kvcalloc() misuse with __GFP_NOFAIL") Reviewed-by: Chao Yu Link: https://lore.kernel.org/r/20230309053148.9223-1-hsiangkao@linux.alibaba.com Signed-off-by: Gao Xiang --- fs/erofs/zdata.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index 3247d2422bea..f1708c77a991 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -1312,12 +1312,12 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, if (!be->decompressed_pages) be->decompressed_pages = - kcalloc(be->nr_pages, sizeof(struct page *), - GFP_KERNEL | __GFP_NOFAIL); + kvcalloc(be->nr_pages, sizeof(struct page *), + GFP_KERNEL | __GFP_NOFAIL); if (!be->compressed_pages) be->compressed_pages = - kcalloc(pclusterpages, sizeof(struct page *), - GFP_KERNEL | __GFP_NOFAIL); + kvcalloc(pclusterpages, sizeof(struct page *), + GFP_KERNEL | __GFP_NOFAIL); z_erofs_parse_out_bvecs(be); err2 = z_erofs_parse_in_bvecs(be, &overlapped); @@ -1365,7 +1365,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, } if (be->compressed_pages < be->onstack_pages || be->compressed_pages >= be->onstack_pages + Z_EROFS_ONSTACK_PAGES) - kfree(be->compressed_pages); + kvfree(be->compressed_pages); z_erofs_fill_other_copies(be, err); for (i = 0; i < be->nr_pages; ++i) { @@ -1384,7 +1384,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, } if (be->decompressed_pages != be->onstack_pages) - kfree(be->decompressed_pages); + kvfree(be->decompressed_pages); pcl->length = 0; pcl->partial = true; From 9ff471800b74f5f952c7e75a0355f1d30ee2b046 Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Thu, 9 Mar 2023 13:31:48 +0800 Subject: [PATCH 4/5] erofs: get rid of a useless DBG_BUGON `err` could be -EINTR and it should not be the case. Actually such DBG_BUGON is useless. Reviewed-by: Chao Yu Link: https://lore.kernel.org/r/20230309053148.9223-2-hsiangkao@linux.alibaba.com Signed-off-by: Gao Xiang --- fs/erofs/zmap.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index 8bf6d30518b6..655da4d739cb 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -757,9 +757,6 @@ int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map, err = z_erofs_do_map_blocks(inode, map, flags); out: trace_z_erofs_map_blocks_iter_exit(inode, map, flags, err); - - /* aggressively BUG_ON iff CONFIG_EROFS_FS_DEBUG is on */ - DBG_BUGON(err < 0 && err != -ENOMEM); return err; } From 3993f4f456309580445bb515fbc609d995b6a3ae Mon Sep 17 00:00:00 2001 From: Yue Hu Date: Mon, 6 Mar 2023 15:55:27 +0800 Subject: [PATCH 5/5] erofs: use wrapper i_blocksize() in erofs_file_read_iter() linux/fs.h has a wrapper for this operation. Signed-off-by: Yue Hu Reviewed-by: Gao Xiang Reviewed-by: Chao Yu Link: https://lore.kernel.org/r/20230306075527.1338-1-zbestahu@gmail.com Signed-off-by: Gao Xiang --- fs/erofs/data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/erofs/data.c b/fs/erofs/data.c index e16545849ea7..c08c0f578bc6 100644 --- a/fs/erofs/data.c +++ b/fs/erofs/data.c @@ -376,7 +376,7 @@ static ssize_t erofs_file_read_iter(struct kiocb *iocb, struct iov_iter *to) if (bdev) blksize_mask = bdev_logical_block_size(bdev) - 1; else - blksize_mask = (1 << inode->i_blkbits) - 1; + blksize_mask = i_blocksize(inode) - 1; if ((iocb->ki_pos | iov_iter_count(to) | iov_iter_alignment(to)) & blksize_mask)