From nobody Wed Apr 8 07:43:21 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77880C32792 for ; Mon, 22 Aug 2022 21:56:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234803AbiHVV4D (ORCPT ); Mon, 22 Aug 2022 17:56:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49708 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230081AbiHVV4B (ORCPT ); Mon, 22 Aug 2022 17:56:01 -0400 Received: from p3plwbeout16-06.prod.phx3.secureserver.net (p3plsmtp16-06-2.prod.phx3.secureserver.net [173.201.193.64]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 64086558D8 for ; Mon, 22 Aug 2022 14:55:58 -0700 (PDT) Received: from mailex.mailcore.me ([94.136.40.144]) by :WBEOUT: with ESMTP id QFOloDwIMMXmVQFOloILK8; Mon, 22 Aug 2022 14:55:56 -0700 X-CMAE-Analysis: v=2.4 cv=EYgN/NqC c=1 sm=1 tr=0 ts=6303fb6d a=wXHyRMViKMYRd//SnbHIqA==:117 a=84ok6UeoqCVsigPHarzEiQ==:17 a=ggZhUymU-5wA:10 a=biHskzXt2R4A:10 a=lZFbU4aQAAAA:8 a=FXvPX3liAAAA:8 a=gbRoYUdNN1fX-E31I0kA:9 a=yKZbCDypxrTF-tGext6c:22 a=UObqyxdv-6Yh2QiB9mM_:22 X-SECURESERVER-ACCT: phillip@squashfs.org.uk X-SID: QFOloDwIMMXmV Received: from 82-69-79-175.dsl.in-addr.zen.co.uk ([82.69.79.175] helo=phoenix.fritz.box) by smtp02.mailcore.me with esmtpa (Exim 4.94.2) (envelope-from ) id 1oQFOk-000Clp-BD; Mon, 22 Aug 2022 22:55:54 +0100 From: Phillip Lougher To: linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, akpm@linux-foundation.org, Phillip Lougher , Chris Murphy Subject: [PATCH] Squashfs: don't call kmalloc in decompressors Date: Mon, 22 Aug 2022 22:54:30 +0100 Message-Id: <20220822215430.15933-1-phillip@squashfs.org.uk> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Mailcore-Auth: 439999529 X-Mailcore-Domain: 1394945 X-123-reg-Authenticated: phillip@squashfs.org.uk X-Originating-IP: 82.69.79.175 X-CMAE-Envelope: MS4xfMRATBo/usai2DMDrUc9NVuRYTs+FFi3XKWOVn8r9gUPMPN5qf4mXY3WN22x1jhvAeo795SsByAcPzp5YGNA5LK6fjx7vrcju0IYOFHlC+r2C6WDvASM XXPXczRVuVkCgTvfRgOTTP5p3ISplnMhnY1QDt9HGME0JjpBzyN/8CyonBlbbYKAiPg5uyqNgXY6H/yS3ZM0V6Y5oenWYZxbEWU0JmX9rxDsTUONY9kJZfem 9jY/vkpThTDI97f9HH/wXw== Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The decompressors may be called while in an atomic section. So move the kmalloc() out of this path, and into the "page actor" init function. This fixes a regression introduced by commit f268eedddf35 ("squashfs: extend "page actor" to handle missing pages") Reported-by: Chris Murphy Signed-off-by: Phillip Lougher --- fs/squashfs/file.c | 2 +- fs/squashfs/file_direct.c | 2 +- fs/squashfs/page_actor.c | 34 +++++++++++++++------------------- fs/squashfs/page_actor.h | 5 +++++ 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c index 98e64fec75b7..e56510964b22 100644 --- a/fs/squashfs/file.c +++ b/fs/squashfs/file.c @@ -593,7 +593,7 @@ static void squashfs_readahead(struct readahead_control= *ractl) =20 res =3D squashfs_read_data(inode->i_sb, block, bsize, NULL, actor); =20 - kfree(actor); + squashfs_page_actor_free(actor); =20 if (res =3D=3D expected) { int bytes; diff --git a/fs/squashfs/file_direct.c b/fs/squashfs/file_direct.c index be4b12d31e0c..f1ccad519e28 100644 --- a/fs/squashfs/file_direct.c +++ b/fs/squashfs/file_direct.c @@ -74,7 +74,7 @@ int squashfs_readpage_block(struct page *target_page, u64= block, int bsize, /* Decompress directly into the page cache buffers */ res =3D squashfs_read_data(inode->i_sb, block, bsize, NULL, actor); =20 - kfree(actor); + squashfs_page_actor_free(actor); =20 if (res < 0) goto mark_errored; diff --git a/fs/squashfs/page_actor.c b/fs/squashfs/page_actor.c index b23b780d8f42..54b93bf4a25c 100644 --- a/fs/squashfs/page_actor.c +++ b/fs/squashfs/page_actor.c @@ -52,6 +52,7 @@ struct squashfs_page_actor *squashfs_page_actor_init(void= **buffer, actor->buffer =3D buffer; actor->pages =3D pages; actor->next_page =3D 0; + actor->tmp_buffer =3D NULL; actor->squashfs_first_page =3D cache_first_page; actor->squashfs_next_page =3D cache_next_page; actor->squashfs_finish_page =3D cache_finish_page; @@ -68,20 +69,9 @@ static void *handle_next_page(struct squashfs_page_actor= *actor) =20 if ((actor->next_page =3D=3D actor->pages) || (actor->next_index !=3D actor->page[actor->next_page]->index)) { - if (actor->alloc_buffer) { - void *tmp_buffer =3D kmalloc(PAGE_SIZE, GFP_KERNEL); - - if (tmp_buffer) { - actor->tmp_buffer =3D tmp_buffer; - actor->next_index++; - actor->returned_pages++; - return tmp_buffer; - } - } - actor->next_index++; actor->returned_pages++; - return ERR_PTR(-ENOMEM); + return actor->alloc_buffer ? actor->tmp_buffer : ERR_PTR(-ENOMEM); } =20 actor->next_index++; @@ -96,11 +86,10 @@ static void *direct_first_page(struct squashfs_page_act= or *actor) =20 static void *direct_next_page(struct squashfs_page_actor *actor) { - if (actor->pageaddr) + if (actor->pageaddr) { kunmap_local(actor->pageaddr); - - kfree(actor->tmp_buffer); - actor->pageaddr =3D actor->tmp_buffer =3D NULL; + actor->pageaddr =3D NULL; + } =20 return handle_next_page(actor); } @@ -109,8 +98,6 @@ static void direct_finish_page(struct squashfs_page_acto= r *actor) { if (actor->pageaddr) kunmap_local(actor->pageaddr); - - kfree(actor->tmp_buffer); } =20 struct squashfs_page_actor *squashfs_page_actor_init_special(struct squash= fs_sb_info *msblk, @@ -121,6 +108,16 @@ struct squashfs_page_actor *squashfs_page_actor_init_s= pecial(struct squashfs_sb_ if (actor =3D=3D NULL) return NULL; =20 + if (msblk->decompressor->alloc_buffer) { + actor->tmp_buffer =3D kmalloc(PAGE_SIZE, GFP_KERNEL); + + if (actor->tmp_buffer =3D=3D NULL) { + kfree(actor); + return NULL; + } + } else + actor->tmp_buffer =3D NULL; + actor->length =3D length ? : pages * PAGE_SIZE; actor->page =3D page; actor->pages =3D pages; @@ -128,7 +125,6 @@ struct squashfs_page_actor *squashfs_page_actor_init_sp= ecial(struct squashfs_sb_ actor->returned_pages =3D 0; actor->next_index =3D page[0]->index & ~((1 << (msblk->block_log - PAGE_S= HIFT)) - 1); actor->pageaddr =3D NULL; - actor->tmp_buffer =3D NULL; actor->alloc_buffer =3D msblk->decompressor->alloc_buffer; actor->squashfs_first_page =3D direct_first_page; actor->squashfs_next_page =3D direct_next_page; diff --git a/fs/squashfs/page_actor.h b/fs/squashfs/page_actor.h index 24841d28bc0f..95ffbb543d91 100644 --- a/fs/squashfs/page_actor.h +++ b/fs/squashfs/page_actor.h @@ -29,6 +29,11 @@ extern struct squashfs_page_actor *squashfs_page_actor_i= nit(void **buffer, extern struct squashfs_page_actor *squashfs_page_actor_init_special( struct squashfs_sb_info *msblk, struct page **page, int pages, int length); +static inline void squashfs_page_actor_free(struct squashfs_page_actor *ac= tor) +{ + kfree(actor->tmp_buffer); + kfree(actor); +} static inline void *squashfs_first_page(struct squashfs_page_actor *actor) { return actor->squashfs_first_page(actor); --=20 2.35.1