From 0ed16548e408a2f7ebb7d1c522975f0eb9798eca Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Thu, 29 Feb 2024 11:25:24 +1100 Subject: [PATCH] pretty: initial concept for ZIO flags Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. --- include/Makefile.am | 1 + include/zfs_pretty.h | 47 ++++++++++++ lib/libzfs/Makefile.am | 1 + lib/libzpool/Makefile.am | 1 + module/Kbuild.in | 1 + module/Makefile.bsd | 1 + module/zcommon/zfs_pretty.c | 142 ++++++++++++++++++++++++++++++++++++ 7 files changed, 194 insertions(+) create mode 100644 include/zfs_pretty.h create mode 100644 module/zcommon/zfs_pretty.c diff --git a/include/Makefile.am b/include/Makefile.am index fa725c2e7a..da186adacc 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -13,6 +13,7 @@ COMMON_H = \ zfs_deleg.h \ zfs_fletcher.h \ zfs_namecheck.h \ + zfs_pretty.h \ zfs_prop.h \ \ sys/abd.h \ diff --git a/include/zfs_pretty.h b/include/zfs_pretty.h new file mode 100644 index 0000000000..084ce93e33 --- /dev/null +++ b/include/zfs_pretty.h @@ -0,0 +1,47 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2024, Klara Inc. + */ + +#ifndef _ZFS_PRETTY_H +#define _ZFS_PRETTY_H extern __attribute__((visibility("default"))) + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +_ZFS_PRETTY_H size_t zfs_pretty_zio_flag_bits( + uint64_t bits, char *out, size_t outlen); +_ZFS_PRETTY_H size_t zfs_pretty_zio_flag_pairs( + uint64_t bits, char *out, size_t outlen); +_ZFS_PRETTY_H size_t zfs_pretty_zio_flag_str( + uint64_t bits, char *out, size_t outlen); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZFS_PRETTY_H */ diff --git a/lib/libzfs/Makefile.am b/lib/libzfs/Makefile.am index 5e74d908de..88650e9617 100644 --- a/lib/libzfs/Makefile.am +++ b/lib/libzfs/Makefile.am @@ -46,6 +46,7 @@ nodist_libzfs_la_SOURCES = \ module/zcommon/zfs_fletcher_superscalar.c \ module/zcommon/zfs_fletcher_superscalar4.c \ module/zcommon/zfs_namecheck.c \ + module/zcommon/zfs_pretty.c \ module/zcommon/zfs_prop.c \ module/zcommon/zpool_prop.c \ module/zcommon/zprop_common.c diff --git a/lib/libzpool/Makefile.am b/lib/libzpool/Makefile.am index 42f3404db5..26f023faac 100644 --- a/lib/libzpool/Makefile.am +++ b/lib/libzpool/Makefile.am @@ -61,6 +61,7 @@ nodist_libzpool_la_SOURCES = \ module/zcommon/zfs_fletcher_superscalar.c \ module/zcommon/zfs_fletcher_superscalar4.c \ module/zcommon/zfs_namecheck.c \ + module/zcommon/zfs_pretty.c \ module/zcommon/zfs_prop.c \ module/zcommon/zpool_prop.c \ module/zcommon/zprop_common.c \ diff --git a/module/Kbuild.in b/module/Kbuild.in index 4f48cb9da0..ae6db52c79 100644 --- a/module/Kbuild.in +++ b/module/Kbuild.in @@ -239,6 +239,7 @@ ZCOMMON_OBJS := \ zfs_fletcher_superscalar.o \ zfs_fletcher_superscalar4.o \ zfs_namecheck.o \ + zfs_pretty.o \ zfs_prop.o \ zpool_prop.o \ zprop_common.o diff --git a/module/Makefile.bsd b/module/Makefile.bsd index d9d31564d0..9d04965a50 100644 --- a/module/Makefile.bsd +++ b/module/Makefile.bsd @@ -232,6 +232,7 @@ SRCS+= cityhash.c \ zfs_fletcher_superscalar4.c \ zfs_fletcher_superscalar.c \ zfs_namecheck.c \ + zfs_pretty.c \ zfs_prop.c \ zpool_prop.c \ zprop_common.c diff --git a/module/zcommon/zfs_pretty.c b/module/zcommon/zfs_pretty.c new file mode 100644 index 0000000000..98fb256478 --- /dev/null +++ b/module/zcommon/zfs_pretty.c @@ -0,0 +1,142 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or https://opensource.org/licenses/CDDL-1.0. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2024, Klara Inc. + */ + +#include +#include +#include +#include +#include "zfs_pretty.h" + +typedef struct { + const char pb_bit; + const char pb_pair[2]; + const char *pb_name; +} pretty_bit_t; + +static const pretty_bit_t pretty_zio_flag_table[] = { + { '.', "DA", "DONT_AGGREGATE" }, + { '.', "RP", "IO_REPAIR" }, + { '.', "SH", "SELF_HEAL" }, + { '.', "RS", "RESILVER" }, + { '.', "SC", "SCRUB" }, + { '.', "ST", "SCAN_THREAD" }, + { '.', "PH", "PHYSICAL" }, + { '.', "CF", "CANFAIL" }, + { '.', "SP", "SPECULATIVE" }, + { '.', "CW", "CONFIG_WRITER" }, + { '.', "DR", "DONT_RETRY" }, + { '.', "ND", "NODATA" }, + { '.', "ID", "INDUCE_DAMAGE" }, + { '.', "AL", "IO_ALLOCATING" }, + { '.', "RE", "IO_RETRY" }, + { '.', "PR", "PROBE" }, + { '.', "TH", "TRYHARD" }, + { '.', "OP", "OPTIONAL" }, + { '.', "DQ", "DONT_QUEUE" }, + { '.', "DP", "DONT_PROPAGATE" }, + { '.', "BY", "IO_BYPASS" }, + { '.', "RW", "IO_REWRITE" }, + { '.', "CM", "RAW_COMPRESS" }, + { '.', "EN", "RAW_ENCRYPT" }, + { '.', "GG", "GANG_CHILD" }, + { '.', "DD", "DDT_CHILD" }, + { '.', "GF", "GODFATHER" }, + { '.', "NP", "NOPWRITE" }, + { '.', "EX", "REEXECUTED" }, + { '.', "DG", "DELEGATED" }, +}; +static const size_t pretty_zio_flag_table_elems = + sizeof (pretty_zio_flag_table) / sizeof (pretty_bit_t); + +size_t +zfs_pretty_zio_flag_bits(uint64_t bits, char *out, size_t outlen) +{ + ASSERT(out); + size_t n = 0; + for (int b = pretty_zio_flag_table_elems; b >= 0; b--) { + if (n == outlen) + break; + uint64_t mask = (1ULL << b); + out[n++] = + (bits & mask) ? pretty_zio_flag_table[b].pb_bit : ' '; + } + if (n < outlen) + out[n++] = '\0'; + return (n); +} + +size_t +zfs_pretty_zio_flag_pairs(uint64_t bits, char *out, size_t outlen) +{ + ASSERT(out); + size_t n = 0; + for (int b = pretty_zio_flag_table_elems; b >= 0; b--) { + ASSERT3U(n, <=, outlen); + if (n == outlen) + break; + uint64_t mask = (1ULL << b); + if (bits & mask) { + size_t len = (n > 0) ? 3 : 2; + if (n > outlen-len) + break; + if (n > 0) + out[n++] = '|'; + out[n++] = pretty_zio_flag_table[b].pb_pair[0]; + out[n++] = pretty_zio_flag_table[b].pb_pair[1]; + } + } + if (n < outlen) + out[n++] = '\0'; + return (n); +} + +size_t +zfs_pretty_zio_flag_str(uint64_t bits, char *out, size_t outlen) +{ + ASSERT(out); + size_t n = 0; + for (int b = pretty_zio_flag_table_elems; b >= 0; b--) { + ASSERT3U(n, <=, outlen); + if (n == outlen) + break; + uint64_t mask = (1ULL << b); + if (bits & mask) { + size_t len = strlen(pretty_zio_flag_table[b].pb_name); + if (n > 0) + len++; + if (n > outlen-len) + break; + if (n > 0) { + out[n++] = ' '; + len--; + } + memcpy(&out[n], pretty_zio_flag_table[b].pb_name, len); + n += len; + } + } + if (n < outlen) + out[n++] = '\0'; + return (n); +}