Message ID | 0f40108bed3e084057223bdbe32c4b37f8500ff3.1694845203.git.christophe.jaillet@wanadoo.fr |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:172:b0:3f2:4152:657d with SMTP id h50csp1506078vqi; Fri, 15 Sep 2023 23:21:43 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHzmuFoP18qMAOs60vZPFxJrco2YINaRamv19Rt59tW/X7e0WAIKm0JnIKoa9Fe81JfWMjP X-Received: by 2002:a05:6870:1707:b0:1d6:5658:7989 with SMTP id h7-20020a056870170700b001d656587989mr4861826oae.19.1694845303263; Fri, 15 Sep 2023 23:21:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694845303; cv=none; d=google.com; s=arc-20160816; b=TUcawOfnSwASZrGkx+c98odmsRFmhvVOpnLICe69ClA/n/phvjVzt0nXaPKeCe28Rh p6J7NO3DmRRPAtzQHoZDl94vH13ANGqQLjYR5VjgBjEHWMyH/MXTQdMlKZT2+XmtqcZm AxSYn6fS4Z/dKP8LOUXCSFVImPlfmaQvM+7xvu0FWOuugQQZ0igU12WYhrleE09f/79R h3fmCx2b4eqX5oGKw7Klu5TQ9P2Ns96jjjWOQhkyTo5aqVikzf7k6g1pY52hGrGpUAAw 1uNoR/PkOlD3gE3WS5XKNJiNOV2ZWCXQyO1w1wvKUbUs2fhdHGtEdEq+oyQ9lr8zmk0/ kJuA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=NpZEkdpmUURyXQQ8IOswWsw2MID9l3LvCoklUVqRxWQ=; fh=m3UyueLH4KDy0H9ZPaSnoQRYWYiD76Xl1Jq/Gorb8Ss=; b=ZDgZxgkkJr41NNErtzzCZSyNGPJEEBa/rtsXoSalwbBi47centRtDBtsO2yObbfbLK YjZkayzniWgB0qYJa19rWzwxiknHIBorw3azwPeLCHJLn/JCH2FJl0w4tY9Ev6+JZPOh kFy1tE2WTXFmgqoGW33VS7hIm2i2wojnc4Dep7y/RBicYMiyo0mqH4NbA0oRwiXIOaIf kaFeJbeYrtq9LFQotN5KnxA08DkDM8MWO1llc/kzggxpr1rLfTUJMRISqlWMNyJN0j20 g7oM/kSXfVcNmS2GNEd4ZhyWkUuw8bXkCgtXPOJi2sWi2Msrcl35w2wnlwrvWTYeta/1 3Caw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@wanadoo.fr header.s=t20230301 header.b=DOWhnNS+; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=wanadoo.fr Received: from groat.vger.email (groat.vger.email. [23.128.96.35]) by mx.google.com with ESMTPS id w67-20020a636246000000b00565f617a486si4208184pgb.212.2023.09.15.23.21.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 15 Sep 2023 23:21:43 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) client-ip=23.128.96.35; Authentication-Results: mx.google.com; dkim=pass header.i=@wanadoo.fr header.s=t20230301 header.b=DOWhnNS+; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=wanadoo.fr Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id 8CC8A83CAA57; Fri, 15 Sep 2023 23:21:40 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232942AbjIPGVI (ORCPT <rfc822;toshivichauhan@gmail.com> + 27 others); Sat, 16 Sep 2023 02:21:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43674 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237972AbjIPGUh (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sat, 16 Sep 2023 02:20:37 -0400 Received: from smtp.smtpout.orange.fr (smtp-26.smtpout.orange.fr [80.12.242.26]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 516D919A0 for <linux-kernel@vger.kernel.org>; Fri, 15 Sep 2023 23:20:31 -0700 (PDT) Received: from pop-os.home ([86.243.2.178]) by smtp.orange.fr with ESMTPA id hOfKq4neiXyjrhOfKqtMkJ; Sat, 16 Sep 2023 08:20:29 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wanadoo.fr; s=t20230301; t=1694845229; bh=NpZEkdpmUURyXQQ8IOswWsw2MID9l3LvCoklUVqRxWQ=; h=From:To:Cc:Subject:Date; b=DOWhnNS+NJtCPbiE9W4YqtuJXUQKSvgaUxKLcg8+zkJWr2r+Z/rUpoq5RDAYfTVV8 ylMh7+iiPQ4YJzfK6kILGUA9tJckMqWCqgvHw6IQsKehfjZBEeTqKLEp7cz2uIb+LZ 1YsU5EKs86qNi/jfn8UhsWOGhRkCwHz6cqtxiPyjgiXxMv8dzrhK4ANni96I+MqC5B yP1NSJfc78JtnzGfX2vzL9lg1DJZwW/8slSB3m/24uMERUg0BDSa0MSR/khvQ9IC27 PXpRH76C0gJnZgsFcntRGy3qY8UqpRW2+6LXOvx3zSNFmLlKrOEztHD4gnJGCdtWAg +cZxGPc7s8zdQ== X-ME-Helo: pop-os.home X-ME-Auth: Y2hyaXN0b3BoZS5qYWlsbGV0QHdhbmFkb28uZnI= X-ME-Date: Sat, 16 Sep 2023 08:20:29 +0200 X-ME-IP: 86.243.2.178 From: Christophe JAILLET <christophe.jaillet@wanadoo.fr> To: Kent Overstreet <kent.overstreet@linux.dev>, Brian Foster <bfoster@redhat.com> Cc: linux-kernel@vger.kernel.org, kernel-janitors@vger.kernel.org, Christophe JAILLET <christophe.jaillet@wanadoo.fr>, linux-bcachefs@vger.kernel.org Subject: [PATCH] bcachefs: Avoid a potential useless over memory allocation in bch2_prt_vprintf() Date: Sat, 16 Sep 2023 08:20:24 +0200 Message-Id: <0f40108bed3e084057223bdbe32c4b37f8500ff3.1694845203.git.christophe.jaillet@wanadoo.fr> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Fri, 15 Sep 2023 23:21:40 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1777174108267182426 X-GMAIL-MSGID: 1777174108267182426 |
Series |
bcachefs: Avoid a potential useless over memory allocation in bch2_prt_vprintf()
|
|
Commit Message
Christophe JAILLET
Sept. 16, 2023, 6:20 a.m. UTC
printbuf_remaining() returns the number of characters we can print to the
output buffer - i.e. excluding the terminating null.
vsnprintf() takes the size of the buffer, including the trailing null
space.
It is truncated if the returned value is greater than or equal to the size
of the buffer.
Knowing all that, buffer sizes and overflow checks can be fixed in order
to potentially avoid a useless memory over-allocation.
Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
Un-tested
---
fs/bcachefs/printbuf.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
Comments
On Sat, Sep 16, 2023 at 08:20:24AM +0200, Christophe JAILLET wrote: > printbuf_remaining() returns the number of characters we can print to the > output buffer - i.e. excluding the terminating null. > > vsnprintf() takes the size of the buffer, including the trailing null > space. > It is truncated if the returned value is greater than or equal to the size > of the buffer. > > Knowing all that, buffer sizes and overflow checks can be fixed in order > to potentially avoid a useless memory over-allocation. > For whatever reason I had a hard time parsing this last sentence. Do you mean to say there's an off by one here that leads to an unnecessary overallocation? > Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> > --- > Un-tested > --- > fs/bcachefs/printbuf.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > > diff --git a/fs/bcachefs/printbuf.c b/fs/bcachefs/printbuf.c > index de41f9a14492..77bee9060bfe 100644 > --- a/fs/bcachefs/printbuf.c > +++ b/fs/bcachefs/printbuf.c > @@ -54,8 +54,9 @@ void bch2_prt_vprintf(struct printbuf *out, const char *fmt, va_list args) > va_list args2; > > va_copy(args2, args); > - len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args2); > - } while (len + 1 >= printbuf_remaining(out) && > + len = vsnprintf(out->buf + out->pos, printbuf_remaining(out) + 1, > + fmt, args2); > + } while (len >= printbuf_remaining(out) + 1 && > !bch2_printbuf_make_room(out, len + 1)); It's amazing how simple arithmetic can make my eyes cross at times. :) I think I follow the fix after reading the commit log a couple times, but could we use printbuf_remaining_size() appropriately in these places that want to check actual buffer size (i.e. including terminating null) instead of doing the manual size fixup? Brian > > len = min_t(size_t, len, > @@ -70,9 +71,10 @@ void bch2_prt_printf(struct printbuf *out, const char *fmt, ...) > > do { > va_start(args, fmt); > - len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args); > + len = vsnprintf(out->buf + out->pos, printbuf_remaining(out) + 1, > + fmt, args); > va_end(args); > - } while (len + 1 >= printbuf_remaining(out) && > + } while (len >= printbuf_remaining(out) + 1 && > !bch2_printbuf_make_room(out, len + 1)); > > len = min_t(size_t, len, > -- > 2.34.1 >
Le 19/09/2023 à 15:17, Brian Foster a écrit : > On Sat, Sep 16, 2023 at 08:20:24AM +0200, Christophe JAILLET wrote: >> printbuf_remaining() returns the number of characters we can print to the >> output buffer - i.e. excluding the terminating null. >> >> vsnprintf() takes the size of the buffer, including the trailing null >> space. >> It is truncated if the returned value is greater than or equal to the size >> of the buffer. >> >> Knowing all that, buffer sizes and overflow checks can be fixed in order >> to potentially avoid a useless memory over-allocation. >> > > For whatever reason I had a hard time parsing this last sentence. Do > you mean to say there's an off by one here that leads to an unnecessary > overallocation? An off-by-two in fact, IIUC. But yes, that's my point. We consider that the string is truncated when it may not be (len+1 vs len) and we under-estimate the available space (printbuf_remaining() vs printbuf_remaining()+1 or printbuf_remaining_size()) > >> Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr> >> --- >> Un-tested >> --- >> fs/bcachefs/printbuf.c | 10 ++++++---- >> 1 file changed, 6 insertions(+), 4 deletions(-) >> >> diff --git a/fs/bcachefs/printbuf.c b/fs/bcachefs/printbuf.c >> index de41f9a14492..77bee9060bfe 100644 >> --- a/fs/bcachefs/printbuf.c >> +++ b/fs/bcachefs/printbuf.c >> @@ -54,8 +54,9 @@ void bch2_prt_vprintf(struct printbuf *out, const char *fmt, va_list args) >> va_list args2; >> >> va_copy(args2, args); >> - len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args2); >> - } while (len + 1 >= printbuf_remaining(out) && >> + len = vsnprintf(out->buf + out->pos, printbuf_remaining(out) + 1, >> + fmt, args2); >> + } while (len >= printbuf_remaining(out) + 1 && >> !bch2_printbuf_make_room(out, len + 1)); > > It's amazing how simple arithmetic can make my eyes cross at times. :) I > think I follow the fix after reading the commit log a couple times, but > could we use printbuf_remaining_size() appropriately in these places > that want to check actual buffer size (i.e. including terminating null) > instead of doing the manual size fixup? Sure, it would be much better. I had not seen this function. CJ > > Brian > >> >> len = min_t(size_t, len, >> @@ -70,9 +71,10 @@ void bch2_prt_printf(struct printbuf *out, const char *fmt, ...) >> >> do { >> va_start(args, fmt); >> - len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args); >> + len = vsnprintf(out->buf + out->pos, printbuf_remaining(out) + 1, >> + fmt, args); >> va_end(args); >> - } while (len + 1 >= printbuf_remaining(out) && >> + } while (len >= printbuf_remaining(out) + 1 && >> !bch2_printbuf_make_room(out, len + 1)); >> >> len = min_t(size_t, len, >> -- >> 2.34.1 >> > >
diff --git a/fs/bcachefs/printbuf.c b/fs/bcachefs/printbuf.c index de41f9a14492..77bee9060bfe 100644 --- a/fs/bcachefs/printbuf.c +++ b/fs/bcachefs/printbuf.c @@ -54,8 +54,9 @@ void bch2_prt_vprintf(struct printbuf *out, const char *fmt, va_list args) va_list args2; va_copy(args2, args); - len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args2); - } while (len + 1 >= printbuf_remaining(out) && + len = vsnprintf(out->buf + out->pos, printbuf_remaining(out) + 1, + fmt, args2); + } while (len >= printbuf_remaining(out) + 1 && !bch2_printbuf_make_room(out, len + 1)); len = min_t(size_t, len, @@ -70,9 +71,10 @@ void bch2_prt_printf(struct printbuf *out, const char *fmt, ...) do { va_start(args, fmt); - len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args); + len = vsnprintf(out->buf + out->pos, printbuf_remaining(out) + 1, + fmt, args); va_end(args); - } while (len + 1 >= printbuf_remaining(out) && + } while (len >= printbuf_remaining(out) + 1 && !bch2_printbuf_make_room(out, len + 1)); len = min_t(size_t, len,