mirror of
https://github.com/kdave/btrfs-progs
synced 2025-04-20 22:15:19 +00: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 <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <printf.h>
|
|
||||||
#include "common/messages.h"
|
#include "common/messages.h"
|
||||||
#include "common/utils.h"
|
#include "common/utils.h"
|
||||||
|
|
||||||
@ -26,8 +25,6 @@ static const char *common_error_string[] = {
|
|||||||
[ERROR_MSG_COMMIT_TRANS] = "failed to commit transaction",
|
[ERROR_MSG_COMMIT_TRANS] = "failed to commit transaction",
|
||||||
};
|
};
|
||||||
|
|
||||||
static int va_modifier = -1;
|
|
||||||
|
|
||||||
__attribute__ ((format (printf, 1, 2)))
|
__attribute__ ((format (printf, 1, 2)))
|
||||||
void __btrfs_printf(const char *fmt, ...)
|
void __btrfs_printf(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -38,6 +35,10 @@ void __btrfs_printf(const char *fmt, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PV_WORKAROUND
|
||||||
|
|
||||||
|
static int va_modifier = -1;
|
||||||
|
|
||||||
static int print_va_format(FILE *stream, const struct printf_info *info,
|
static int print_va_format(FILE *stream, const struct printf_info *info,
|
||||||
const void *const *args)
|
const void *const *args)
|
||||||
{
|
{
|
||||||
@ -59,17 +60,20 @@ static int print_va_format_arginfo(const struct printf_info *info,
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
__attribute__ ((format (printf, 2, 3)))
|
__attribute__ ((format (printf, 2, 3)))
|
||||||
void btrfs_no_printk(const void *fs_info, const char *fmt, ...)
|
void btrfs_no_printk(const void *fs_info, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
|
#ifndef PV_WORKAROUND
|
||||||
if (va_modifier == -1) {
|
if (va_modifier == -1) {
|
||||||
register_printf_specifier('V', print_va_format,
|
register_printf_specifier('V', print_va_format,
|
||||||
print_va_format_arginfo);
|
print_va_format_arginfo);
|
||||||
va_modifier = register_printf_modifier(L"p");
|
va_modifier = register_printf_modifier(L"p");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vfprintf(stderr, fmt, args);
|
vfprintf(stderr, fmt, args);
|
||||||
|
@ -22,6 +22,23 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.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
|
#ifdef DEBUG_VERBOSE_ERROR
|
||||||
#define PRINT_VERBOSE_ERROR fprintf(stderr, "%s:%d:", __FILE__, __LINE__)
|
#define PRINT_VERBOSE_ERROR fprintf(stderr, "%s:%d:", __FILE__, __LINE__)
|
||||||
#else
|
#else
|
||||||
|
@ -85,6 +85,7 @@ AX_GCC_BUILTIN([__builtin_mul_overflow])
|
|||||||
AC_CHECK_HEADERS([linux/perf_event.h])
|
AC_CHECK_HEADERS([linux/perf_event.h])
|
||||||
AC_CHECK_HEADERS([linux/hw_breakpoint.h])
|
AC_CHECK_HEADERS([linux/hw_breakpoint.h])
|
||||||
AC_CHECK_HEADERS([linux/fsverity.h])
|
AC_CHECK_HEADERS([linux/fsverity.h])
|
||||||
|
AC_CHECK_HEADERS([printf.h])
|
||||||
|
|
||||||
if grep -q 'HAVE_LINUX_FSVERITY_H.*1' confdefs.h; then
|
if grep -q 'HAVE_LINUX_FSVERITY_H.*1' confdefs.h; then
|
||||||
have_fsverity='yes'
|
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);
|
errstr = btrfs_decode_error(error);
|
||||||
btrfs_state_to_string(fs_info, statestr);
|
btrfs_state_to_string(fs_info, statestr);
|
||||||
if (fmt) {
|
if (fmt) {
|
||||||
struct va_format vaf;
|
DECLARE_PV(vaf);
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vaf.fmt = fmt;
|
PV_ASSIGN(vaf, fmt, args);
|
||||||
vaf.va = &args;
|
|
||||||
|
|
||||||
pr_crit("BTRFS: error (device %s%s) in %s:%d: error=%d %s (%pV)\n",
|
pr_crit("BTRFS: error (device %s%s) in %s:%d: error=%d %s (" PV_FMT ")\n",
|
||||||
sb->s_id, statestr, function, line, error, errstr, &vaf);
|
sb->s_id, statestr, function, line, error, errstr, PV_VAL(vaf));
|
||||||
va_end(args);
|
va_end(args);
|
||||||
} else {
|
} else {
|
||||||
pr_crit("BTRFS: error (device %s%s) in %s:%d: error=%d %s\n",
|
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, ...)
|
void __cold _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
char lvl[PRINTK_MAX_SINGLE_HEADER_LEN + 1] = "\0";
|
char lvl[PRINTK_MAX_SINGLE_HEADER_LEN + 1] = "\0";
|
||||||
struct va_format vaf;
|
DECLARE_PV(vaf);
|
||||||
va_list args;
|
va_list args;
|
||||||
int kern_level;
|
int kern_level;
|
||||||
const char *type = logtypes[4];
|
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;
|
fmt += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
vaf.fmt = fmt;
|
PV_ASSIGN(vaf, fmt, args);
|
||||||
vaf.va = &args;
|
|
||||||
|
|
||||||
if (__ratelimit(ratelimit)) {
|
if (__ratelimit(ratelimit)) {
|
||||||
if (fs_info) {
|
if (fs_info) {
|
||||||
char statestr[STATE_STRING_BUF_LEN];
|
char statestr[STATE_STRING_BUF_LEN];
|
||||||
|
|
||||||
btrfs_state_to_string(fs_info, statestr);
|
btrfs_state_to_string(fs_info, statestr);
|
||||||
_printk("%sBTRFS %s (device %s%s): %pV\n", lvl, type,
|
_printk("%sBTRFS %s (device %s%s): " PV_FMT "\n", lvl, type,
|
||||||
fs_info->sb->s_id, statestr, &vaf);
|
fs_info->sb->s_id, statestr, PV_VAL(vaf));
|
||||||
} else {
|
} 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, ...)
|
unsigned int line, int error, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
struct va_format vaf = { .fmt = fmt };
|
DECLARE_PV(vaf);
|
||||||
va_list args;
|
va_list args;
|
||||||
#if 0
|
#if 0
|
||||||
char *s_id = "<unknown>";
|
char *s_id = "<unknown>";
|
||||||
@ -320,17 +318,18 @@ void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
vaf.va = &args;
|
PV_ASSIGN(vaf, fmt, args);
|
||||||
|
|
||||||
errstr = btrfs_decode_error(error);
|
errstr = btrfs_decode_error(error);
|
||||||
#if 0
|
#if 0
|
||||||
if (fs_info && (btrfs_test_opt(fs_info, PANIC_ON_FATAL_ERROR)))
|
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",
|
panic(KERN_CRIT "BTRFS panic (device %s) in %s:%d: " PV_FMT " (error=%d %s)\n",
|
||||||
s_id, function, line, &vaf, error, errstr);
|
s_id, function, line, PV_VAL(vaf), error, errstr);
|
||||||
#endif
|
#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);
|
va_end(args);
|
||||||
/* Caller calls BUG() */
|
/* Caller calls BUG() */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user