Re: [PATCH v1 1/2] vsprintf: introduce %dE for error constants

From: Andy Shevchenko
Date: Thu Aug 29 2019 - 09:28:03 EST


On Sun, Aug 25, 2019 at 2:40 AM Uwe Kleine-KÃnig <uwe@xxxxxxxxxxxxxxxxx> wrote:
>
> pr_info("probing failed (%dE)\n", ret);
>
> expands to
>
> probing failed (EIO)
>
> if ret holds -EIO (or EIO). This introduces an array of error codes. If
> the error code is missing, %dE falls back to %d and so prints the plain
> number.
>
> Signed-off-by: Uwe Kleine-KÃnig <uwe@xxxxxxxxxxxxxxxxx>
> ---
> Hello
>
> there are many code sites that benefit from this. Just grep for
> "(%d)" ...
>
> As an example the follow up patch converts a printk to use this new
> format escape.
>

Let's not do this!

We have already a lot of pain with pointer extension, but here is just
a misleading stuff.
Besides above, how you print (float) number out of kernel in sysfs in
very well standard format?
Please, use %p<SMTH> instead.

> Best regards
> Uwe
>
> Documentation/core-api/printk-formats.rst | 3 +
> lib/vsprintf.c | 193 +++++++++++++++++++++-
> 2 files changed, 195 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst
> index c6224d039bcb..81002414f956 100644
> --- a/Documentation/core-api/printk-formats.rst
> +++ b/Documentation/core-api/printk-formats.rst
> @@ -35,6 +35,9 @@ Integer types
> u64 %llu or %llx
>
>
> +To print the name that corresponds to an integer error constant, use %dE and
> +pass the int.
> +
> If <type> is dependent on a config option for its size (e.g., sector_t,
> blkcnt_t) or is architecture-dependent for its size (e.g., tcflag_t), use a
> format specifier of its largest possible type and explicitly cast to it.
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index b0967cf17137..672eab8dab84 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -533,6 +533,192 @@ char *number(char *buf, char *end, unsigned long long num,
> return buf;
> }
>
> +#define ERRORCODE(x) { .str = #x, .err = x }
> +
> +static const struct {
> + const char *str;
> + int err;
> +} errorcodes[] = {
> + ERRORCODE(EPERM),
> + ERRORCODE(ENOENT),
> + ERRORCODE(ESRCH),
> + ERRORCODE(EINTR),
> + ERRORCODE(EIO),
> + ERRORCODE(ENXIO),
> + ERRORCODE(E2BIG),
> + ERRORCODE(ENOEXEC),
> + ERRORCODE(EBADF),
> + ERRORCODE(ECHILD),
> + ERRORCODE(EAGAIN),
> + ERRORCODE(ENOMEM),
> + ERRORCODE(EACCES),
> + ERRORCODE(EFAULT),
> + ERRORCODE(ENOTBLK),
> + ERRORCODE(EBUSY),
> + ERRORCODE(EEXIST),
> + ERRORCODE(EXDEV),
> + ERRORCODE(ENODEV),
> + ERRORCODE(ENOTDIR),
> + ERRORCODE(EISDIR),
> + ERRORCODE(EINVAL),
> + ERRORCODE(ENFILE),
> + ERRORCODE(EMFILE),
> + ERRORCODE(ENOTTY),
> + ERRORCODE(ETXTBSY),
> + ERRORCODE(EFBIG),
> + ERRORCODE(ENOSPC),
> + ERRORCODE(ESPIPE),
> + ERRORCODE(EROFS),
> + ERRORCODE(EMLINK),
> + ERRORCODE(EPIPE),
> + ERRORCODE(EDOM),
> + ERRORCODE(ERANGE),
> + ERRORCODE(EDEADLK),
> + ERRORCODE(ENAMETOOLONG),
> + ERRORCODE(ENOLCK),
> + ERRORCODE(ENOSYS),
> + ERRORCODE(ENOTEMPTY),
> + ERRORCODE(ELOOP),
> + ERRORCODE(EWOULDBLOCK),
> + ERRORCODE(ENOMSG),
> + ERRORCODE(EIDRM),
> + ERRORCODE(ECHRNG),
> + ERRORCODE(EL2NSYNC),
> + ERRORCODE(EL3HLT),
> + ERRORCODE(EL3RST),
> + ERRORCODE(ELNRNG),
> + ERRORCODE(EUNATCH),
> + ERRORCODE(ENOCSI),
> + ERRORCODE(EL2HLT),
> + ERRORCODE(EBADE),
> + ERRORCODE(EBADR),
> + ERRORCODE(EXFULL),
> + ERRORCODE(ENOANO),
> + ERRORCODE(EBADRQC),
> + ERRORCODE(EBADSLT),
> + ERRORCODE(EBFONT),
> + ERRORCODE(ENOSTR),
> + ERRORCODE(ENODATA),
> + ERRORCODE(ETIME),
> + ERRORCODE(ENOSR),
> + ERRORCODE(ENONET),
> + ERRORCODE(ENOPKG),
> + ERRORCODE(EREMOTE),
> + ERRORCODE(ENOLINK),
> + ERRORCODE(EADV),
> + ERRORCODE(ESRMNT),
> + ERRORCODE(ECOMM),
> + ERRORCODE(EPROTO),
> + ERRORCODE(EMULTIHOP),
> + ERRORCODE(EDOTDOT),
> + ERRORCODE(EBADMSG),
> + ERRORCODE(EOVERFLOW),
> + ERRORCODE(ENOTUNIQ),
> + ERRORCODE(EBADFD),
> + ERRORCODE(EREMCHG),
> + ERRORCODE(ELIBACC),
> + ERRORCODE(ELIBBAD),
> + ERRORCODE(ELIBSCN),
> + ERRORCODE(ELIBMAX),
> + ERRORCODE(ELIBEXEC),
> + ERRORCODE(EILSEQ),
> + ERRORCODE(ERESTART),
> + ERRORCODE(ESTRPIPE),
> + ERRORCODE(EUSERS),
> + ERRORCODE(ENOTSOCK),
> + ERRORCODE(EDESTADDRREQ),
> + ERRORCODE(EMSGSIZE),
> + ERRORCODE(EPROTOTYPE),
> + ERRORCODE(ENOPROTOOPT),
> + ERRORCODE(EPROTONOSUPPORT),
> + ERRORCODE(ESOCKTNOSUPPORT),
> + ERRORCODE(EOPNOTSUPP),
> + ERRORCODE(EPFNOSUPPORT),
> + ERRORCODE(EAFNOSUPPORT),
> + ERRORCODE(EADDRINUSE),
> + ERRORCODE(EADDRNOTAVAIL),
> + ERRORCODE(ENETDOWN),
> + ERRORCODE(ENETUNREACH),
> + ERRORCODE(ENETRESET),
> + ERRORCODE(ECONNABORTED),
> + ERRORCODE(ECONNRESET),
> + ERRORCODE(ENOBUFS),
> + ERRORCODE(EISCONN),
> + ERRORCODE(ENOTCONN),
> + ERRORCODE(ESHUTDOWN),
> + ERRORCODE(ETOOMANYREFS),
> + ERRORCODE(ETIMEDOUT),
> + ERRORCODE(ECONNREFUSED),
> + ERRORCODE(EHOSTDOWN),
> + ERRORCODE(EHOSTUNREACH),
> + ERRORCODE(EALREADY),
> + ERRORCODE(EINPROGRESS),
> + ERRORCODE(ESTALE),
> + ERRORCODE(EUCLEAN),
> + ERRORCODE(ENOTNAM),
> + ERRORCODE(ENAVAIL),
> + ERRORCODE(EISNAM),
> + ERRORCODE(EREMOTEIO),
> + ERRORCODE(EDQUOT),
> + ERRORCODE(ENOMEDIUM),
> + ERRORCODE(EMEDIUMTYPE),
> + ERRORCODE(ECANCELED),
> + ERRORCODE(ENOKEY),
> + ERRORCODE(EKEYEXPIRED),
> + ERRORCODE(EKEYREVOKED),
> + ERRORCODE(EKEYREJECTED),
> + ERRORCODE(EOWNERDEAD),
> + ERRORCODE(ENOTRECOVERABLE),
> + ERRORCODE(ERFKILL),
> + ERRORCODE(EHWPOISON),
> + ERRORCODE(ERESTARTSYS),
> + ERRORCODE(ERESTARTNOINTR),
> + ERRORCODE(ERESTARTNOHAND),
> + ERRORCODE(ENOIOCTLCMD),
> + ERRORCODE(ERESTART_RESTARTBLOCK),
> + ERRORCODE(EPROBE_DEFER),
> + ERRORCODE(EOPENSTALE),
> + ERRORCODE(ENOPARAM),
> + ERRORCODE(EBADHANDLE),
> + ERRORCODE(ENOTSYNC),
> + ERRORCODE(EBADCOOKIE),
> + ERRORCODE(ENOTSUPP),
> + ERRORCODE(ETOOSMALL),
> + ERRORCODE(ESERVERFAULT),
> + ERRORCODE(EBADTYPE),
> + ERRORCODE(EJUKEBOX),
> + ERRORCODE(EIOCBQUEUED),
> + ERRORCODE(ERECALLCONFLICT),
> +};
> +
> +static noinline_for_stack
> +char *errstr(char *buf, char *end, unsigned long long num,
> + struct printf_spec spec)
> +{
> + char *errname = NULL;
> + size_t errnamelen, copy;
> + int i;
> +
> + for (i = 0; i < ARRAY_SIZE(errorcodes); ++i) {
> + if (num == errorcodes[i].err || num == -errorcodes[i].err) {
> + errname = errorcodes[i].str;
> + break;
> + }
> + }
> +
> + if (!errname) {
> + /* fall back to ordinary number */
> + return number(buf, end, num, spec);
> + }
> +
> + copy = errnamelen = strlen(errname);
> + if (copy > end - buf)
> + copy = end - buf;
> + buf = memcpy(buf, errname, copy);
> +
> + return buf + errnamelen;
> +}
> +
> static noinline_for_stack
> char *special_hex_number(char *buf, char *end, unsigned long long num, int size)
> {
> @@ -2566,7 +2752,12 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
> num = va_arg(args, unsigned int);
> }
>
> - str = number(str, end, num, spec);
> + if (spec.type == FORMAT_TYPE_INT && *fmt == 'E') {
> + fmt++;
> + str = errstr(str, end, num, spec);
> + } else {
> + str = number(str, end, num, spec);
> + }
> }
> }
>
> --
> 2.20.1
>


--
With Best Regards,
Andy Shevchenko