On Mon, 2019-07-29 at 18:49 -0700, Deepa Dinamani wrote: > The warning reuses the uptime max of 30 years used by the > setitimeofday(). > > Note that the warning is only added for new filesystem mounts > through the mount syscall. Automounts do not have the same warning. > > Signed-off-by: Deepa Dinamani <deepa.kernel@xxxxxxxxx> > --- > fs/namespace.c | 11 +++++++++++ > 1 file changed, 11 insertions(+) > > diff --git a/fs/namespace.c b/fs/namespace.c > index b26778bdc236..5314fac8035e 100644 > --- a/fs/namespace.c > +++ b/fs/namespace.c > @@ -2739,6 +2739,17 @@ static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint, > error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags); > if (error < 0) > mntput(mnt); > + > + if (!error && sb->s_time_max && I don't know why you are testing sb->s_time_max here - it should always be non-zero since alloc_super() sets it to TIME64_MAX. > + (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) { > + char *buf = (char *)__get_free_page(GFP_KERNEL); > + char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM); > + > + pr_warn("Mounted %s file system at %s supports timestamps until 0x%llx\n", > + fc->fs_type->name, mntpath, (unsigned long long)sb->s_time_max); This doesn't seem like a helpful way to log the time. Maybe use time64_to_tm() to convert to "broken down" time and then print it with "%ptR"... but that wants struct rtc_time. If you apply the attached patch, however, you should then be able to print struct tm with "%ptT". Ben. > + free_page((unsigned long)buf); > + } > + > return error; > } > -- Ben Hutchings, Software Developer Codethink Ltd https://www.codethink.co.uk/ Dale House, 35 Dale Street Manchester, M1 2HF, United Kingdom
From 40cd51356d366110d33b891a6b9f3a428ed4ab2e Mon Sep 17 00:00:00 2001 From: Ben Hutchings <ben.hutchings@xxxxxxxxxxxxxxx> Date: Mon, 5 Aug 2019 14:49:33 +0100 Subject: [PATCH] vsprintf: Add support for printing struct tm in human-readable format Change date_str(), time_str(), rtc_str() to take a struct tm (the main kAPI type) instead of struct rtc_time (uAPI type), and rename rtc_str() accordingly. Change time_and_date() to accept either a struct rtc_time ('R') or a struct tm ('T'), converting the former to the latter. Signed-off-by: Ben Hutchings <ben.hutchings@xxxxxxxxxxxxxxx> --- Documentation/core-api/printk-formats.rst | 6 ++-- lib/vsprintf.c | 34 ++++++++++++++++------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst index 75d2bbe9813f..fbae020bcc22 100644 --- a/Documentation/core-api/printk-formats.rst +++ b/Documentation/core-api/printk-formats.rst @@ -436,10 +436,10 @@ Time and date (struct rtc_time) %ptR YYYY-mm-ddTHH:MM:SS %ptRd YYYY-mm-dd %ptRt HH:MM:SS - %ptR[dt][r] + %pt[RT][dt][r] -For printing date and time as represented by struct rtc_time structure in -human readable format. +For printing date and time as represented by struct rtc_time (R) or struct +tm (T) structure in human readable format. By default year will be incremented by 1900 and month by 1. Use %ptRr (raw) to suppress this behaviour. diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 63937044c57d..dc32742876fd 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1699,7 +1699,7 @@ char *address_val(char *buf, char *end, const void *addr, } static noinline_for_stack -char *date_str(char *buf, char *end, const struct rtc_time *tm, bool r) +char *date_str(char *buf, char *end, const struct tm *tm, bool r) { int year = tm->tm_year + (r ? 0 : 1900); int mon = tm->tm_mon + (r ? 0 : 1); @@ -1718,7 +1718,7 @@ char *date_str(char *buf, char *end, const struct rtc_time *tm, bool r) } static noinline_for_stack -char *time_str(char *buf, char *end, const struct rtc_time *tm, bool r) +char *time_str(char *buf, char *end, const struct tm *tm, bool r) { buf = number(buf, end, tm->tm_hour, default_dec02_spec); if (buf < end) @@ -1734,16 +1734,13 @@ char *time_str(char *buf, char *end, const struct rtc_time *tm, bool r) } static noinline_for_stack -char *rtc_str(char *buf, char *end, const struct rtc_time *tm, - struct printf_spec spec, const char *fmt) +char *struct_tm_str(char *buf, char *end, const struct tm *tm, + struct printf_spec spec, const char *fmt) { bool have_t = true, have_d = true; bool raw = false; int count = 2; - if (check_pointer(&buf, end, tm, spec)) - return buf; - switch (fmt[count]) { case 'd': have_t = false; @@ -1775,11 +1772,28 @@ static noinline_for_stack char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, const char *fmt) { + if (check_pointer(&buf, end, ptr, spec)) + return buf; + switch (fmt[1]) { - case 'R': - return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); + case 'R': { + const struct rtc_time *rtm = (const struct rtc_time *)ptr; + struct tm tm = { + .tm_sec = rtm->tm_sec, + .tm_min = rtm->tm_min, + .tm_hour = rtm->tm_hour, + .tm_mday = rtm->tm_mday, + .tm_mon = rtm->tm_mon, + .tm_year = rtm->tm_year, + }; + + return struct_tm_str(buf, end, &tm, spec, fmt); + } + case 'T': + return struct_tm_str(buf, end, (const struct tm *)ptr, + spec, fmt); default: - return error_string(buf, end, "(%ptR?)", spec); + return error_string(buf, end, "(%pt?)", spec); } } -- Ben Hutchings, Software Developer Codethink Ltd https://www.codethink.co.uk/ Dale House, 35 Dale Street Manchester, M1 2HF, United Kingdom