From: Greg Kroah-Hartman Date: Wed, 15 Nov 2023 19:58:50 +0000 (-0500) Subject: fix up f2fs patches X-Git-Tag: v4.14.330~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b390bc7f379791dd0005a5e793880ee505937504;p=thirdparty%2Fkernel%2Fstable-queue.git fix up f2fs patches No need to add major features just to add a single line bugfix :) --- diff --git a/queue-5.15/f2fs-compress-fix-to-avoid-redundant-compress-extens.patch b/queue-5.15/f2fs-compress-fix-to-avoid-redundant-compress-extens.patch index 68633c9da1e..9f90d69c2dd 100644 --- a/queue-5.15/f2fs-compress-fix-to-avoid-redundant-compress-extens.patch +++ b/queue-5.15/f2fs-compress-fix-to-avoid-redundant-compress-extens.patch @@ -23,14 +23,12 @@ Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin --- - fs/f2fs/super.c | 33 +++++++++++++++++++++++++++++++++ + fs/f2fs/super.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index 4b862e4a6a110..6823c09c32521 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c -@@ -542,6 +542,29 @@ static int f2fs_set_test_dummy_encryption(struct super_block *sb, +@@ -540,6 +540,29 @@ static int f2fs_set_test_dummy_encryptio } #ifdef CONFIG_F2FS_FS_COMPRESSION @@ -60,7 +58,7 @@ index 4b862e4a6a110..6823c09c32521 100644 /* * 1. The same extension name cannot not appear in both compress and non-compress extension * at the same time. -@@ -1156,6 +1179,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) +@@ -1154,6 +1177,11 @@ static int parse_options(struct super_bl return -EINVAL; } @@ -72,7 +70,7 @@ index 4b862e4a6a110..6823c09c32521 100644 strcpy(ext[ext_cnt], name); F2FS_OPTION(sbi).compress_ext_cnt++; kfree(name); -@@ -1180,6 +1208,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) +@@ -1178,6 +1206,11 @@ static int parse_options(struct super_bl return -EINVAL; } @@ -84,6 +82,3 @@ index 4b862e4a6a110..6823c09c32521 100644 strcpy(noext[noext_cnt], name); F2FS_OPTION(sbi).nocompress_ext_cnt++; kfree(name); --- -2.42.0 - diff --git a/queue-5.15/f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch b/queue-5.15/f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch index 2619ab72cd7..a5139ab1b12 100644 --- a/queue-5.15/f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch +++ b/queue-5.15/f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch @@ -32,26 +32,22 @@ Fixes: 6ce19aff0b8c ("f2fs: compress: add compress_inode to cache compressed blo Signed-off-by: Chao Yu Signed-off-by: Jaegeuk Kim Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman --- - fs/f2fs/data.c | 4 +++- + fs/f2fs/data.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) -diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c -index 93c14dae4460a..7894a22c15993 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c -@@ -2269,8 +2269,10 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, +@@ -2253,8 +2253,10 @@ skip_reading_dnode: f2fs_wait_on_block_writeback(inode, blkaddr); if (f2fs_load_compressed_page(sbi, page, blkaddr)) { - if (atomic_dec_and_test(&dic->remaining_pages)) + if (atomic_dec_and_test(&dic->remaining_pages)) { - f2fs_decompress_cluster(dic, true); + f2fs_decompress_cluster(dic); + break; + } continue; } --- -2.42.0 - diff --git a/queue-5.15/f2fs-handle-decompress-only-post-processing-in-softi.patch b/queue-5.15/f2fs-handle-decompress-only-post-processing-in-softi.patch deleted file mode 100644 index 39cddcd1e5b..00000000000 --- a/queue-5.15/f2fs-handle-decompress-only-post-processing-in-softi.patch +++ /dev/null @@ -1,582 +0,0 @@ -From 219e7b6fea8ca67b3a430cdbb5b53a2e98a5bad7 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 2 Aug 2022 12:24:37 -0700 -Subject: f2fs: handle decompress only post processing in softirq - -From: Daeho Jeong - -[ Upstream commit bff139b49d9f70c1ac5384aac94554846aa834de ] - -Now decompression is being handled in workqueue and it makes read I/O -latency non-deterministic, because of the non-deterministic scheduling -nature of workqueues. So, I made it handled in softirq context only if -possible, not in low memory devices, since this modification will -maintain decompresion related memory a little longer. - -Signed-off-by: Daeho Jeong -Reviewed-by: Chao Yu -Signed-off-by: Jaegeuk Kim -Stable-dep-of: b0327c84e91a ("f2fs: compress: fix to avoid use-after-free on dic") -Signed-off-by: Sasha Levin ---- - fs/f2fs/compress.c | 203 ++++++++++++++++++++++++++++++--------------- - fs/f2fs/data.c | 52 ++++++++---- - fs/f2fs/f2fs.h | 17 ++-- - 3 files changed, 179 insertions(+), 93 deletions(-) - -diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c -index 455fac164fda0..3849252b1b06f 100644 ---- a/fs/f2fs/compress.c -+++ b/fs/f2fs/compress.c -@@ -738,14 +738,19 @@ static int f2fs_compress_pages(struct compress_ctx *cc) - return ret; - } - --void f2fs_decompress_cluster(struct decompress_io_ctx *dic) -+static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic, -+ bool pre_alloc); -+static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic, -+ bool bypass_destroy_callback, bool pre_alloc); -+ -+void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task) - { - struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); - struct f2fs_inode_info *fi = F2FS_I(dic->inode); - const struct f2fs_compress_ops *cops = - f2fs_cops[fi->i_compress_algorithm]; -+ bool bypass_callback = false; - int ret; -- int i; - - trace_f2fs_decompress_pages_start(dic->inode, dic->cluster_idx, - dic->cluster_size, fi->i_compress_algorithm); -@@ -755,41 +760,10 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic) - goto out_end_io; - } - -- dic->tpages = page_array_alloc(dic->inode, dic->cluster_size); -- if (!dic->tpages) { -- ret = -ENOMEM; -- goto out_end_io; -- } -- -- for (i = 0; i < dic->cluster_size; i++) { -- if (dic->rpages[i]) { -- dic->tpages[i] = dic->rpages[i]; -- continue; -- } -- -- dic->tpages[i] = f2fs_compress_alloc_page(); -- if (!dic->tpages[i]) { -- ret = -ENOMEM; -- goto out_end_io; -- } -- } -- -- if (cops->init_decompress_ctx) { -- ret = cops->init_decompress_ctx(dic); -- if (ret) -- goto out_end_io; -- } -- -- dic->rbuf = f2fs_vmap(dic->tpages, dic->cluster_size); -- if (!dic->rbuf) { -- ret = -ENOMEM; -- goto out_destroy_decompress_ctx; -- } -- -- dic->cbuf = f2fs_vmap(dic->cpages, dic->nr_cpages); -- if (!dic->cbuf) { -- ret = -ENOMEM; -- goto out_vunmap_rbuf; -+ ret = f2fs_prepare_decomp_mem(dic, false); -+ if (ret) { -+ bypass_callback = true; -+ goto out_release; - } - - dic->clen = le32_to_cpu(dic->cbuf->clen); -@@ -797,7 +771,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic) - - if (dic->clen > PAGE_SIZE * dic->nr_cpages - COMPRESS_HEADER_SIZE) { - ret = -EFSCORRUPTED; -- goto out_vunmap_cbuf; -+ goto out_release; - } - - ret = cops->decompress_pages(dic); -@@ -818,17 +792,13 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic) - } - } - --out_vunmap_cbuf: -- vm_unmap_ram(dic->cbuf, dic->nr_cpages); --out_vunmap_rbuf: -- vm_unmap_ram(dic->rbuf, dic->cluster_size); --out_destroy_decompress_ctx: -- if (cops->destroy_decompress_ctx) -- cops->destroy_decompress_ctx(dic); -+out_release: -+ f2fs_release_decomp_mem(dic, bypass_callback, false); -+ - out_end_io: - trace_f2fs_decompress_pages_end(dic->inode, dic->cluster_idx, - dic->clen, ret); -- f2fs_decompress_end_io(dic, ret); -+ f2fs_decompress_end_io(dic, ret, in_task); - } - - /* -@@ -838,7 +808,7 @@ void f2fs_decompress_cluster(struct decompress_io_ctx *dic) - * (or in the case of a failure, cleans up without actually decompressing). - */ - void f2fs_end_read_compressed_page(struct page *page, bool failed, -- block_t blkaddr) -+ block_t blkaddr, bool in_task) - { - struct decompress_io_ctx *dic = - (struct decompress_io_ctx *)page_private(page); -@@ -848,12 +818,12 @@ void f2fs_end_read_compressed_page(struct page *page, bool failed, - - if (failed) - WRITE_ONCE(dic->failed, true); -- else if (blkaddr) -+ else if (blkaddr && in_task) - f2fs_cache_compressed_page(sbi, page, - dic->inode->i_ino, blkaddr); - - if (atomic_dec_and_test(&dic->remaining_pages)) -- f2fs_decompress_cluster(dic); -+ f2fs_decompress_cluster(dic, in_task); - } - - static bool is_page_in_cluster(struct compress_ctx *cc, pgoff_t index) -@@ -1552,16 +1522,85 @@ int f2fs_write_multi_pages(struct compress_ctx *cc, - return err; - } - --static void f2fs_free_dic(struct decompress_io_ctx *dic); -+static inline bool allow_memalloc_for_decomp(struct f2fs_sb_info *sbi, -+ bool pre_alloc) -+{ -+ return pre_alloc ^ f2fs_low_mem_mode(sbi); -+} -+ -+static int f2fs_prepare_decomp_mem(struct decompress_io_ctx *dic, -+ bool pre_alloc) -+{ -+ const struct f2fs_compress_ops *cops = -+ f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm]; -+ int i; -+ -+ if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc)) -+ return 0; -+ -+ dic->tpages = page_array_alloc(dic->inode, dic->cluster_size); -+ if (!dic->tpages) -+ return -ENOMEM; -+ -+ for (i = 0; i < dic->cluster_size; i++) { -+ if (dic->rpages[i]) { -+ dic->tpages[i] = dic->rpages[i]; -+ continue; -+ } -+ -+ dic->tpages[i] = f2fs_compress_alloc_page(); -+ if (!dic->tpages[i]) -+ return -ENOMEM; -+ } -+ -+ dic->rbuf = f2fs_vmap(dic->tpages, dic->cluster_size); -+ if (!dic->rbuf) -+ return -ENOMEM; -+ -+ dic->cbuf = f2fs_vmap(dic->cpages, dic->nr_cpages); -+ if (!dic->cbuf) -+ return -ENOMEM; -+ -+ if (cops->init_decompress_ctx) { -+ int ret = cops->init_decompress_ctx(dic); -+ -+ if (ret) -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void f2fs_release_decomp_mem(struct decompress_io_ctx *dic, -+ bool bypass_destroy_callback, bool pre_alloc) -+{ -+ const struct f2fs_compress_ops *cops = -+ f2fs_cops[F2FS_I(dic->inode)->i_compress_algorithm]; -+ -+ if (!allow_memalloc_for_decomp(F2FS_I_SB(dic->inode), pre_alloc)) -+ return; -+ -+ if (!bypass_destroy_callback && cops->destroy_decompress_ctx) -+ cops->destroy_decompress_ctx(dic); -+ -+ if (dic->cbuf) -+ vm_unmap_ram(dic->cbuf, dic->nr_cpages); -+ -+ if (dic->rbuf) -+ vm_unmap_ram(dic->rbuf, dic->cluster_size); -+} -+ -+static void f2fs_free_dic(struct decompress_io_ctx *dic, -+ bool bypass_destroy_callback); - - struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc) - { - struct decompress_io_ctx *dic; - pgoff_t start_idx = start_idx_of_cluster(cc); -- int i; -+ struct f2fs_sb_info *sbi = F2FS_I_SB(cc->inode); -+ int i, ret; - -- dic = f2fs_kmem_cache_alloc(dic_entry_slab, GFP_F2FS_ZERO, -- false, F2FS_I_SB(cc->inode)); -+ dic = f2fs_kmem_cache_alloc(dic_entry_slab, GFP_F2FS_ZERO, false, sbi); - if (!dic) - return ERR_PTR(-ENOMEM); - -@@ -1587,32 +1626,43 @@ struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc) - dic->nr_rpages = cc->cluster_size; - - dic->cpages = page_array_alloc(dic->inode, dic->nr_cpages); -- if (!dic->cpages) -+ if (!dic->cpages) { -+ ret = -ENOMEM; - goto out_free; -+ } - - for (i = 0; i < dic->nr_cpages; i++) { - struct page *page; - - page = f2fs_compress_alloc_page(); -- if (!page) -+ if (!page) { -+ ret = -ENOMEM; - goto out_free; -+ } - - f2fs_set_compressed_page(page, cc->inode, - start_idx + i + 1, dic); - dic->cpages[i] = page; - } - -+ ret = f2fs_prepare_decomp_mem(dic, true); -+ if (ret) -+ goto out_free; -+ - return dic; - - out_free: -- f2fs_free_dic(dic); -- return ERR_PTR(-ENOMEM); -+ f2fs_free_dic(dic, true); -+ return ERR_PTR(ret); - } - --static void f2fs_free_dic(struct decompress_io_ctx *dic) -+static void f2fs_free_dic(struct decompress_io_ctx *dic, -+ bool bypass_destroy_callback) - { - int i; - -+ f2fs_release_decomp_mem(dic, bypass_destroy_callback, true); -+ - if (dic->tpages) { - for (i = 0; i < dic->cluster_size; i++) { - if (dic->rpages[i]) -@@ -1637,17 +1687,33 @@ static void f2fs_free_dic(struct decompress_io_ctx *dic) - kmem_cache_free(dic_entry_slab, dic); - } - --static void f2fs_put_dic(struct decompress_io_ctx *dic) -+static void f2fs_late_free_dic(struct work_struct *work) -+{ -+ struct decompress_io_ctx *dic = -+ container_of(work, struct decompress_io_ctx, free_work); -+ -+ f2fs_free_dic(dic, false); -+} -+ -+static void f2fs_put_dic(struct decompress_io_ctx *dic, bool in_task) - { -- if (refcount_dec_and_test(&dic->refcnt)) -- f2fs_free_dic(dic); -+ if (refcount_dec_and_test(&dic->refcnt)) { -+ if (in_task) { -+ f2fs_free_dic(dic, false); -+ } else { -+ INIT_WORK(&dic->free_work, f2fs_late_free_dic); -+ queue_work(F2FS_I_SB(dic->inode)->post_read_wq, -+ &dic->free_work); -+ } -+ } - } - - /* - * Update and unlock the cluster's pagecache pages, and release the reference to - * the decompress_io_ctx that was being held for I/O completion. - */ --static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed) -+static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed, -+ bool in_task) - { - int i; - -@@ -1668,7 +1734,7 @@ static void __f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed) - unlock_page(rpage); - } - -- f2fs_put_dic(dic); -+ f2fs_put_dic(dic, in_task); - } - - static void f2fs_verify_cluster(struct work_struct *work) -@@ -1685,14 +1751,15 @@ static void f2fs_verify_cluster(struct work_struct *work) - SetPageError(rpage); - } - -- __f2fs_decompress_end_io(dic, false); -+ __f2fs_decompress_end_io(dic, false, true); - } - - /* - * This is called when a compressed cluster has been decompressed - * (or failed to be read and/or decompressed). - */ --void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed) -+void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed, -+ bool in_task) - { - if (!failed && dic->need_verity) { - /* -@@ -1704,7 +1771,7 @@ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed) - INIT_WORK(&dic->verity_work, f2fs_verify_cluster); - fsverity_enqueue_verify_work(&dic->verity_work); - } else { -- __f2fs_decompress_end_io(dic, failed); -+ __f2fs_decompress_end_io(dic, failed, in_task); - } - } - -@@ -1713,12 +1780,12 @@ void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed) - * - * This is called when the page is no longer needed and can be freed. - */ --void f2fs_put_page_dic(struct page *page) -+void f2fs_put_page_dic(struct page *page, bool in_task) - { - struct decompress_io_ctx *dic = - (struct decompress_io_ctx *)page_private(page); - -- f2fs_put_dic(dic); -+ f2fs_put_dic(dic, in_task); - } - - /* -diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c -index 3956852ad1de0..93c14dae4460a 100644 ---- a/fs/f2fs/data.c -+++ b/fs/f2fs/data.c -@@ -120,7 +120,7 @@ struct bio_post_read_ctx { - block_t fs_blkaddr; - }; - --static void f2fs_finish_read_bio(struct bio *bio) -+static void f2fs_finish_read_bio(struct bio *bio, bool in_task) - { - struct bio_vec *bv; - struct bvec_iter_all iter_all; -@@ -134,8 +134,9 @@ static void f2fs_finish_read_bio(struct bio *bio) - - if (f2fs_is_compressed_page(page)) { - if (bio->bi_status) -- f2fs_end_read_compressed_page(page, true, 0); -- f2fs_put_page_dic(page); -+ f2fs_end_read_compressed_page(page, true, 0, -+ in_task); -+ f2fs_put_page_dic(page, in_task); - continue; - } - -@@ -192,7 +193,7 @@ static void f2fs_verify_bio(struct work_struct *work) - fsverity_verify_bio(bio); - } - -- f2fs_finish_read_bio(bio); -+ f2fs_finish_read_bio(bio, true); - } - - /* -@@ -204,7 +205,7 @@ static void f2fs_verify_bio(struct work_struct *work) - * can involve reading verity metadata pages from the file, and these verity - * metadata pages may be encrypted and/or compressed. - */ --static void f2fs_verify_and_finish_bio(struct bio *bio) -+static void f2fs_verify_and_finish_bio(struct bio *bio, bool in_task) - { - struct bio_post_read_ctx *ctx = bio->bi_private; - -@@ -212,7 +213,7 @@ static void f2fs_verify_and_finish_bio(struct bio *bio) - INIT_WORK(&ctx->work, f2fs_verify_bio); - fsverity_enqueue_verify_work(&ctx->work); - } else { -- f2fs_finish_read_bio(bio); -+ f2fs_finish_read_bio(bio, in_task); - } - } - -@@ -225,7 +226,8 @@ static void f2fs_verify_and_finish_bio(struct bio *bio) - * that the bio includes at least one compressed page. The actual decompression - * is done on a per-cluster basis, not a per-bio basis. - */ --static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx) -+static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx, -+ bool in_task) - { - struct bio_vec *bv; - struct bvec_iter_all iter_all; -@@ -238,7 +240,7 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx) - /* PG_error was set if decryption failed. */ - if (f2fs_is_compressed_page(page)) - f2fs_end_read_compressed_page(page, PageError(page), -- blkaddr); -+ blkaddr, in_task); - else - all_compressed = false; - -@@ -263,15 +265,16 @@ static void f2fs_post_read_work(struct work_struct *work) - fscrypt_decrypt_bio(ctx->bio); - - if (ctx->enabled_steps & STEP_DECOMPRESS) -- f2fs_handle_step_decompress(ctx); -+ f2fs_handle_step_decompress(ctx, true); - -- f2fs_verify_and_finish_bio(ctx->bio); -+ f2fs_verify_and_finish_bio(ctx->bio, true); - } - - static void f2fs_read_end_io(struct bio *bio) - { - struct f2fs_sb_info *sbi = F2FS_P_SB(bio_first_page_all(bio)); - struct bio_post_read_ctx *ctx; -+ bool intask = in_task(); - - iostat_update_and_unbind_ctx(bio, 0); - ctx = bio->bi_private; -@@ -282,16 +285,29 @@ static void f2fs_read_end_io(struct bio *bio) - } - - if (bio->bi_status) { -- f2fs_finish_read_bio(bio); -+ f2fs_finish_read_bio(bio, intask); - return; - } - -- if (ctx && (ctx->enabled_steps & (STEP_DECRYPT | STEP_DECOMPRESS))) { -- INIT_WORK(&ctx->work, f2fs_post_read_work); -- queue_work(ctx->sbi->post_read_wq, &ctx->work); -- } else { -- f2fs_verify_and_finish_bio(bio); -+ if (ctx) { -+ unsigned int enabled_steps = ctx->enabled_steps & -+ (STEP_DECRYPT | STEP_DECOMPRESS); -+ -+ /* -+ * If we have only decompression step between decompression and -+ * decrypt, we don't need post processing for this. -+ */ -+ if (enabled_steps == STEP_DECOMPRESS && -+ !f2fs_low_mem_mode(sbi)) { -+ f2fs_handle_step_decompress(ctx, intask); -+ } else if (enabled_steps) { -+ INIT_WORK(&ctx->work, f2fs_post_read_work); -+ queue_work(ctx->sbi->post_read_wq, &ctx->work); -+ return; -+ } - } -+ -+ f2fs_verify_and_finish_bio(bio, intask); - } - - static void f2fs_write_end_io(struct bio *bio) -@@ -2254,7 +2270,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, - - if (f2fs_load_compressed_page(sbi, page, blkaddr)) { - if (atomic_dec_and_test(&dic->remaining_pages)) -- f2fs_decompress_cluster(dic); -+ f2fs_decompress_cluster(dic, true); - continue; - } - -@@ -2272,7 +2288,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, - page->index, for_write); - if (IS_ERR(bio)) { - ret = PTR_ERR(bio); -- f2fs_decompress_end_io(dic, ret); -+ f2fs_decompress_end_io(dic, ret, true); - f2fs_put_dnode(&dn); - *bio_ret = NULL; - return ret; -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index fb53a35f31b04..1f6b735edc4d5 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -1557,6 +1557,7 @@ struct decompress_io_ctx { - void *private; /* payload buffer for specified decompression algorithm */ - void *private2; /* extra payload buffer */ - struct work_struct verity_work; /* work to verify the decompressed pages */ -+ struct work_struct free_work; /* work for late free this structure itself */ - }; - - #define NULL_CLUSTER ((unsigned int)(~0)) -@@ -4058,9 +4059,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page); - bool f2fs_is_compress_backend_ready(struct inode *inode); - int f2fs_init_compress_mempool(void); - void f2fs_destroy_compress_mempool(void); --void f2fs_decompress_cluster(struct decompress_io_ctx *dic); -+void f2fs_decompress_cluster(struct decompress_io_ctx *dic, bool in_task); - void f2fs_end_read_compressed_page(struct page *page, bool failed, -- block_t blkaddr); -+ block_t blkaddr, bool in_task); - bool f2fs_cluster_is_empty(struct compress_ctx *cc); - bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index); - bool f2fs_sanity_check_cluster(struct dnode_of_data *dn); -@@ -4077,8 +4078,9 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, - unsigned nr_pages, sector_t *last_block_in_bio, - bool is_readahead, bool for_write); - struct decompress_io_ctx *f2fs_alloc_dic(struct compress_ctx *cc); --void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed); --void f2fs_put_page_dic(struct page *page); -+void f2fs_decompress_end_io(struct decompress_io_ctx *dic, bool failed, -+ bool in_task); -+void f2fs_put_page_dic(struct page *page, bool in_task); - unsigned int f2fs_cluster_blocks_are_contiguous(struct dnode_of_data *dn); - int f2fs_init_compress_ctx(struct compress_ctx *cc); - void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse); -@@ -4124,13 +4126,14 @@ static inline struct page *f2fs_compress_control_page(struct page *page) - } - static inline int f2fs_init_compress_mempool(void) { return 0; } - static inline void f2fs_destroy_compress_mempool(void) { } --static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { } -+static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic, -+ bool in_task) { } - static inline void f2fs_end_read_compressed_page(struct page *page, -- bool failed, block_t blkaddr) -+ bool failed, block_t blkaddr, bool in_task) - { - WARN_ON_ONCE(1); - } --static inline void f2fs_put_page_dic(struct page *page) -+static inline void f2fs_put_page_dic(struct page *page, bool in_task) - { - WARN_ON_ONCE(1); - } --- -2.42.0 - diff --git a/queue-5.15/f2fs-introduce-memory-mode.patch b/queue-5.15/f2fs-introduce-memory-mode.patch deleted file mode 100644 index 297b88c7ae8..00000000000 --- a/queue-5.15/f2fs-introduce-memory-mode.patch +++ /dev/null @@ -1,146 +0,0 @@ -From c9b88216941edab0e607dea249f4d4d0df4776c3 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 20 Jun 2022 10:38:42 -0700 -Subject: f2fs: introduce memory mode - -From: Daeho Jeong - -[ Upstream commit 7a8fc586180d8c57db5cc1e2acb32bb9986f642b ] - -Introduce memory mode to supports "normal" and "low" memory modes. -"low" mode is to support low memory devices. Because of the nature of -low memory devices, in this mode, f2fs will try to save memory sometimes -by sacrificing performance. "normal" mode is the default mode and same -as before. - -Signed-off-by: Daeho Jeong -Reviewed-by: Chao Yu -Signed-off-by: Jaegeuk Kim -Stable-dep-of: b0327c84e91a ("f2fs: compress: fix to avoid use-after-free on dic") -Signed-off-by: Sasha Levin ---- - Documentation/filesystems/f2fs.rst | 5 +++++ - fs/f2fs/f2fs.h | 13 +++++++++++++ - fs/f2fs/super.c | 24 ++++++++++++++++++++++++ - 3 files changed, 42 insertions(+) - -diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst -index 7fe50b0bccde9..415bba41597c3 100644 ---- a/Documentation/filesystems/f2fs.rst -+++ b/Documentation/filesystems/f2fs.rst -@@ -323,6 +323,11 @@ discard_unit=%s Control discard unit, the argument can be "block", "segment" - default, it is helpful for large sized SMR or ZNS devices to - reduce memory cost by getting rid of fs metadata supports small - discard. -+memory=%s Control memory mode. This supports "normal" and "low" modes. -+ "low" mode is introduced to support low memory devices. -+ Because of the nature of low memory devices, in this mode, f2fs -+ will try to save memory sometimes by sacrificing performance. -+ "normal" mode is the default mode and same as before. - ======================== ============================================================ - - Debugfs Entries -diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h -index 835ef98643bd4..fb53a35f31b04 100644 ---- a/fs/f2fs/f2fs.h -+++ b/fs/f2fs/f2fs.h -@@ -142,6 +142,7 @@ struct f2fs_mount_info { - int fsync_mode; /* fsync policy */ - int fs_mode; /* fs mode: LFS or ADAPTIVE */ - int bggc_mode; /* bggc mode: off, on or sync */ -+ int memory_mode; /* memory mode */ - int discard_unit; /* - * discard command's offset/size should - * be aligned to this unit: block, -@@ -1330,6 +1331,13 @@ enum { - DISCARD_UNIT_SECTION, /* basic discard unit is section */ - }; - -+enum { -+ MEMORY_MODE_NORMAL, /* memory mode for normal devices */ -+ MEMORY_MODE_LOW, /* memory mode for low memry devices */ -+}; -+ -+ -+ - static inline int f2fs_test_bit(unsigned int nr, char *addr); - static inline void f2fs_set_bit(unsigned int nr, char *addr); - static inline void f2fs_clear_bit(unsigned int nr, char *addr); -@@ -4294,6 +4302,11 @@ static inline bool f2fs_lfs_mode(struct f2fs_sb_info *sbi) - return F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS; - } - -+static inline bool f2fs_low_mem_mode(struct f2fs_sb_info *sbi) -+{ -+ return F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_LOW; -+} -+ - static inline bool f2fs_may_compress(struct inode *inode) - { - if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) || -diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c -index 5c0b2b300aa1b..4b862e4a6a110 100644 ---- a/fs/f2fs/super.c -+++ b/fs/f2fs/super.c -@@ -159,6 +159,7 @@ enum { - Opt_gc_merge, - Opt_nogc_merge, - Opt_discard_unit, -+ Opt_memory_mode, - Opt_err, - }; - -@@ -236,6 +237,7 @@ static match_table_t f2fs_tokens = { - {Opt_gc_merge, "gc_merge"}, - {Opt_nogc_merge, "nogc_merge"}, - {Opt_discard_unit, "discard_unit=%s"}, -+ {Opt_memory_mode, "memory=%s"}, - {Opt_err, NULL}, - }; - -@@ -1241,6 +1243,22 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) - } - kfree(name); - break; -+ case Opt_memory_mode: -+ name = match_strdup(&args[0]); -+ if (!name) -+ return -ENOMEM; -+ if (!strcmp(name, "normal")) { -+ F2FS_OPTION(sbi).memory_mode = -+ MEMORY_MODE_NORMAL; -+ } else if (!strcmp(name, "low")) { -+ F2FS_OPTION(sbi).memory_mode = -+ MEMORY_MODE_LOW; -+ } else { -+ kfree(name); -+ return -EINVAL; -+ } -+ kfree(name); -+ break; - default: - f2fs_err(sbi, "Unrecognized mount option \"%s\" or missing value", - p); -@@ -2012,6 +2030,11 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) - else if (F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_SECTION) - seq_printf(seq, ",discard_unit=%s", "section"); - -+ if (F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_NORMAL) -+ seq_printf(seq, ",memory=%s", "normal"); -+ else if (F2FS_OPTION(sbi).memory_mode == MEMORY_MODE_LOW) -+ seq_printf(seq, ",memory=%s", "low"); -+ - return 0; - } - -@@ -2034,6 +2057,7 @@ static void default_options(struct f2fs_sb_info *sbi) - F2FS_OPTION(sbi).compress_ext_cnt = 0; - F2FS_OPTION(sbi).compress_mode = COMPR_MODE_FS; - F2FS_OPTION(sbi).bggc_mode = BGGC_MODE_ON; -+ F2FS_OPTION(sbi).memory_mode = MEMORY_MODE_NORMAL; - - sbi->sb->s_flags &= ~SB_INLINECRYPT; - --- -2.42.0 - diff --git a/queue-5.15/series b/queue-5.15/series index c5c3de87d03..f15de030d68 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -168,8 +168,6 @@ leds-turris-omnia-drop-unnecessary-mutex-locking.patch leds-turris-omnia-do-not-use-smbus-calls.patch leds-pwm-don-t-disable-the-pwm-when-the-led-should-b.patch leds-trigger-ledtrig-cpu-fix-output-may-be-truncated.patch -f2fs-introduce-memory-mode.patch -f2fs-handle-decompress-only-post-processing-in-softi.patch f2fs-compress-fix-to-avoid-use-after-free-on-dic.patch f2fs-compress-fix-to-avoid-redundant-compress-extens.patch tty-tty_jobctrl-fix-pid-memleak-in-disassociate_ctty.patch