From d063623b6ae7c326d21a2713dd38cab15d794c1c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 29 Nov 2017 12:32:42 -0800 Subject: Documentation: add UUID/GUID to kernel-api Update kernel-doc notation in lib/uuid.c and then add UUID/GUID function interfaces to kernel-api. Signed-off-by: Randy Dunlap [jc: tweaked the uuid_is_valid() kerneldoc] Signed-off-by: Jonathan Corbet --- lib/uuid.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/uuid.c b/lib/uuid.c index 680b9fb9ba09..2290b9f001a9 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -29,15 +29,14 @@ EXPORT_SYMBOL(uuid_null); const u8 guid_index[16] = {3,2,1,0,5,4,7,6,8,9,10,11,12,13,14,15}; const u8 uuid_index[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; -/*************************************************************** +/** + * generate_random_uuid - generate a random UUID + * @uuid: where to put the generated UUID + * * Random UUID interface * - * Used here for a Boot ID, but can be useful for other kernel - * drivers. - ***************************************************************/ - -/* - * Generate random UUID + * Used to create a Boot ID or a filesystem UUID/GUID, but can be + * useful for other kernel drivers. */ void generate_random_uuid(unsigned char uuid[16]) { @@ -73,16 +72,17 @@ void uuid_gen(uuid_t *bu) EXPORT_SYMBOL_GPL(uuid_gen); /** - * uuid_is_valid - checks if UUID string valid - * @uuid: UUID string to check - * - * Description: - * It checks if the UUID string is following the format: - * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx - * where x is a hex digit. - * - * Return: true if input is valid UUID string. - */ + * uuid_is_valid - checks if a UUID string is valid + * @uuid: UUID string to check + * + * Description: + * It checks if the UUID string is following the format: + * xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + * + * where x is a hex digit. + * + * Return: true if input is valid UUID string. + */ bool uuid_is_valid(const char *uuid) { unsigned int i; -- cgit v1.2.3 From b3ed23213eab1e08be594ad44b4237588c58af09 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 20 Dec 2017 08:17:15 +1100 Subject: doc: convert printk-formats.txt to rst Documentation/printk-formats.txt is a candidate for conversion to ReStructuredText format. Some effort has already been made to do this conversion even thought the suffix is currently .txt Changes required to complete conversion - Move printk-formats.txt to core-api/printk-formats.rst - Add entry to Documentation/core-api/index.rst - Remove entry from Documentation/00-INDEX - Fix minor grammatical errors. - Order heading adornments as suggested by rst docs. - Use 'Passed by reference' uniformly. - Update pointer documentation around %px specifier. - Fix erroneous double backticks (to commas). - Remove extraneous double backticks (suggested by Jonathan Corbet). - Simplify documentation for kobject. Signed-off-by: Tobin C. Harding [jc: downcased "kernel"] Signed-off-by: Jonathan Corbet --- Documentation/00-INDEX | 2 - Documentation/core-api/index.rst | 1 + Documentation/core-api/printk-formats.rst | 492 ++++++++++++++++++++++++++++++ Documentation/printk-formats.txt | 483 ----------------------------- lib/vsprintf.c | 3 +- 5 files changed, 495 insertions(+), 486 deletions(-) create mode 100644 Documentation/core-api/printk-formats.rst delete mode 100644 Documentation/printk-formats.txt (limited to 'lib') diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 3bec49c33bbb..7023bfaec21c 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -346,8 +346,6 @@ prctl/ - directory with info on the priveledge control subsystem preempt-locking.txt - info on locking under a preemptive kernel. -printk-formats.txt - - how to get printk format specifiers right process/ - how to work with the mainline kernel development process. pps/ diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index d4d54b05d6c5..d55ee6b006ed 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -22,6 +22,7 @@ Core utilities flexible-arrays librs genalloc + printk-formats Interfaces for kernel debugging =============================== diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst new file mode 100644 index 000000000000..258b46435320 --- /dev/null +++ b/Documentation/core-api/printk-formats.rst @@ -0,0 +1,492 @@ +========================================= +How to get printk format specifiers right +========================================= + +:Author: Randy Dunlap +:Author: Andrew Murray + + +Integer types +============= + +:: + + If variable is of Type, use printk format specifier: + ------------------------------------------------------------ + int %d or %x + unsigned int %u or %x + long %ld or %lx + unsigned long %lu or %lx + long long %lld or %llx + unsigned long long %llu or %llx + size_t %zu or %zx + ssize_t %zd or %zx + s32 %d or %x + u32 %u or %x + s64 %lld or %llx + u64 %llu or %llx + + +If is dependent on a config option for its size (e.g., sector_t, +blkcnt_t) or is architecture-dependent for its size (e.g., tcflag_t), use a +format specifier of its largest possible type and explicitly cast to it. + +Example:: + + printk("test: sector number/total blocks: %llu/%llu\n", + (unsigned long long)sector, (unsigned long long)blockcount); + +Reminder: sizeof() returns type size_t. + +The kernel's printf does not support %n. Floating point formats (%e, %f, +%g, %a) are also not recognized, for obvious reasons. Use of any +unsupported specifier or length qualifier results in a WARN and early +return from vsnprintf(). + +Pointer types +============= + +A raw pointer value may be printed with %p which will hash the address +before printing. The kernel also supports extended specifiers for printing +pointers of different types. + +Plain Pointers +-------------- + +:: + + %p abcdef12 or 00000000abcdef12 + +Pointers printed without a specifier extension (i.e unadorned %p) are +hashed to prevent leaking information about the kernel memory layout. This +has the added benefit of providing a unique identifier. On 64-bit machines +the first 32 bits are zeroed. If you *really* want the address see %px +below. + +Symbols/Function Pointers +------------------------- + +:: + + %pF versatile_init+0x0/0x110 + %pf versatile_init + %pS versatile_init+0x0/0x110 + %pSR versatile_init+0x9/0x110 + (with __builtin_extract_return_addr() translation) + %ps versatile_init + %pB prev_fn_of_versatile_init+0x88/0x88 + + +The ``F`` and ``f`` specifiers are for printing function pointers, +for example, f->func, &gettimeofday. They have the same result as +``S`` and ``s`` specifiers. But they do an extra conversion on +ia64, ppc64 and parisc64 architectures where the function pointers +are actually function descriptors. + +The ``S`` and ``s`` specifiers can be used for printing symbols +from direct addresses, for example, __builtin_return_address(0), +(void *)regs->ip. They result in the symbol name with (S) or +without (s) offsets. If KALLSYMS are disabled then the symbol +address is printed instead. + +The ``B`` specifier results in the symbol name with offsets and should be +used when printing stack backtraces. The specifier takes into +consideration the effect of compiler optimisations which may occur +when tail-calls are used and marked with the noreturn GCC attribute. + +Examples:: + + printk("Going to call: %pF\n", gettimeofday); + printk("Going to call: %pF\n", p->func); + printk("%s: called from %pS\n", __func__, (void *)_RET_IP_); + printk("%s: called from %pS\n", __func__, + (void *)__builtin_return_address(0)); + printk("Faulted at %pS\n", (void *)regs->ip); + printk(" %s%pB\n", (reliable ? "" : "? "), (void *)*stack); + +Kernel Pointers +--------------- + +:: + + %pK 01234567 or 0123456789abcdef + +For printing kernel pointers which should be hidden from unprivileged +users. The behaviour of %pK depends on the kptr_restrict sysctl - see +Documentation/sysctl/kernel.txt for more details. + +Unmodified Addresses +-------------------- + +:: + + %px 01234567 or 0123456789abcdef + +For printing pointers when you *really* want to print the address. Please +consider whether or not you are leaking sensitive information about the +kernel memory layout before printing pointers with %px. %px is functionally +equivalent to %lx (or %lu). %px is preferred because it is more uniquely +grep'able. If in the future we need to modify the way the kernel handles +printing pointers we will be better equipped to find the call sites. + +Struct Resources +---------------- + +:: + + %pr [mem 0x60000000-0x6fffffff flags 0x2200] or + [mem 0x0000000060000000-0x000000006fffffff flags 0x2200] + %pR [mem 0x60000000-0x6fffffff pref] or + [mem 0x0000000060000000-0x000000006fffffff pref] + +For printing struct resources. The ``R`` and ``r`` specifiers result in a +printed resource with (R) or without (r) a decoded flags member. + +Passed by reference. + +Physical address types phys_addr_t +---------------------------------- + +:: + + %pa[p] 0x01234567 or 0x0123456789abcdef + +For printing a phys_addr_t type (and its derivatives, such as +resource_size_t) which can vary based on build options, regardless of the +width of the CPU data path. + +Passed by reference. + +DMA address types dma_addr_t +---------------------------- + +:: + + %pad 0x01234567 or 0x0123456789abcdef + +For printing a dma_addr_t type which can vary based on build options, +regardless of the width of the CPU data path. + +Passed by reference. + +Raw buffer as an escaped string +------------------------------- + +:: + + %*pE[achnops] + +For printing raw buffer as an escaped string. For the following buffer:: + + 1b 62 20 5c 43 07 22 90 0d 5d + +A few examples show how the conversion would be done (excluding surrounding +quotes):: + + %*pE "\eb \C\a"\220\r]" + %*pEhp "\x1bb \C\x07"\x90\x0d]" + %*pEa "\e\142\040\\\103\a\042\220\r\135" + +The conversion rules are applied according to an optional combination +of flags (see :c:func:`string_escape_mem` kernel documentation for the +details): + + - a - ESCAPE_ANY + - c - ESCAPE_SPECIAL + - h - ESCAPE_HEX + - n - ESCAPE_NULL + - o - ESCAPE_OCTAL + - p - ESCAPE_NP + - s - ESCAPE_SPACE + +By default ESCAPE_ANY_NP is used. + +ESCAPE_ANY_NP is the sane choice for many cases, in particularly for +printing SSIDs. + +If field width is omitted then 1 byte only will be escaped. + +Raw buffer as a hex string +-------------------------- + +:: + + %*ph 00 01 02 ... 3f + %*phC 00:01:02: ... :3f + %*phD 00-01-02- ... -3f + %*phN 000102 ... 3f + +For printing small buffers (up to 64 bytes long) as a hex string with a +certain separator. For larger buffers consider using +:c:func:`print_hex_dump`. + +MAC/FDDI addresses +------------------ + +:: + + %pM 00:01:02:03:04:05 + %pMR 05:04:03:02:01:00 + %pMF 00-01-02-03-04-05 + %pm 000102030405 + %pmR 050403020100 + +For printing 6-byte MAC/FDDI addresses in hex notation. The ``M`` and ``m`` +specifiers result in a printed address with (M) or without (m) byte +separators. The default byte separator is the colon (:). + +Where FDDI addresses are concerned the ``F`` specifier can be used after +the ``M`` specifier to use dash (-) separators instead of the default +separator. + +For Bluetooth addresses the ``R`` specifier shall be used after the ``M`` +specifier to use reversed byte order suitable for visual interpretation +of Bluetooth addresses which are in the little endian order. + +Passed by reference. + +IPv4 addresses +-------------- + +:: + + %pI4 1.2.3.4 + %pi4 001.002.003.004 + %p[Ii]4[hnbl] + +For printing IPv4 dot-separated decimal addresses. The ``I4`` and ``i4`` +specifiers result in a printed address with (i4) or without (I4) leading +zeros. + +The additional ``h``, ``n``, ``b``, and ``l`` specifiers are used to specify +host, network, big or little endian order addresses respectively. Where +no specifier is provided the default network/big endian order is used. + +Passed by reference. + +IPv6 addresses +-------------- + +:: + + %pI6 0001:0002:0003:0004:0005:0006:0007:0008 + %pi6 00010002000300040005000600070008 + %pI6c 1:2:3:4:5:6:7:8 + +For printing IPv6 network-order 16-bit hex addresses. The ``I6`` and ``i6`` +specifiers result in a printed address with (I6) or without (i6) +colon-separators. Leading zeros are always used. + +The additional ``c`` specifier can be used with the ``I`` specifier to +print a compressed IPv6 address as described by +http://tools.ietf.org/html/rfc5952 + +Passed by reference. + +IPv4/IPv6 addresses (generic, with port, flowinfo, scope) +--------------------------------------------------------- + +:: + + %pIS 1.2.3.4 or 0001:0002:0003:0004:0005:0006:0007:0008 + %piS 001.002.003.004 or 00010002000300040005000600070008 + %pISc 1.2.3.4 or 1:2:3:4:5:6:7:8 + %pISpc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345 + %p[Ii]S[pfschnbl] + +For printing an IP address without the need to distinguish whether it's of +type AF_INET or AF_INET6. A pointer to a valid struct sockaddr, +specified through ``IS`` or ``iS``, can be passed to this format specifier. + +The additional ``p``, ``f``, and ``s`` specifiers are used to specify port +(IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ``:`` prefix, +flowinfo a ``/`` and scope a ``%``, each followed by the actual value. + +In case of an IPv6 address the compressed IPv6 address as described by +http://tools.ietf.org/html/rfc5952 is being used if the additional +specifier ``c`` is given. The IPv6 address is surrounded by ``[``, ``]`` in +case of additional specifiers ``p``, ``f`` or ``s`` as suggested by +https://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-07 + +In case of IPv4 addresses, the additional ``h``, ``n``, ``b``, and ``l`` +specifiers can be used as well and are ignored in case of an IPv6 +address. + +Passed by reference. + +Further examples:: + + %pISfc 1.2.3.4 or [1:2:3:4:5:6:7:8]/123456789 + %pISsc 1.2.3.4 or [1:2:3:4:5:6:7:8]%1234567890 + %pISpfc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345/123456789 + +UUID/GUID addresses +------------------- + +:: + + %pUb 00010203-0405-0607-0809-0a0b0c0d0e0f + %pUB 00010203-0405-0607-0809-0A0B0C0D0E0F + %pUl 03020100-0504-0706-0809-0a0b0c0e0e0f + %pUL 03020100-0504-0706-0809-0A0B0C0E0E0F + +For printing 16-byte UUID/GUIDs addresses. The additional ``l``, ``L``, +``b`` and ``B`` specifiers are used to specify a little endian order in +lower (l) or upper case (L) hex notation - and big endian order in lower (b) +or upper case (B) hex notation. + +Where no additional specifiers are used the default big endian +order with lower case hex notation will be printed. + +Passed by reference. + +dentry names +------------ + +:: + + %pd{,2,3,4} + %pD{,2,3,4} + +For printing dentry name; if we race with :c:func:`d_move`, the name might +be a mix of old and new ones, but it won't oops. %pd dentry is a safer +equivalent of %s dentry->d_name.name we used to use, %pd prints ``n`` +last components. %pD does the same thing for struct file. + +Passed by reference. + +block_device names +------------------ + +:: + + %pg sda, sda1 or loop0p1 + +For printing name of block_device pointers. + +struct va_format +---------------- + +:: + + %pV + +For printing struct va_format structures. These contain a format string +and va_list as follows:: + + struct va_format { + const char *fmt; + va_list *va; + }; + +Implements a "recursive vsnprintf". + +Do not use this feature without some mechanism to verify the +correctness of the format string and va_list arguments. + +Passed by reference. + +kobjects +-------- + +:: + + %pOF[fnpPcCF] + + +For printing kobject based structs (device nodes). Default behaviour is +equivalent to %pOFf. + + - f - device node full_name + - n - device node name + - p - device node phandle + - P - device node path spec (name + @unit) + - F - device node flags + - c - major compatible string + - C - full compatible string + +The separator when using multiple arguments is ':' + +Examples:: + + %pOF /foo/bar@0 - Node full name + %pOFf /foo/bar@0 - Same as above + %pOFfp /foo/bar@0:10 - Node full name + phandle + %pOFfcF /foo/bar@0:foo,device:--P- - Node full name + + major compatible string + + node flags + D - dynamic + d - detached + P - Populated + B - Populated bus + +Passed by reference. + +struct clk +---------- + +:: + + %pC pll1 + %pCn pll1 + %pCr 1560000000 + +For printing struct clk structures. %pC and %pCn print the name +(Common Clock Framework) or address (legacy clock framework) of the +structure; %pCr prints the current clock rate. + +Passed by reference. + +bitmap and its derivatives such as cpumask and nodemask +------------------------------------------------------- + +:: + + %*pb 0779 + %*pbl 0,3-6,8-10 + +For printing bitmap and its derivatives such as cpumask and nodemask, +%*pb outputs the bitmap with field width as the number of bits and %*pbl +output the bitmap as range list with field width as the number of bits. + +Passed by reference. + +Flags bitfields such as page flags, gfp_flags +--------------------------------------------- + +:: + + %pGp referenced|uptodate|lru|active|private + %pGg GFP_USER|GFP_DMA32|GFP_NOWARN + %pGv read|exec|mayread|maywrite|mayexec|denywrite + +For printing flags bitfields as a collection of symbolic constants that +would construct the value. The type of flags is given by the third +character. Currently supported are [p]age flags, [v]ma_flags (both +expect ``unsigned long *``) and [g]fp_flags (expects ``gfp_t *``). The flag +names and print order depends on the particular type. + +Note that this format should not be used directly in the +:c:func:`TP_printk()` part of a tracepoint. Instead, use the show_*_flags() +functions from . + +Passed by reference. + +Network device features +----------------------- + +:: + + %pNF 0x000000000000c000 + +For printing netdev_features_t. + +Passed by reference. + +Thanks +====== + +If you add other %p extensions, please extend with +one or more test cases, if at all feasible. + +Thank you for your cooperation and attention. diff --git a/Documentation/printk-formats.txt b/Documentation/printk-formats.txt deleted file mode 100644 index aa0a776c817a..000000000000 --- a/Documentation/printk-formats.txt +++ /dev/null @@ -1,483 +0,0 @@ -========================================= -How to get printk format specifiers right -========================================= - -:Author: Randy Dunlap -:Author: Andrew Murray - -Integer types -============= - -:: - - If variable is of Type, use printk format specifier: - ------------------------------------------------------------ - int %d or %x - unsigned int %u or %x - long %ld or %lx - unsigned long %lu or %lx - long long %lld or %llx - unsigned long long %llu or %llx - size_t %zu or %zx - ssize_t %zd or %zx - s32 %d or %x - u32 %u or %x - s64 %lld or %llx - u64 %llu or %llx - -If is dependent on a config option for its size (e.g., ``sector_t``, -``blkcnt_t``) or is architecture-dependent for its size (e.g., ``tcflag_t``), -use a format specifier of its largest possible type and explicitly cast to it. - -Example:: - - printk("test: sector number/total blocks: %llu/%llu\n", - (unsigned long long)sector, (unsigned long long)blockcount); - -Reminder: ``sizeof()`` result is of type ``size_t``. - -The kernel's printf does not support ``%n``. For obvious reasons, floating -point formats (``%e, %f, %g, %a``) are also not recognized. Use of any -unsupported specifier or length qualifier results in a WARN and early -return from vsnprintf. - -Raw pointer value SHOULD be printed with %p. The kernel supports -the following extended format specifiers for pointer types: - -Pointer Types -============= - -Pointers printed without a specifier extension (i.e unadorned %p) are -hashed to give a unique identifier without leaking kernel addresses to user -space. On 64 bit machines the first 32 bits are zeroed. If you _really_ -want the address see %px below. - -:: - - %p abcdef12 or 00000000abcdef12 - -Symbols/Function Pointers -========================= - -:: - - %pF versatile_init+0x0/0x110 - %pf versatile_init - %pS versatile_init+0x0/0x110 - %pSR versatile_init+0x9/0x110 - (with __builtin_extract_return_addr() translation) - %ps versatile_init - %pB prev_fn_of_versatile_init+0x88/0x88 - -The ``F`` and ``f`` specifiers are for printing function pointers, -for example, f->func, &gettimeofday. They have the same result as -``S`` and ``s`` specifiers. But they do an extra conversion on -ia64, ppc64 and parisc64 architectures where the function pointers -are actually function descriptors. - -The ``S`` and ``s`` specifiers can be used for printing symbols -from direct addresses, for example, __builtin_return_address(0), -(void *)regs->ip. They result in the symbol name with (``S``) or -without (``s``) offsets. If KALLSYMS are disabled then the symbol -address is printed instead. - -The ``B`` specifier results in the symbol name with offsets and should be -used when printing stack backtraces. The specifier takes into -consideration the effect of compiler optimisations which may occur -when tail-call``s are used and marked with the noreturn GCC attribute. - -Examples:: - - printk("Going to call: %pF\n", gettimeofday); - printk("Going to call: %pF\n", p->func); - printk("%s: called from %pS\n", __func__, (void *)_RET_IP_); - printk("%s: called from %pS\n", __func__, - (void *)__builtin_return_address(0)); - printk("Faulted at %pS\n", (void *)regs->ip); - printk(" %s%pB\n", (reliable ? "" : "? "), (void *)*stack); - -Kernel Pointers -=============== - -:: - - %pK 01234567 or 0123456789abcdef - -For printing kernel pointers which should be hidden from unprivileged -users. The behaviour of ``%pK`` depends on the ``kptr_restrict sysctl`` - see -Documentation/sysctl/kernel.txt for more details. - -Unmodified Addresses -==================== - -:: - - %px 01234567 or 0123456789abcdef - -For printing pointers when you _really_ want to print the address. Please -consider whether or not you are leaking sensitive information about the -Kernel layout in memory before printing pointers with %px. %px is -functionally equivalent to %lx. %px is preferred to %lx because it is more -uniquely grep'able. If, in the future, we need to modify the way the Kernel -handles printing pointers it will be nice to be able to find the call -sites. - -Struct Resources -================ - -:: - - %pr [mem 0x60000000-0x6fffffff flags 0x2200] or - [mem 0x0000000060000000-0x000000006fffffff flags 0x2200] - %pR [mem 0x60000000-0x6fffffff pref] or - [mem 0x0000000060000000-0x000000006fffffff pref] - -For printing struct resources. The ``R`` and ``r`` specifiers result in a -printed resource with (``R``) or without (``r``) a decoded flags member. -Passed by reference. - -Physical addresses types ``phys_addr_t`` -======================================== - -:: - - %pa[p] 0x01234567 or 0x0123456789abcdef - -For printing a ``phys_addr_t`` type (and its derivatives, such as -``resource_size_t``) which can vary based on build options, regardless of -the width of the CPU data path. Passed by reference. - -DMA addresses types ``dma_addr_t`` -================================== - -:: - - %pad 0x01234567 or 0x0123456789abcdef - -For printing a ``dma_addr_t`` type which can vary based on build options, -regardless of the width of the CPU data path. Passed by reference. - -Raw buffer as an escaped string -=============================== - -:: - - %*pE[achnops] - -For printing raw buffer as an escaped string. For the following buffer:: - - 1b 62 20 5c 43 07 22 90 0d 5d - -few examples show how the conversion would be done (the result string -without surrounding quotes):: - - %*pE "\eb \C\a"\220\r]" - %*pEhp "\x1bb \C\x07"\x90\x0d]" - %*pEa "\e\142\040\\\103\a\042\220\r\135" - -The conversion rules are applied according to an optional combination -of flags (see :c:func:`string_escape_mem` kernel documentation for the -details): - - - ``a`` - ESCAPE_ANY - - ``c`` - ESCAPE_SPECIAL - - ``h`` - ESCAPE_HEX - - ``n`` - ESCAPE_NULL - - ``o`` - ESCAPE_OCTAL - - ``p`` - ESCAPE_NP - - ``s`` - ESCAPE_SPACE - -By default ESCAPE_ANY_NP is used. - -ESCAPE_ANY_NP is the sane choice for many cases, in particularly for -printing SSIDs. - -If field width is omitted the 1 byte only will be escaped. - -Raw buffer as a hex string -========================== - -:: - - %*ph 00 01 02 ... 3f - %*phC 00:01:02: ... :3f - %*phD 00-01-02- ... -3f - %*phN 000102 ... 3f - -For printing a small buffers (up to 64 bytes long) as a hex string with -certain separator. For the larger buffers consider to use -:c:func:`print_hex_dump`. - -MAC/FDDI addresses -================== - -:: - - %pM 00:01:02:03:04:05 - %pMR 05:04:03:02:01:00 - %pMF 00-01-02-03-04-05 - %pm 000102030405 - %pmR 050403020100 - -For printing 6-byte MAC/FDDI addresses in hex notation. The ``M`` and ``m`` -specifiers result in a printed address with (``M``) or without (``m``) byte -separators. The default byte separator is the colon (``:``). - -Where FDDI addresses are concerned the ``F`` specifier can be used after -the ``M`` specifier to use dash (``-``) separators instead of the default -separator. - -For Bluetooth addresses the ``R`` specifier shall be used after the ``M`` -specifier to use reversed byte order suitable for visual interpretation -of Bluetooth addresses which are in the little endian order. - -Passed by reference. - -IPv4 addresses -============== - -:: - - %pI4 1.2.3.4 - %pi4 001.002.003.004 - %p[Ii]4[hnbl] - -For printing IPv4 dot-separated decimal addresses. The ``I4`` and ``i4`` -specifiers result in a printed address with (``i4``) or without (``I4``) -leading zeros. - -The additional ``h``, ``n``, ``b``, and ``l`` specifiers are used to specify -host, network, big or little endian order addresses respectively. Where -no specifier is provided the default network/big endian order is used. - -Passed by reference. - -IPv6 addresses -============== - -:: - - %pI6 0001:0002:0003:0004:0005:0006:0007:0008 - %pi6 00010002000300040005000600070008 - %pI6c 1:2:3:4:5:6:7:8 - -For printing IPv6 network-order 16-bit hex addresses. The ``I6`` and ``i6`` -specifiers result in a printed address with (``I6``) or without (``i6``) -colon-separators. Leading zeros are always used. - -The additional ``c`` specifier can be used with the ``I`` specifier to -print a compressed IPv6 address as described by -http://tools.ietf.org/html/rfc5952 - -Passed by reference. - -IPv4/IPv6 addresses (generic, with port, flowinfo, scope) -========================================================= - -:: - - %pIS 1.2.3.4 or 0001:0002:0003:0004:0005:0006:0007:0008 - %piS 001.002.003.004 or 00010002000300040005000600070008 - %pISc 1.2.3.4 or 1:2:3:4:5:6:7:8 - %pISpc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345 - %p[Ii]S[pfschnbl] - -For printing an IP address without the need to distinguish whether it``s -of type AF_INET or AF_INET6, a pointer to a valid ``struct sockaddr``, -specified through ``IS`` or ``iS``, can be passed to this format specifier. - -The additional ``p``, ``f``, and ``s`` specifiers are used to specify port -(IPv4, IPv6), flowinfo (IPv6) and scope (IPv6). Ports have a ``:`` prefix, -flowinfo a ``/`` and scope a ``%``, each followed by the actual value. - -In case of an IPv6 address the compressed IPv6 address as described by -http://tools.ietf.org/html/rfc5952 is being used if the additional -specifier ``c`` is given. The IPv6 address is surrounded by ``[``, ``]`` in -case of additional specifiers ``p``, ``f`` or ``s`` as suggested by -https://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-07 - -In case of IPv4 addresses, the additional ``h``, ``n``, ``b``, and ``l`` -specifiers can be used as well and are ignored in case of an IPv6 -address. - -Passed by reference. - -Further examples:: - - %pISfc 1.2.3.4 or [1:2:3:4:5:6:7:8]/123456789 - %pISsc 1.2.3.4 or [1:2:3:4:5:6:7:8]%1234567890 - %pISpfc 1.2.3.4:12345 or [1:2:3:4:5:6:7:8]:12345/123456789 - -UUID/GUID addresses -=================== - -:: - - %pUb 00010203-0405-0607-0809-0a0b0c0d0e0f - %pUB 00010203-0405-0607-0809-0A0B0C0D0E0F - %pUl 03020100-0504-0706-0809-0a0b0c0e0e0f - %pUL 03020100-0504-0706-0809-0A0B0C0E0E0F - -For printing 16-byte UUID/GUIDs addresses. The additional 'l', 'L', -'b' and 'B' specifiers are used to specify a little endian order in -lower ('l') or upper case ('L') hex characters - and big endian order -in lower ('b') or upper case ('B') hex characters. - -Where no additional specifiers are used the default big endian -order with lower case hex characters will be printed. - -Passed by reference. - -dentry names -============ - -:: - - %pd{,2,3,4} - %pD{,2,3,4} - -For printing dentry name; if we race with :c:func:`d_move`, the name might be -a mix of old and new ones, but it won't oops. ``%pd`` dentry is a safer -equivalent of ``%s`` ``dentry->d_name.name`` we used to use, ``%pd`` prints -``n`` last components. ``%pD`` does the same thing for struct file. - -Passed by reference. - -block_device names -================== - -:: - - %pg sda, sda1 or loop0p1 - -For printing name of block_device pointers. - -struct va_format -================ - -:: - - %pV - -For printing struct va_format structures. These contain a format string -and va_list as follows:: - - struct va_format { - const char *fmt; - va_list *va; - }; - -Implements a "recursive vsnprintf". - -Do not use this feature without some mechanism to verify the -correctness of the format string and va_list arguments. - -Passed by reference. - -kobjects -======== - -:: - - %pO - - Base specifier for kobject based structs. Must be followed with - character for specific type of kobject as listed below: - - Device tree nodes: - - %pOF[fnpPcCF] - - For printing device tree nodes. The optional arguments are: - f device node full_name - n device node name - p device node phandle - P device node path spec (name + @unit) - F device node flags - c major compatible string - C full compatible string - Without any arguments prints full_name (same as %pOFf) - The separator when using multiple arguments is ':' - - Examples: - - %pOF /foo/bar@0 - Node full name - %pOFf /foo/bar@0 - Same as above - %pOFfp /foo/bar@0:10 - Node full name + phandle - %pOFfcF /foo/bar@0:foo,device:--P- - Node full name + - major compatible string + - node flags - D - dynamic - d - detached - P - Populated - B - Populated bus - - Passed by reference. - - -struct clk -========== - -:: - - %pC pll1 - %pCn pll1 - %pCr 1560000000 - -For printing struct clk structures. ``%pC`` and ``%pCn`` print the name -(Common Clock Framework) or address (legacy clock framework) of the -structure; ``%pCr`` prints the current clock rate. - -Passed by reference. - -bitmap and its derivatives such as cpumask and nodemask -======================================================= - -:: - - %*pb 0779 - %*pbl 0,3-6,8-10 - -For printing bitmap and its derivatives such as cpumask and nodemask, -``%*pb`` output the bitmap with field width as the number of bits and ``%*pbl`` -output the bitmap as range list with field width as the number of bits. - -Passed by reference. - -Flags bitfields such as page flags, gfp_flags -============================================= - -:: - - %pGp referenced|uptodate|lru|active|private - %pGg GFP_USER|GFP_DMA32|GFP_NOWARN - %pGv read|exec|mayread|maywrite|mayexec|denywrite - -For printing flags bitfields as a collection of symbolic constants that -would construct the value. The type of flags is given by the third -character. Currently supported are [p]age flags, [v]ma_flags (both -expect ``unsigned long *``) and [g]fp_flags (expects ``gfp_t *``). The flag -names and print order depends on the particular type. - -Note that this format should not be used directly in :c:func:`TP_printk()` part -of a tracepoint. Instead, use the ``show_*_flags()`` functions from -. - -Passed by reference. - -Network device features -======================= - -:: - - %pNF 0x000000000000c000 - -For printing netdev_features_t. - -Passed by reference. - -If you add other ``%p`` extensions, please extend lib/test_printf.c with -one or more test cases, if at all feasible. - - -Thank you for your cooperation and attention. diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 01c3957b2de6..6ec0844ab5d1 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1834,7 +1834,8 @@ static char *ptr_to_id(char *buf, char *end, void *ptr, struct printf_spec spec) * * - 'x' For printing the address. Equivalent to "%lx". * - * ** Please update also Documentation/printk-formats.txt when making changes ** + * ** When making changes please also update: + * Documentation/core-api/printk-formats.rst * * Note: The difference between 'S' and 'F' is that on ia64 and ppc64 * function pointers are really function descriptors, which contain a -- cgit v1.2.3 From 27e7c0e813aa5c626ac7e68250bdac82205057b1 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 21 Dec 2017 12:39:45 -0700 Subject: vsprintf: Fix a dangling documentation reference A reference to printk-formats.txt didn't get updated when the file moved; fix that. Signed-off-by: Jonathan Corbet --- lib/vsprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 6ec0844ab5d1..2b18135446dc 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -2195,7 +2195,7 @@ set_precision(struct printf_spec *spec, int prec) * - ``%n`` is unsupported * - ``%p*`` is handled by pointer() * - * See pointer() or Documentation/printk-formats.txt for more + * See pointer() or Documentation/core-api/printk-formats.rst for more * extensive description. * * **Please update the documentation in both places when making changes** -- cgit v1.2.3 From 14ebc28e07e68ff412aa42f7d8b67969e2f63d00 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 22 Dec 2017 06:32:16 -0800 Subject: errseq: Add to documentation tree - Move errseq.rst into core-api - Add errseq to the core-api index - Promote the header to a more prominent header type, otherwise we get three entries in the table of contents. - Reformat the table to look nicer and be a little more proportional in terms of horizontal width per bit (the SF bit is still disproportionately large, but there's no way to fix that). - Include errseq kernel-doc in the errseq.rst - Neaten some kernel-doc markup Signed-off-by: Matthew Wilcox Reviewed-by: Jeff Layton Reviewed-by: Randy Dunlap Signed-off-by: Jonathan Corbet --- Documentation/core-api/errseq.rst | 159 ++++++++++++++++++++++++++++++++++++++ Documentation/core-api/index.rst | 1 + Documentation/errseq.rst | 149 ----------------------------------- include/linux/errseq.h | 2 +- lib/errseq.c | 37 +++++---- 5 files changed, 182 insertions(+), 166 deletions(-) create mode 100644 Documentation/core-api/errseq.rst delete mode 100644 Documentation/errseq.rst (limited to 'lib') diff --git a/Documentation/core-api/errseq.rst b/Documentation/core-api/errseq.rst new file mode 100644 index 000000000000..ff332e272405 --- /dev/null +++ b/Documentation/core-api/errseq.rst @@ -0,0 +1,159 @@ +===================== +The errseq_t datatype +===================== + +An errseq_t is a way of recording errors in one place, and allowing any +number of "subscribers" to tell whether it has changed since a previous +point where it was sampled. + +The initial use case for this is tracking errors for file +synchronization syscalls (fsync, fdatasync, msync and sync_file_range), +but it may be usable in other situations. + +It's implemented as an unsigned 32-bit value. The low order bits are +designated to hold an error code (between 1 and MAX_ERRNO). The upper bits +are used as a counter. This is done with atomics instead of locking so that +these functions can be called from any context. + +Note that there is a risk of collisions if new errors are being recorded +frequently, since we have so few bits to use as a counter. + +To mitigate this, the bit between the error value and counter is used as +a flag to tell whether the value has been sampled since a new value was +recorded. That allows us to avoid bumping the counter if no one has +sampled it since the last time an error was recorded. + +Thus we end up with a value that looks something like this: + ++--------------------------------------+----+------------------------+ +| 31..13 | 12 | 11..0 | ++--------------------------------------+----+------------------------+ +| counter | SF | errno | ++--------------------------------------+----+------------------------+ + +The general idea is for "watchers" to sample an errseq_t value and keep +it as a running cursor. That value can later be used to tell whether +any new errors have occurred since that sampling was done, and atomically +record the state at the time that it was checked. This allows us to +record errors in one place, and then have a number of "watchers" that +can tell whether the value has changed since they last checked it. + +A new errseq_t should always be zeroed out. An errseq_t value of all zeroes +is the special (but common) case where there has never been an error. An all +zero value thus serves as the "epoch" if one wishes to know whether there +has ever been an error set since it was first initialized. + +API usage +========= + +Let me tell you a story about a worker drone. Now, he's a good worker +overall, but the company is a little...management heavy. He has to +report to 77 supervisors today, and tomorrow the "big boss" is coming in +from out of town and he's sure to test the poor fellow too. + +They're all handing him work to do -- so much he can't keep track of who +handed him what, but that's not really a big problem. The supervisors +just want to know when he's finished all of the work they've handed him so +far and whether he made any mistakes since they last asked. + +He might have made the mistake on work they didn't actually hand him, +but he can't keep track of things at that level of detail, all he can +remember is the most recent mistake that he made. + +Here's our worker_drone representation:: + + struct worker_drone { + errseq_t wd_err; /* for recording errors */ + }; + +Every day, the worker_drone starts out with a blank slate:: + + struct worker_drone wd; + + wd.wd_err = (errseq_t)0; + +The supervisors come in and get an initial read for the day. They +don't care about anything that happened before their watch begins:: + + struct supervisor { + errseq_t s_wd_err; /* private "cursor" for wd_err */ + spinlock_t s_wd_err_lock; /* protects s_wd_err */ + } + + struct supervisor su; + + su.s_wd_err = errseq_sample(&wd.wd_err); + spin_lock_init(&su.s_wd_err_lock); + +Now they start handing him tasks to do. Every few minutes they ask him to +finish up all of the work they've handed him so far. Then they ask him +whether he made any mistakes on any of it:: + + spin_lock(&su.su_wd_err_lock); + err = errseq_check_and_advance(&wd.wd_err, &su.s_wd_err); + spin_unlock(&su.su_wd_err_lock); + +Up to this point, that just keeps returning 0. + +Now, the owners of this company are quite miserly and have given him +substandard equipment with which to do his job. Occasionally it +glitches and he makes a mistake. He sighs a heavy sigh, and marks it +down:: + + errseq_set(&wd.wd_err, -EIO); + +...and then gets back to work. The supervisors eventually poll again +and they each get the error when they next check. Subsequent calls will +return 0, until another error is recorded, at which point it's reported +to each of them once. + +Note that the supervisors can't tell how many mistakes he made, only +whether one was made since they last checked, and the latest value +recorded. + +Occasionally the big boss comes in for a spot check and asks the worker +to do a one-off job for him. He's not really watching the worker +full-time like the supervisors, but he does need to know whether a +mistake occurred while his job was processing. + +He can just sample the current errseq_t in the worker, and then use that +to tell whether an error has occurred later:: + + errseq_t since = errseq_sample(&wd.wd_err); + /* submit some work and wait for it to complete */ + err = errseq_check(&wd.wd_err, since); + +Since he's just going to discard "since" after that point, he doesn't +need to advance it here. He also doesn't need any locking since it's +not usable by anyone else. + +Serializing errseq_t cursor updates +=================================== + +Note that the errseq_t API does not protect the errseq_t cursor during a +check_and_advance_operation. Only the canonical error code is handled +atomically. In a situation where more than one task might be using the +same errseq_t cursor at the same time, it's important to serialize +updates to that cursor. + +If that's not done, then it's possible for the cursor to go backward +in which case the same error could be reported more than once. + +Because of this, it's often advantageous to first do an errseq_check to +see if anything has changed, and only later do an +errseq_check_and_advance after taking the lock. e.g.:: + + if (errseq_check(&wd.wd_err, READ_ONCE(su.s_wd_err)) { + /* su.s_wd_err is protected by s_wd_err_lock */ + spin_lock(&su.s_wd_err_lock); + err = errseq_check_and_advance(&wd.wd_err, &su.s_wd_err); + spin_unlock(&su.s_wd_err_lock); + } + +That avoids the spinlock in the common case where nothing has changed +since the last time it was checked. + +Functions +========= + +.. kernel-doc:: lib/errseq.c diff --git a/Documentation/core-api/index.rst b/Documentation/core-api/index.rst index d55ee6b006ed..1b1fd01990b5 100644 --- a/Documentation/core-api/index.rst +++ b/Documentation/core-api/index.rst @@ -22,6 +22,7 @@ Core utilities flexible-arrays librs genalloc + errseq printk-formats Interfaces for kernel debugging diff --git a/Documentation/errseq.rst b/Documentation/errseq.rst deleted file mode 100644 index 4c29bd5afbc5..000000000000 --- a/Documentation/errseq.rst +++ /dev/null @@ -1,149 +0,0 @@ -The errseq_t datatype -===================== -An errseq_t is a way of recording errors in one place, and allowing any -number of "subscribers" to tell whether it has changed since a previous -point where it was sampled. - -The initial use case for this is tracking errors for file -synchronization syscalls (fsync, fdatasync, msync and sync_file_range), -but it may be usable in other situations. - -It's implemented as an unsigned 32-bit value. The low order bits are -designated to hold an error code (between 1 and MAX_ERRNO). The upper bits -are used as a counter. This is done with atomics instead of locking so that -these functions can be called from any context. - -Note that there is a risk of collisions if new errors are being recorded -frequently, since we have so few bits to use as a counter. - -To mitigate this, the bit between the error value and counter is used as -a flag to tell whether the value has been sampled since a new value was -recorded. That allows us to avoid bumping the counter if no one has -sampled it since the last time an error was recorded. - -Thus we end up with a value that looks something like this:: - - bit: 31..13 12 11..0 - +-----------------+----+----------------+ - | counter | SF | errno | - +-----------------+----+----------------+ - -The general idea is for "watchers" to sample an errseq_t value and keep -it as a running cursor. That value can later be used to tell whether -any new errors have occurred since that sampling was done, and atomically -record the state at the time that it was checked. This allows us to -record errors in one place, and then have a number of "watchers" that -can tell whether the value has changed since they last checked it. - -A new errseq_t should always be zeroed out. An errseq_t value of all zeroes -is the special (but common) case where there has never been an error. An all -zero value thus serves as the "epoch" if one wishes to know whether there -has ever been an error set since it was first initialized. - -API usage -========= -Let me tell you a story about a worker drone. Now, he's a good worker -overall, but the company is a little...management heavy. He has to -report to 77 supervisors today, and tomorrow the "big boss" is coming in -from out of town and he's sure to test the poor fellow too. - -They're all handing him work to do -- so much he can't keep track of who -handed him what, but that's not really a big problem. The supervisors -just want to know when he's finished all of the work they've handed him so -far and whether he made any mistakes since they last asked. - -He might have made the mistake on work they didn't actually hand him, -but he can't keep track of things at that level of detail, all he can -remember is the most recent mistake that he made. - -Here's our worker_drone representation:: - - struct worker_drone { - errseq_t wd_err; /* for recording errors */ - }; - -Every day, the worker_drone starts out with a blank slate:: - - struct worker_drone wd; - - wd.wd_err = (errseq_t)0; - -The supervisors come in and get an initial read for the day. They -don't care about anything that happened before their watch begins:: - - struct supervisor { - errseq_t s_wd_err; /* private "cursor" for wd_err */ - spinlock_t s_wd_err_lock; /* protects s_wd_err */ - } - - struct supervisor su; - - su.s_wd_err = errseq_sample(&wd.wd_err); - spin_lock_init(&su.s_wd_err_lock); - -Now they start handing him tasks to do. Every few minutes they ask him to -finish up all of the work they've handed him so far. Then they ask him -whether he made any mistakes on any of it:: - - spin_lock(&su.su_wd_err_lock); - err = errseq_check_and_advance(&wd.wd_err, &su.s_wd_err); - spin_unlock(&su.su_wd_err_lock); - -Up to this point, that just keeps returning 0. - -Now, the owners of this company are quite miserly and have given him -substandard equipment with which to do his job. Occasionally it -glitches and he makes a mistake. He sighs a heavy sigh, and marks it -down:: - - errseq_set(&wd.wd_err, -EIO); - -...and then gets back to work. The supervisors eventually poll again -and they each get the error when they next check. Subsequent calls will -return 0, until another error is recorded, at which point it's reported -to each of them once. - -Note that the supervisors can't tell how many mistakes he made, only -whether one was made since they last checked, and the latest value -recorded. - -Occasionally the big boss comes in for a spot check and asks the worker -to do a one-off job for him. He's not really watching the worker -full-time like the supervisors, but he does need to know whether a -mistake occurred while his job was processing. - -He can just sample the current errseq_t in the worker, and then use that -to tell whether an error has occurred later:: - - errseq_t since = errseq_sample(&wd.wd_err); - /* submit some work and wait for it to complete */ - err = errseq_check(&wd.wd_err, since); - -Since he's just going to discard "since" after that point, he doesn't -need to advance it here. He also doesn't need any locking since it's -not usable by anyone else. - -Serializing errseq_t cursor updates -=================================== -Note that the errseq_t API does not protect the errseq_t cursor during a -check_and_advance_operation. Only the canonical error code is handled -atomically. In a situation where more than one task might be using the -same errseq_t cursor at the same time, it's important to serialize -updates to that cursor. - -If that's not done, then it's possible for the cursor to go backward -in which case the same error could be reported more than once. - -Because of this, it's often advantageous to first do an errseq_check to -see if anything has changed, and only later do an -errseq_check_and_advance after taking the lock. e.g.:: - - if (errseq_check(&wd.wd_err, READ_ONCE(su.s_wd_err)) { - /* su.s_wd_err is protected by s_wd_err_lock */ - spin_lock(&su.s_wd_err_lock); - err = errseq_check_and_advance(&wd.wd_err, &su.s_wd_err); - spin_unlock(&su.s_wd_err_lock); - } - -That avoids the spinlock in the common case where nothing has changed -since the last time it was checked. diff --git a/include/linux/errseq.h b/include/linux/errseq.h index 6ffae9c5052d..fc2777770768 100644 --- a/include/linux/errseq.h +++ b/include/linux/errseq.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * See Documentation/errseq.rst and lib/errseq.c + * See Documentation/core-api/errseq.rst and lib/errseq.c */ #ifndef _LINUX_ERRSEQ_H #define _LINUX_ERRSEQ_H diff --git a/lib/errseq.c b/lib/errseq.c index 79cc66897db4..df782418b333 100644 --- a/lib/errseq.c +++ b/lib/errseq.c @@ -46,14 +46,14 @@ * @eseq: errseq_t field that should be set * @err: error to set (must be between -1 and -MAX_ERRNO) * - * This function sets the error in *eseq, and increments the sequence counter + * This function sets the error in @eseq, and increments the sequence counter * if the last sequence was sampled at some point in the past. * * Any error set will always overwrite an existing error. * - * We do return the latest value here, primarily for debugging purposes. The - * return value should not be used as a previously sampled value in later calls - * as it will not have the SEEN flag set. + * Return: The previous value, primarily for debugging purposes. The + * return value should not be used as a previously sampled value in later + * calls as it will not have the SEEN flag set. */ errseq_t errseq_set(errseq_t *eseq, int err) { @@ -108,11 +108,13 @@ errseq_t errseq_set(errseq_t *eseq, int err) EXPORT_SYMBOL(errseq_set); /** - * errseq_sample - grab current errseq_t value - * @eseq: pointer to errseq_t to be sampled + * errseq_sample() - Grab current errseq_t value. + * @eseq: Pointer to errseq_t to be sampled. * * This function allows callers to sample an errseq_t value, marking it as * "seen" if required. + * + * Return: The current errseq value. */ errseq_t errseq_sample(errseq_t *eseq) { @@ -134,15 +136,15 @@ errseq_t errseq_sample(errseq_t *eseq) EXPORT_SYMBOL(errseq_sample); /** - * errseq_check - has an error occurred since a particular sample point? - * @eseq: pointer to errseq_t value to be checked - * @since: previously-sampled errseq_t from which to check + * errseq_check() - Has an error occurred since a particular sample point? + * @eseq: Pointer to errseq_t value to be checked. + * @since: Previously-sampled errseq_t from which to check. * - * Grab the value that eseq points to, and see if it has changed "since" - * the given value was sampled. The "since" value is not advanced, so there + * Grab the value that eseq points to, and see if it has changed @since + * the given value was sampled. The @since value is not advanced, so there * is no need to mark the value as seen. * - * Returns the latest error set in the errseq_t or 0 if it hasn't changed. + * Return: The latest error set in the errseq_t or 0 if it hasn't changed. */ int errseq_check(errseq_t *eseq, errseq_t since) { @@ -155,11 +157,11 @@ int errseq_check(errseq_t *eseq, errseq_t since) EXPORT_SYMBOL(errseq_check); /** - * errseq_check_and_advance - check an errseq_t and advance to current value - * @eseq: pointer to value being checked and reported - * @since: pointer to previously-sampled errseq_t to check against and advance + * errseq_check_and_advance() - Check an errseq_t and advance to current value. + * @eseq: Pointer to value being checked and reported. + * @since: Pointer to previously-sampled errseq_t to check against and advance. * - * Grab the eseq value, and see whether it matches the value that "since" + * Grab the eseq value, and see whether it matches the value that @since * points to. If it does, then just return 0. * * If it doesn't, then the value has changed. Set the "seen" flag, and try to @@ -170,6 +172,9 @@ EXPORT_SYMBOL(errseq_check); * value. The caller must provide that if necessary. Because of this, callers * may want to do a lockless errseq_check before taking the lock and calling * this. + * + * Return: Negative errno if one has been stored, or 0 if no new error has + * occurred. */ int errseq_check_and_advance(errseq_t *eseq, errseq_t *since) { -- cgit v1.2.3