diff options
author | Dmitry Monakhov <dmonakhov@openvz.org> | 2015-04-13 16:31:35 +0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-01-06 12:55:29 -0500 |
commit | 1031bc589228ca35b3b6fb3dfe4656c0da5fbeb4 (patch) | |
tree | 52ad94e769ee16491c9db4e9904ac266292e4996 /lib | |
parent | 424081f3c881ca3aef50cfa571e91863c10d952a (diff) |
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 <dmonakhov@openvz.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/vsprintf.c | 29 |
1 files changed, 29 insertions, 0 deletions
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 <linux/dcache.h> #include <linux/cred.h> #include <net/addrconf.h> +#ifdef CONFIG_BLOCK +#include <linux/blkdev.h> +#endif #include <asm/page.h> /* for PAGE_SIZE */ #include <asm/sections.h> /* 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) { |