diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 11:50:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-05 11:50:26 -0400 |
commit | 45d9a2220f6004b47c362cc7fc7cf9a73cb6353a (patch) | |
tree | 4e2217464c5cd71674a6ffff1f3dddaeb52556b7 /lib | |
parent | 2386a3b0fbb0c2dcf29694c7df9a72cb268458f0 (diff) | |
parent | 02afc27faec94c9e068517a22acf55400976c698 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs pile 1 from Al Viro:
"Unfortunately, this merge window it'll have a be a lot of small piles -
my fault, actually, for not keeping #for-next in anything that would
resemble a sane shape ;-/
This pile: assorted fixes (the first 3 are -stable fodder, IMO) and
cleanups + %pd/%pD formats (dentry/file pathname, up to 4 last
components) + several long-standing patches from various folks.
There definitely will be a lot more (starting with Miklos'
check_submount_and_drop() series)"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (26 commits)
direct-io: Handle O_(D)SYNC AIO
direct-io: Implement generic deferred AIO completions
add formats for dentry/file pathnames
kvm eventfd: switch to fdget
powerpc kvm: use fdget
switch fchmod() to fdget
switch epoll_ctl() to fdget
switch copy_module_from_fd() to fdget
git simplify nilfs check for busy subtree
ibmasmfs: don't bother passing superblock when not needed
don't pass superblock to hypfs_{mkdir,create*}
don't pass superblock to hypfs_diag_create_files
don't pass superblock to hypfs_vm_create_files()
oprofile: get rid of pointless forward declarations of struct super_block
oprofilefs_create_...() do not need superblock argument
oprofilefs_mkdir() doesn't need superblock argument
don't bother with passing superblock to oprofile_create_stats_files()
oprofile: don't bother with passing superblock to ->create_files()
don't bother passing sb to oprofile_create_files()
coh901318: don't open-code simple_read_from_buffer()
...
Diffstat (limited to 'lib')
-rw-r--r-- | lib/vsprintf.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 739a36366b79..26559bdb4c49 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/math64.h> | 26 | #include <linux/math64.h> |
27 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/dcache.h> | ||
29 | #include <net/addrconf.h> | 30 | #include <net/addrconf.h> |
30 | 31 | ||
31 | #include <asm/page.h> /* for PAGE_SIZE */ | 32 | #include <asm/page.h> /* for PAGE_SIZE */ |
@@ -532,6 +533,81 @@ char *string(char *buf, char *end, const char *s, struct printf_spec spec) | |||
532 | return buf; | 533 | return buf; |
533 | } | 534 | } |
534 | 535 | ||
536 | static void widen(char *buf, char *end, unsigned len, unsigned spaces) | ||
537 | { | ||
538 | size_t size; | ||
539 | if (buf >= end) /* nowhere to put anything */ | ||
540 | return; | ||
541 | size = end - buf; | ||
542 | if (size <= spaces) { | ||
543 | memset(buf, ' ', size); | ||
544 | return; | ||
545 | } | ||
546 | if (len) { | ||
547 | if (len > size - spaces) | ||
548 | len = size - spaces; | ||
549 | memmove(buf + spaces, buf, len); | ||
550 | } | ||
551 | memset(buf, ' ', spaces); | ||
552 | } | ||
553 | |||
554 | static noinline_for_stack | ||
555 | char *dentry_name(char *buf, char *end, const struct dentry *d, struct printf_spec spec, | ||
556 | const char *fmt) | ||
557 | { | ||
558 | const char *array[4], *s; | ||
559 | const struct dentry *p; | ||
560 | int depth; | ||
561 | int i, n; | ||
562 | |||
563 | switch (fmt[1]) { | ||
564 | case '2': case '3': case '4': | ||
565 | depth = fmt[1] - '0'; | ||
566 | break; | ||
567 | default: | ||
568 | depth = 1; | ||
569 | } | ||
570 | |||
571 | rcu_read_lock(); | ||
572 | for (i = 0; i < depth; i++, d = p) { | ||
573 | p = ACCESS_ONCE(d->d_parent); | ||
574 | array[i] = ACCESS_ONCE(d->d_name.name); | ||
575 | if (p == d) { | ||
576 | if (i) | ||
577 | array[i] = ""; | ||
578 | i++; | ||
579 | break; | ||
580 | } | ||
581 | } | ||
582 | s = array[--i]; | ||
583 | for (n = 0; n != spec.precision; n++, buf++) { | ||
584 | char c = *s++; | ||
585 | if (!c) { | ||
586 | if (!i) | ||
587 | break; | ||
588 | c = '/'; | ||
589 | s = array[--i]; | ||
590 | } | ||
591 | if (buf < end) | ||
592 | *buf = c; | ||
593 | } | ||
594 | rcu_read_unlock(); | ||
595 | if (n < spec.field_width) { | ||
596 | /* we want to pad the sucker */ | ||
597 | unsigned spaces = spec.field_width - n; | ||
598 | if (!(spec.flags & LEFT)) { | ||
599 | widen(buf - n, end, n, spaces); | ||
600 | return buf + spaces; | ||
601 | } | ||
602 | while (spaces--) { | ||
603 | if (buf < end) | ||
604 | *buf = ' '; | ||
605 | ++buf; | ||
606 | } | ||
607 | } | ||
608 | return buf; | ||
609 | } | ||
610 | |||
535 | static noinline_for_stack | 611 | static noinline_for_stack |
536 | char *symbol_string(char *buf, char *end, void *ptr, | 612 | char *symbol_string(char *buf, char *end, void *ptr, |
537 | struct printf_spec spec, const char *fmt) | 613 | struct printf_spec spec, const char *fmt) |
@@ -1253,6 +1329,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
1253 | spec.base = 16; | 1329 | spec.base = 16; |
1254 | return number(buf, end, | 1330 | return number(buf, end, |
1255 | (unsigned long long) *((phys_addr_t *)ptr), spec); | 1331 | (unsigned long long) *((phys_addr_t *)ptr), spec); |
1332 | case 'd': | ||
1333 | return dentry_name(buf, end, ptr, spec, fmt); | ||
1334 | case 'D': | ||
1335 | return dentry_name(buf, end, | ||
1336 | ((const struct file *)ptr)->f_path.dentry, | ||
1337 | spec, fmt); | ||
1256 | } | 1338 | } |
1257 | spec.flags |= SMALL; | 1339 | spec.flags |= SMALL; |
1258 | if (spec.field_width == -1) { | 1340 | if (spec.field_width == -1) { |