diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2022-02-22 04:53:48 -0500 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:09:24 -0400 |
commit | 702a4ef07774fbc565f3e567073d2f83f9602667 (patch) | |
tree | 2a3075cca3b847265a4c5d345b40e53cf9f684e8 | |
parent | f61816d0fc6091e14b3f4ffce962dc5084a1b6cd (diff) | |
download | linux-stable-702a4ef07774fbc565f3e567073d2f83f9602667.tar.gz linux-stable-702a4ef07774fbc565f3e567073d2f83f9602667.tar.bz2 linux-stable-702a4ef07774fbc565f3e567073d2f83f9602667.zip |
bcachefs: Add tabstops to printbufs
Now, when outputting to printbufs, we can set tabstops and left or right
justify text to them - this is to be used by the userspace 'bcachefs fs
usage' command.
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
-rw-r--r-- | fs/bcachefs/super-io.c | 12 | ||||
-rw-r--r-- | fs/bcachefs/util.c | 8 | ||||
-rw-r--r-- | fs/bcachefs/util.h | 84 |
3 files changed, 84 insertions, 20 deletions
diff --git a/fs/bcachefs/super-io.c b/fs/bcachefs/super-io.c index e1ff14eedaea..f95c9d754530 100644 --- a/fs/bcachefs/super-io.c +++ b/fs/bcachefs/super-io.c @@ -1061,7 +1061,7 @@ static void bch2_sb_members_to_text(struct printbuf *out, struct bch_sb *sb, pr_buf(out, "Device: %u", i); pr_newline(out); - printbuf_indent_push(out, 2); + pr_indent_push(out, 2); pr_buf(out, "UUID: "); pr_uuid(out, m->uuid.b); @@ -1129,7 +1129,7 @@ static void bch2_sb_members_to_text(struct printbuf *out, struct bch_sb *sb, BCH_MEMBER_DISCARD(m)); pr_newline(out); - printbuf_indent_pop(out, 2); + pr_indent_pop(out, 2); } } @@ -1471,9 +1471,9 @@ void bch2_sb_field_to_text(struct printbuf *out, struct bch_sb *sb, pr_newline(out); if (ops && ops->to_text) { - printbuf_indent_push(out, 2); + pr_indent_push(out, 2); bch2_sb_field_ops[type]->to_text(out, sb, f); - printbuf_indent_pop(out, 2); + pr_indent_pop(out, 2); } } @@ -1656,9 +1656,9 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb, pr_newline(out); pr_buf(out, "layout:"); pr_newline(out); - printbuf_indent_push(out, 2); + pr_indent_push(out, 2); bch2_sb_layout_to_text(out, &sb->layout); - printbuf_indent_pop(out, 2); + pr_indent_pop(out, 2); } vstruct_for_each(sb, f) diff --git a/fs/bcachefs/util.c b/fs/bcachefs/util.c index f170cf9d5052..a330fa30cd79 100644 --- a/fs/bcachefs/util.c +++ b/fs/bcachefs/util.c @@ -117,17 +117,11 @@ void bch2_hprint(struct printbuf *buf, s64 v) if (u && t && v < 100 && v > -100) pr_buf(buf, ".%i", t / 103); if (u) - pr_buf(buf, "%c", si_units[u]); + pr_char(buf, si_units[u]); } void bch2_pr_units(struct printbuf *out, s64 raw, s64 bytes) { - if (raw < 0) { - pr_buf(out, "-"); - raw = -raw; - bytes = -bytes; - } - switch (out->units) { case PRINTBUF_UNITS_RAW: pr_buf(out, "%llu", raw); diff --git a/fs/bcachefs/util.h b/fs/bcachefs/util.h index 3d5a9e04b3ad..426c3009f292 100644 --- a/fs/bcachefs/util.h +++ b/fs/bcachefs/util.h @@ -244,8 +244,12 @@ enum printbuf_units { struct printbuf { char *pos; char *end; + char *last_newline; + char *last_field; unsigned indent; enum printbuf_units units; + unsigned tabstop; + unsigned tabstops[4]; }; static inline size_t printbuf_remaining(struct printbuf *buf) @@ -253,29 +257,49 @@ static inline size_t printbuf_remaining(struct printbuf *buf) return buf->end - buf->pos; } +static inline size_t printbuf_linelen(struct printbuf *buf) +{ + return buf->pos - buf->last_newline; +} + #define _PBUF(_buf, _len) \ ((struct printbuf) { \ - .pos = _buf, \ - .end = _buf + _len, \ + .pos = _buf, \ + .end = _buf + _len, \ + .last_newline = _buf, \ + .last_field = _buf, \ }) #define PBUF(_buf) _PBUF(_buf, sizeof(_buf)) + #define pr_buf(_out, ...) \ do { \ (_out)->pos += scnprintf((_out)->pos, printbuf_remaining(_out), \ __VA_ARGS__); \ } while (0) -static inline void printbuf_indent_push(struct printbuf *buf, unsigned spaces) +static inline void pr_char(struct printbuf *out, char c) +{ + if (printbuf_remaining(out) > 1) { + *out->pos = c; + out->pos++; + } +} + +static inline void pr_indent_push(struct printbuf *buf, unsigned spaces) { buf->indent += spaces; while (spaces--) - pr_buf(buf, " "); + pr_char(buf, ' '); } -static inline void printbuf_indent_pop(struct printbuf *buf, unsigned spaces) +static inline void pr_indent_pop(struct printbuf *buf, unsigned spaces) { + if (buf->last_newline + buf->indent == buf->pos) { + buf->pos -= spaces; + buf->pos = '\0'; + } buf->indent -= spaces; } @@ -283,14 +307,60 @@ static inline void pr_newline(struct printbuf *buf) { unsigned i; - pr_buf(buf, "\n"); + pr_char(buf, '\n'); + + buf->last_newline = buf->pos; + for (i = 0; i < buf->indent; i++) - pr_buf(buf, " "); + pr_char(buf, ' '); + + buf->last_field = buf->pos; + buf->tabstop = 0; +} + +static inline void pr_tab(struct printbuf *buf) +{ + BUG_ON(buf->tabstop > ARRAY_SIZE(buf->tabstops)); + + while (printbuf_remaining(buf) > 1 && + printbuf_linelen(buf) < buf->tabstops[buf->tabstop]) + pr_char(buf, ' '); + + buf->last_field = buf->pos; + buf->tabstop++; +} + +static inline void pr_tab_rjust(struct printbuf *buf) +{ + ssize_t shift = min_t(ssize_t, buf->tabstops[buf->tabstop] - + printbuf_linelen(buf), + printbuf_remaining(buf)); + ssize_t move = min_t(ssize_t, buf->pos - buf->last_field, + printbuf_remaining(buf) - shift); + + BUG_ON(buf->tabstop > ARRAY_SIZE(buf->tabstops)); + + if (shift > 0) { + memmove(buf->last_field + shift, + buf->last_field, + move); + memset(buf->last_field, ' ', shift); + buf->pos += shift; + *buf->pos = 0; + } + + buf->last_field = buf->pos; + buf->tabstop++; } void bch2_pr_units(struct printbuf *, s64, s64); #define pr_units(...) bch2_pr_units(__VA_ARGS__) +static inline void pr_sectors(struct printbuf *out, u64 v) +{ + bch2_pr_units(out, v, v << 9); +} + #ifdef __KERNEL__ static inline void pr_time(struct printbuf *out, u64 time) { |