mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/kdave/btrfs-progs.git
synced 2024-11-15 00:04:23 +08:00
btrfs-progs: add musl compatibility for printf format %pV
Glibc provides an interface to extend the printf formats but this is not standardized and does not work on musl. The code brought from kernel uses %pV for varargs and also has own implementation of printk. As a workaround for musl expand the pV value to a string and then simply print it. The details are hidden behind macros: - DECLARE_PV(vaf) - PV_ASSIGN(vaf, format, args) - PV_FMT in printf string - PV_VAL in arguments Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
762dbd6d70
commit
164bc10dfc
@ -16,7 +16,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <printf.h>
|
||||
#include "common/messages.h"
|
||||
#include "common/utils.h"
|
||||
|
||||
@ -26,8 +25,6 @@ static const char *common_error_string[] = {
|
||||
[ERROR_MSG_COMMIT_TRANS] = "failed to commit transaction",
|
||||
};
|
||||
|
||||
static int va_modifier = -1;
|
||||
|
||||
__attribute__ ((format (printf, 1, 2)))
|
||||
void __btrfs_printf(const char *fmt, ...)
|
||||
{
|
||||
@ -38,6 +35,10 @@ void __btrfs_printf(const char *fmt, ...)
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#ifndef PV_WORKAROUND
|
||||
|
||||
static int va_modifier = -1;
|
||||
|
||||
static int print_va_format(FILE *stream, const struct printf_info *info,
|
||||
const void *const *args)
|
||||
{
|
||||
@ -58,18 +59,21 @@ static int print_va_format_arginfo(const struct printf_info *info,
|
||||
size[0] = sizeof(struct va_format *);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
void btrfs_no_printk(const void *fs_info, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
#ifndef PV_WORKAROUND
|
||||
if (va_modifier == -1) {
|
||||
register_printf_specifier('V', print_va_format,
|
||||
print_va_format_arginfo);
|
||||
va_modifier = register_printf_modifier(L"p");
|
||||
}
|
||||
#endif
|
||||
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
|
@ -22,6 +22,23 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* Workaround for custom format %pV that may not be supported on all libcs.
|
||||
*/
|
||||
#ifdef HAVE_PRINTF_H
|
||||
#define DECLARE_PV(name) struct va_format name
|
||||
#define PV_FMT "%pV"
|
||||
#define PV_VAL(va) &va
|
||||
#define PV_ASSIGN(_va, _fmt, _args) ({ _va.fmt = (_fmt); _va.va = &(_args); })
|
||||
#include <printf.h>
|
||||
#else
|
||||
#define PV_WORKAROUND
|
||||
#define DECLARE_PV(name) char name[1024]
|
||||
#define PV_FMT "%s"
|
||||
#define PV_VAL(va) va
|
||||
#define PV_ASSIGN(_va, _fmt, _args) vsnprintf(_va, 1024, _fmt, _args)
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_VERBOSE_ERROR
|
||||
#define PRINT_VERBOSE_ERROR fprintf(stderr, "%s:%d:", __FILE__, __LINE__)
|
||||
#else
|
||||
|
@ -85,6 +85,7 @@ AX_GCC_BUILTIN([__builtin_mul_overflow])
|
||||
AC_CHECK_HEADERS([linux/perf_event.h])
|
||||
AC_CHECK_HEADERS([linux/hw_breakpoint.h])
|
||||
AC_CHECK_HEADERS([linux/fsverity.h])
|
||||
AC_CHECK_HEADERS([printf.h])
|
||||
|
||||
if grep -q 'HAVE_LINUX_FSVERITY_H.*1' confdefs.h; then
|
||||
have_fsverity='yes'
|
||||
|
@ -134,15 +134,14 @@ void __btrfs_handle_fs_error(struct btrfs_fs_info *fs_info, const char *function
|
||||
errstr = btrfs_decode_error(error);
|
||||
btrfs_state_to_string(fs_info, statestr);
|
||||
if (fmt) {
|
||||
struct va_format vaf;
|
||||
DECLARE_PV(vaf);
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
PV_ASSIGN(vaf, fmt, args);
|
||||
|
||||
pr_crit("BTRFS: error (device %s%s) in %s:%d: error=%d %s (%pV)\n",
|
||||
sb->s_id, statestr, function, line, error, errstr, &vaf);
|
||||
pr_crit("BTRFS: error (device %s%s) in %s:%d: error=%d %s (" PV_FMT ")\n",
|
||||
sb->s_id, statestr, function, line, error, errstr, PV_VAL(vaf));
|
||||
va_end(args);
|
||||
} else {
|
||||
pr_crit("BTRFS: error (device %s%s) in %s:%d: error=%d %s\n",
|
||||
@ -215,7 +214,7 @@ static struct ratelimit_state printk_limits[] = {
|
||||
void __cold _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
|
||||
{
|
||||
char lvl[PRINTK_MAX_SINGLE_HEADER_LEN + 1] = "\0";
|
||||
struct va_format vaf;
|
||||
DECLARE_PV(vaf);
|
||||
va_list args;
|
||||
int kern_level;
|
||||
const char *type = logtypes[4];
|
||||
@ -239,18 +238,17 @@ void __cold _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt,
|
||||
fmt += size;
|
||||
}
|
||||
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
PV_ASSIGN(vaf, fmt, args);
|
||||
|
||||
if (__ratelimit(ratelimit)) {
|
||||
if (fs_info) {
|
||||
char statestr[STATE_STRING_BUF_LEN];
|
||||
|
||||
btrfs_state_to_string(fs_info, statestr);
|
||||
_printk("%sBTRFS %s (device %s%s): %pV\n", lvl, type,
|
||||
fs_info->sb->s_id, statestr, &vaf);
|
||||
_printk("%sBTRFS %s (device %s%s): " PV_FMT "\n", lvl, type,
|
||||
fs_info->sb->s_id, statestr, PV_VAL(vaf));
|
||||
} else {
|
||||
_printk("%sBTRFS %s: %pV\n", lvl, type, &vaf);
|
||||
_printk("%sBTRFS %s: " PV_FMT "\n", lvl, type, PV_VAL(vaf));
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,7 +308,7 @@ void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function,
|
||||
unsigned int line, int error, const char *fmt, ...)
|
||||
{
|
||||
const char *errstr;
|
||||
struct va_format vaf = { .fmt = fmt };
|
||||
DECLARE_PV(vaf);
|
||||
va_list args;
|
||||
#if 0
|
||||
char *s_id = "<unknown>";
|
||||
@ -320,17 +318,18 @@ void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function,
|
||||
#endif
|
||||
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
PV_ASSIGN(vaf, fmt, args);
|
||||
|
||||
errstr = btrfs_decode_error(error);
|
||||
#if 0
|
||||
if (fs_info && (btrfs_test_opt(fs_info, PANIC_ON_FATAL_ERROR)))
|
||||
panic(KERN_CRIT "BTRFS panic (device %s) in %s:%d: %pV (error=%d %s)\n",
|
||||
s_id, function, line, &vaf, error, errstr);
|
||||
panic(KERN_CRIT "BTRFS panic (device %s) in %s:%d: " PV_FMT " (error=%d %s)\n",
|
||||
s_id, function, line, PV_VAL(vaf), error, errstr);
|
||||
#endif
|
||||
|
||||
btrfs_crit(fs_info, "panic in %s:%d: %pV (error=%d %s)",
|
||||
function, line, &vaf, error, errstr);
|
||||
|
||||
btrfs_crit(fs_info, "panic in %s:%d: " PV_FMT " (error=%d %s)",
|
||||
function, line, PV_VAL(vaf), error, errstr);
|
||||
va_end(args);
|
||||
/* Caller calls BUG() */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user