From patchwork Mon Aug 22 21:54:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Phillip Lougher X-Patchwork-Id: 12951417 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 17D99C28D13 for ; Mon, 22 Aug 2022 21:56:03 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 7FE698D0003; Mon, 22 Aug 2022 17:56:02 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 7ADCE8D0002; Mon, 22 Aug 2022 17:56:02 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 675228D0003; Mon, 22 Aug 2022 17:56:02 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 5836E8D0002 for ; Mon, 22 Aug 2022 17:56:02 -0400 (EDT) Received: from smtpin23.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 273A01A01C4 for ; Mon, 22 Aug 2022 21:56:02 +0000 (UTC) X-FDA: 79828586964.23.B111797 Received: from p3plwbeout25-01.prod.phx3.secureserver.net (p3plsmtp25-01-2.prod.phx3.secureserver.net [216.69.139.12]) by imf09.hostedemail.com (Postfix) with ESMTP id AF069140023 for ; Mon, 22 Aug 2022 21:56:00 +0000 (UTC) Received: from mailex.mailcore.me ([94.136.40.144]) by :WBEOUT: with ESMTP id QFOloC8E8sB3IQFOloJDrz; Mon, 22 Aug 2022 14:55:56 -0700 X-CMAE-Analysis: v=2.4 cv=ZZPYiuZA 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: QFOloC8E8sB3I 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 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: MS4xfPwPPA5ElWZNlowEai4ZJsAVqOg1L0p2DTQ29WlBsdg4yIa/KBX/PcJyQBLPATWcvf+zOhuwYJmHv8kRsL5IybxYS1IiTaevV36KIJjQUYvfovb20H2r x5+l3HanlELvydwvNwEZekwhvG+WugF0lytJrh1ZK839aXMZrSDjLQbSlfk2WrAW2EHsEZ4uozLS7FY7NYU3YbScXrS6DNc7a5k= ARC-Authentication-Results: i=1; imf09.hostedemail.com; dkim=none; spf=none (imf09.hostedemail.com: domain of phillip@squashfs.org.uk has no SPF policy when checking 216.69.139.12) smtp.mailfrom=phillip@squashfs.org.uk; dmarc=none ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1661205361; a=rsa-sha256; cv=none; b=ZqJb4rpirgpnqpY/9DZ4P7sRc/DkB9FUUTVvfhAK6xw01XzOg8DJ3+ajRkn4K1mRMmNp44 Dr7SUrbVBeXuycclX9GD3bNPRgHhZRQ8TAs+/hS1/5tFsazO6p2nDTbGyDdFD1tiXGVOLV RQQfjWEKkWTT3mQP0VXoNYyTUNL//V4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1661205361; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:references; bh=GjN7dBuKSGzUnGAA4a1orajQrNezU6JpxlcpYk1jKbg=; b=rpm39AMe3ynyWV4ECseSHlkF/REyyNZWb8HcMSpSC6Rl8NnLNMr5wKiR/8txpKmPkCMgTT yv2LnveNfe/RsB74rqmUoG5Sd78IRlmVvA+jU7gMVk7UeY70vr+hDutad3YoDVmt50CG+/ vf9rnRyj9X1Wbi8ZlPphdtfvRoi9+Ug= Authentication-Results: imf09.hostedemail.com; dkim=none; spf=none (imf09.hostedemail.com: domain of phillip@squashfs.org.uk has no SPF policy when checking 216.69.139.12) smtp.mailfrom=phillip@squashfs.org.uk; dmarc=none X-Rspam-User: X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: AF069140023 X-Stat-Signature: ptfpmiho4mqyt7tuce6qesofjamezy78 X-HE-Tag: 1661205360-407014 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: 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) res = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor); - kfree(actor); + squashfs_page_actor_free(actor); if (res == 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 = squashfs_read_data(inode->i_sb, block, bsize, NULL, actor); - kfree(actor); + squashfs_page_actor_free(actor); 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 = buffer; actor->pages = pages; actor->next_page = 0; + actor->tmp_buffer = NULL; actor->squashfs_first_page = cache_first_page; actor->squashfs_next_page = cache_next_page; actor->squashfs_finish_page = cache_finish_page; @@ -68,20 +69,9 @@ static void *handle_next_page(struct squashfs_page_actor *actor) if ((actor->next_page == actor->pages) || (actor->next_index != actor->page[actor->next_page]->index)) { - if (actor->alloc_buffer) { - void *tmp_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); - - if (tmp_buffer) { - actor->tmp_buffer = 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); } actor->next_index++; @@ -96,11 +86,10 @@ static void *direct_first_page(struct squashfs_page_actor *actor) 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 = actor->tmp_buffer = NULL; + actor->pageaddr = NULL; + } return handle_next_page(actor); } @@ -109,8 +98,6 @@ static void direct_finish_page(struct squashfs_page_actor *actor) { if (actor->pageaddr) kunmap_local(actor->pageaddr); - - kfree(actor->tmp_buffer); } struct squashfs_page_actor *squashfs_page_actor_init_special(struct squashfs_sb_info *msblk, @@ -121,6 +108,16 @@ struct squashfs_page_actor *squashfs_page_actor_init_special(struct squashfs_sb_ if (actor == NULL) return NULL; + if (msblk->decompressor->alloc_buffer) { + actor->tmp_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); + + if (actor->tmp_buffer == NULL) { + kfree(actor); + return NULL; + } + } else + actor->tmp_buffer = NULL; + actor->length = length ? : pages * PAGE_SIZE; actor->page = page; actor->pages = pages; @@ -128,7 +125,6 @@ struct squashfs_page_actor *squashfs_page_actor_init_special(struct squashfs_sb_ actor->returned_pages = 0; actor->next_index = page[0]->index & ~((1 << (msblk->block_log - PAGE_SHIFT)) - 1); actor->pageaddr = NULL; - actor->tmp_buffer = NULL; actor->alloc_buffer = msblk->decompressor->alloc_buffer; actor->squashfs_first_page = direct_first_page; actor->squashfs_next_page = 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_init(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 *actor) +{ + kfree(actor->tmp_buffer); + kfree(actor); +} static inline void *squashfs_first_page(struct squashfs_page_actor *actor) { return actor->squashfs_first_page(actor);