From patchwork Mon Jun 20 00:42:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Overstreet X-Patchwork-Id: 12886892 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 A8675C433EF for ; Mon, 20 Jun 2022 00:42:39 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 206186B0073; Sun, 19 Jun 2022 20:42:39 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 18F9D6B0074; Sun, 19 Jun 2022 20:42:39 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id DC2F06B0075; Sun, 19 Jun 2022 20:42:38 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id C48726B0073 for ; Sun, 19 Jun 2022 20:42:38 -0400 (EDT) Received: from smtpin12.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 984A6244 for ; Mon, 20 Jun 2022 00:42:38 +0000 (UTC) X-FDA: 79596763596.12.D9C5BD3 Received: from mail-qk1-f173.google.com (mail-qk1-f173.google.com [209.85.222.173]) by imf29.hostedemail.com (Postfix) with ESMTP id 421FD120099 for ; Mon, 20 Jun 2022 00:42:38 +0000 (UTC) Received: by mail-qk1-f173.google.com with SMTP id p63so6868872qkd.10 for ; Sun, 19 Jun 2022 17:42:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3/nEaXcS+ZC6RKiVGkArvgF330nGs3znieMvRlKYBkE=; b=e40j//a0UpC8Y8sCD9pIwNHhYdrQIhc2TpikKiZ4J2M58W6FdUALdIMrL/eslykTBx 0nzlTt1rhftLuh0tiigwJVcXj9ODls1SlagoERnk2I9tk/8unLDu7c2cU7Xxtr2IRpom klekBzuOmbd+q2rtwDd1SS8iaPcXODF29ntc55eCRzRe0VDpqhOi6ClSPHanNkFJyDSV mk93zt+iji375miaTDKZXzPcuL4pNBZc0w1Mg8iqI/ssFgqHzCYzI09aFyg0mzVymSJF xrJ5GNt0sYGfdk6Tmbp5lnQ0xw27LP7efZPkEnox3epsAjRgZJYynUgbFAnVjQDfhWLC xmyg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3/nEaXcS+ZC6RKiVGkArvgF330nGs3znieMvRlKYBkE=; b=anCuEmXiEq5jHh9lcIQetozRF3rvuBRJ8tonhTZnN94+XJ5CSfR/RWQblMFP7JXRKb IiQjmWPha1tKpK8/VUM7ObXsIJXL6NwWKII47RpX7EOZthwDbvU4HSfjHzChQkxRpp9f 2mSqAmxJbuqlg0tEgG3LeXQG9Kl3FRoiUddfmHMnljVw66RyRmuEAmMNl+/1dgml34Wy /JX5wPPo5zXDTpqvqPdEabVoux21dUWbfftzScGlIuUHUo2lRaH4ckXIB/qYI+RGAIP6 cU6I+fVOrmzXp+q/JbFRnYhCxm7NUeeNweuEni9pqMX+iEmH2z+zqzIM+7jqgGZk4jhX Lx8A== X-Gm-Message-State: AJIora/3TyH4ldPfKWvoszyvc736Tfjez4tcWuhIR7EUhOlvg3myxNPF uCNi8NQ3lWJjL5LXJxMI6w== X-Google-Smtp-Source: AGRyM1uNJejkIsePjPRiQmFzrgITMNPqpuy+TziXRtN0JNv8oawGRUrDCakDVv7mXhqbhNFu7mXR4g== X-Received: by 2002:a05:620a:4403:b0:6a6:d0ee:8b22 with SMTP id v3-20020a05620a440300b006a6d0ee8b22mr14672050qkp.144.1655685757374; Sun, 19 Jun 2022 17:42:37 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id u11-20020a05622a17cb00b00304bbcc1b8asm9451375qtk.28.2022.06.19.17.42.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:36 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 01/34] lib/printbuf: New data structure for printing strings Date: Sun, 19 Jun 2022 20:42:00 -0400 Message-Id: <20220620004233.3805-2-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-1-kent.overstreet@gmail.com> MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1655685758; 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:in-reply-to:references:references:dkim-signature; bh=3/nEaXcS+ZC6RKiVGkArvgF330nGs3znieMvRlKYBkE=; b=J68yOFGG6Obu0CnkVxtD5hipXxLlgeOO+AalO3f8gtf2StklNZMUpvJcgflX47vdxaHfKb XUO0TrZ74ex4ulagci42JnoBvUz5k1a4CykydDHu8JeNkL5KUOvnsbDqU1QfBlKAqT+WSh sfXLl5NDTyv2rqPbKsMC1VpyE4uwM6Q= ARC-Authentication-Results: i=1; imf29.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b="e40j//a0"; spf=pass (imf29.hostedemail.com: domain of kent.overstreet@gmail.com designates 209.85.222.173 as permitted sender) smtp.mailfrom=kent.overstreet@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1655685758; a=rsa-sha256; cv=none; b=nnO83riwEa257SxmFWLNF/mKkEOik/7LCGRAIJm3b9M8V5HObG4FtAoaC8knx020xjwi6w NXUxqkplLSLTqoqRtXQ0+FbaqhaTOf9YcJBt+BN2B/0y1O0Hinds6RHBGOvZizvOJEsdSR FrThkjL86u0pP/liPVFLoRbfqlNrZxY= X-Stat-Signature: nw6sudjbyebaam6yndm6qbd73u6erf58 X-Rspamd-Queue-Id: 421FD120099 X-Rspamd-Server: rspam11 X-Rspam-User: Authentication-Results: imf29.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b="e40j//a0"; spf=pass (imf29.hostedemail.com: domain of kent.overstreet@gmail.com designates 209.85.222.173 as permitted sender) smtp.mailfrom=kent.overstreet@gmail.com; dmarc=pass (policy=none) header.from=gmail.com X-HE-Tag: 1655685758-41763 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: This adds printbufs: a printbuf points to a char * buffer and knows the size of the output buffer as well as the current output position. Future patches will be adding more features to printbuf, but initially printbufs are targeted at refactoring and improving our existing code in lib/vsprintf.c - so this initial printbuf patch has the features required for that. Signed-off-by: Kent Overstreet Reviewed-by: Matthew Wilcox (Oracle) --- include/linux/printbuf.h | 122 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 include/linux/printbuf.h diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h new file mode 100644 index 0000000000..8186c447ca --- /dev/null +++ b/include/linux/printbuf.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* Copyright (C) 2022 Kent Overstreet */ + +#ifndef _LINUX_PRINTBUF_H +#define _LINUX_PRINTBUF_H + +#include +#include + +/* + * Printbufs: String buffer for outputting (printing) to, for vsnprintf + */ + +struct printbuf { + char *buf; + unsigned size; + unsigned pos; +}; + +/* + * Returns size remaining of output buffer: + */ +static inline unsigned printbuf_remaining_size(struct printbuf *out) +{ + return out->pos < out->size ? out->size - out->pos : 0; +} + +/* + * Returns number of characters we can print to the output buffer - i.e. + * excluding the terminating nul: + */ +static inline unsigned printbuf_remaining(struct printbuf *out) +{ + return out->pos < out->size ? out->size - out->pos - 1 : 0; +} + +static inline unsigned printbuf_written(struct printbuf *out) +{ + return min(out->pos, out->size); +} + +/* + * Returns true if output was truncated: + */ +static inline bool printbuf_overflowed(struct printbuf *out) +{ + return out->pos >= out->size; +} + +static inline void printbuf_nul_terminate(struct printbuf *out) +{ + if (out->pos < out->size) + out->buf[out->pos] = 0; + else if (out->size) + out->buf[out->size - 1] = 0; +} + +static inline void __prt_char(struct printbuf *out, char c) +{ + if (printbuf_remaining(out)) + out->buf[out->pos] = c; + out->pos++; +} + +static inline void prt_char(struct printbuf *out, char c) +{ + __prt_char(out, c); + printbuf_nul_terminate(out); +} + +static inline void __prt_chars(struct printbuf *out, char c, unsigned n) +{ + unsigned i, can_print = min(n, printbuf_remaining(out)); + + for (i = 0; i < can_print; i++) + out->buf[out->pos++] = c; + out->pos += n - can_print; +} + +static inline void prt_chars(struct printbuf *out, char c, unsigned n) +{ + __prt_chars(out, c, n); + printbuf_nul_terminate(out); +} + +static inline void prt_bytes(struct printbuf *out, const void *b, unsigned n) +{ + unsigned i, can_print = min(n, printbuf_remaining(out)); + + for (i = 0; i < can_print; i++) + out->buf[out->pos++] = ((char *) b)[i]; + out->pos += n - can_print; + + printbuf_nul_terminate(out); +} + +static inline void prt_str(struct printbuf *out, const char *str) +{ + prt_bytes(out, str, strlen(str)); +} + +static inline void prt_hex_byte(struct printbuf *out, u8 byte) +{ + __prt_char(out, hex_asc_hi(byte)); + __prt_char(out, hex_asc_lo(byte)); + printbuf_nul_terminate(out); +} + +static inline void prt_hex_byte_upper(struct printbuf *out, u8 byte) +{ + __prt_char(out, hex_asc_upper_hi(byte)); + __prt_char(out, hex_asc_upper_lo(byte)); + printbuf_nul_terminate(out); +} + +#define PRINTBUF_EXTERN(_buf, _size) \ +((struct printbuf) { \ + .buf = _buf, \ + .size = _size, \ +}) + +#endif /* _LINUX_PRINTBUF_H */