summaryrefslogtreecommitdiff
path: root/fs/bcachefs/util.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2022-02-25 13:18:19 -0500
committerKent Overstreet <kent.overstreet@gmail.com>2022-04-17 15:44:23 -0400
commit1feff790c77067d6d1fb451ee8727ea4d8232181 (patch)
treec815528a74b312b4b3443da1211d698d0a4bcd1a /fs/bcachefs/util.c
parentb0620a56dba8cd8c6f410276cac73eead11cb36a (diff)
bcachefs: Heap allocate printbufs
This patch changes printbufs dynamically allocate and reallocate a buffer as needed. Stack usage has become a bit of a problem, and a major cause of that has been static size string buffers on the stack. The most involved part of this refactoring is that printbufs must now be exited with printbuf_exit(). Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/util.c')
-rw-r--r--fs/bcachefs/util.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/fs/bcachefs/util.c b/fs/bcachefs/util.c
index e1b55fe844d6..766d08aede71 100644
--- a/fs/bcachefs/util.c
+++ b/fs/bcachefs/util.c
@@ -99,6 +99,38 @@ STRTO_H(strtoll, long long)
STRTO_H(strtoull, unsigned long long)
STRTO_H(strtou64, u64)
+static int bch2_printbuf_realloc(struct printbuf *out, unsigned extra)
+{
+ unsigned new_size = roundup_pow_of_two(out->size + extra);
+ char *buf = krealloc(out->buf, new_size, !out->atomic ? GFP_KERNEL : GFP_ATOMIC);
+
+ if (!buf) {
+ out->allocation_failure = true;
+ return -ENOMEM;
+ }
+
+ out->buf = buf;
+ out->size = new_size;
+ return 0;
+}
+
+void bch2_pr_buf(struct printbuf *out, const char *fmt, ...)
+{
+ va_list args;
+ int len;
+
+ do {
+ va_start(args, fmt);
+ len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args);
+ va_end(args);
+ } while (len + 1 >= printbuf_remaining(out) &&
+ !bch2_printbuf_realloc(out, len + 1));
+
+ len = min_t(size_t, len,
+ printbuf_remaining(out) ? printbuf_remaining(out) - 1 : 0);
+ out->pos += len;
+}
+
void bch2_hprint(struct printbuf *buf, s64 v)
{
int u, t = 0;
@@ -151,9 +183,6 @@ void bch2_flags_to_text(struct printbuf *out,
unsigned bit, nr = 0;
bool first = true;
- if (out->pos != out->end)
- *out->pos = '\0';
-
while (list[nr])
nr++;