From 1031bc589228ca35b3b6fb3dfe4656c0da5fbeb4 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Mon, 13 Apr 2015 16:31:35 +0400 Subject: lib/vsprintf: add %*pg format specifier This allow to directly print block_device name. Currently one should use bdevname() with temporal char buffer. This is very ineffective because bloat stack usage for deep IO call-traces Example: %pg -> sda, sda1 or loop0p1 [AV: fixed a minor braino - position updates should not be dependent upon having reached the of buffer] Signed-off-by: Dmitry Monakhov Signed-off-by: Al Viro --- lib/vsprintf.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index f9cee8e1233c..ac3f9476b776 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -31,6 +31,9 @@ #include #include #include +#ifdef CONFIG_BLOCK +#include +#endif #include /* for PAGE_SIZE */ #include /* for dereference_function_descriptor() */ @@ -613,6 +616,26 @@ char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_sp return buf; } +#ifdef CONFIG_BLOCK +static noinline_for_stack +char *bdev_name(char *buf, char *end, struct block_device *bdev, + struct printf_spec spec, const char *fmt) +{ + struct gendisk *hd = bdev->bd_disk; + + buf = string(buf, end, hd->disk_name, spec); + if (bdev->bd_part->partno) { + if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) { + if (buf < end) + *buf = 'p'; + buf++; + } + buf = number(buf, end, bdev->bd_part->partno, spec); + } + return buf; +} +#endif + static noinline_for_stack char *symbol_string(char *buf, char *end, void *ptr, struct printf_spec spec, const char *fmt) @@ -1443,6 +1466,7 @@ int kptr_restrict __read_mostly; * (default assumed to be phys_addr_t, passed by reference) * - 'd[234]' For a dentry name (optionally 2-4 last components) * - 'D[234]' Same as 'd' but for a struct file + * - 'g' For block_device name (gendisk + partition number) * - 'C' For a clock, it prints the name (Common Clock Framework) or address * (legacy clock framework) of the clock * - 'Cn' For a clock, it prints the name (Common Clock Framework) or address @@ -1600,6 +1624,11 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, return dentry_name(buf, end, ((const struct file *)ptr)->f_path.dentry, spec, fmt); +#ifdef CONFIG_BLOCK + case 'g': + return bdev_name(buf, end, ptr, spec, fmt); +#endif + } spec.flags |= SMALL; if (spec.field_width == -1) { -- cgit v1.2.3