summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/tests/printf_kunit.c4
-rw-r--r--lib/vsprintf.c28
2 files changed, 31 insertions, 1 deletions
diff --git a/lib/tests/printf_kunit.c b/lib/tests/printf_kunit.c
index bc54cca2d7a6..7617e5b8b02c 100644
--- a/lib/tests/printf_kunit.c
+++ b/lib/tests/printf_kunit.c
@@ -504,6 +504,7 @@ time_and_date(struct kunit *kunittest)
};
/* 2019-01-04T15:32:23 */
time64_t t = 1546615943;
+ struct timespec64 ts = { .tv_sec = t, .tv_nsec = 11235813 };
test("(%pt?)", "%pt", &tm);
test("2018-11-26T05:35:43", "%ptR", &tm);
@@ -522,6 +523,9 @@ time_and_date(struct kunit *kunittest)
test("0119-00-04 15:32:23", "%ptTsr", &t);
test("15:32:23|2019-01-04", "%ptTts|%ptTds", &t, &t);
test("15:32:23|0119-00-04", "%ptTtrs|%ptTdrs", &t, &t);
+
+ test("2019-01-04T15:32:23.011235813", "%ptS", &ts);
+ test("1546615943.011235813", "%ptSp", &ts);
}
static void
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 0dffc7224d41..a3790c43a0ab 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -1984,6 +1984,28 @@ char *time64_str(char *buf, char *end, const time64_t time,
}
static noinline_for_stack
+char *timespec64_str(char *buf, char *end, const struct timespec64 *ts,
+ struct printf_spec spec, const char *fmt)
+{
+ static const struct printf_spec default_dec09_spec = {
+ .base = 10,
+ .field_width = 9,
+ .precision = -1,
+ .flags = ZEROPAD,
+ };
+
+ if (fmt[2] == 'p')
+ buf = number(buf, end, ts->tv_sec, default_dec_spec);
+ else
+ buf = time64_str(buf, end, ts->tv_sec, spec, fmt);
+ if (buf < end)
+ *buf = '.';
+ buf++;
+
+ return number(buf, end, ts->tv_nsec, default_dec09_spec);
+}
+
+static noinline_for_stack
char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec,
const char *fmt)
{
@@ -1993,6 +2015,8 @@ char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec,
switch (fmt[1]) {
case 'R':
return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt);
+ case 'S':
+ return timespec64_str(buf, end, (const struct timespec64 *)ptr, spec, fmt);
case 'T':
return time64_str(buf, end, *(const time64_t *)ptr, spec, fmt);
default:
@@ -2456,9 +2480,11 @@ early_param("no_hash_pointers", no_hash_pointers_enable);
* - '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)
- * - 't[RT][dt][r][s]' For time and date as represented by:
+ * - 't[RST][dt][r][s]' For time and date as represented by:
* R struct rtc_time
+ * S struct timespec64
* T time64_t
+ * - 'tSp' For time represented by struct timespec64 printed as <seconds>.<nanoseconds>
* - 'C' For a clock, it prints the name (Common Clock Framework) or address
* (legacy clock framework) of the clock
* - 'G' For flags to be printed as a collection of symbolic strings that would