The current file system macros and time functions are not y2038 safe because of the use of struct timespec.
Change these to use timespec64.
The change will be globally enabled along with all the other 64-bit time file system changes.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com --- include/linux/fs.h | 4 ++++ include/linux/time.h | 2 ++ include/linux/time64.h | 5 +++++ kernel/time/time.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 39 insertions(+)
diff --git a/include/linux/fs.h b/include/linux/fs.h index c56068f..27bb983 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1399,7 +1399,11 @@ struct super_block { struct list_head s_inodes; /* all inodes */ };
+#ifdef CONFIG_FS_USES_64BIT_TIME +extern struct timespec64 current_fs_time(struct super_block *sb); +#else extern struct timespec current_fs_time(struct super_block *sb); +#endif
/* * Snapshotting support. diff --git a/include/linux/time.h b/include/linux/time.h index beebe3a..40fe4af 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -125,8 +125,10 @@ static inline bool timeval_valid(const struct timeval *tv)
extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
+#ifndef CONFIG_FS_USES_64BIT_TIME #define CURRENT_TIME (current_kernel_time()) #define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 }) +#endif
/* Some architectures do not supply their own clocksource. * This is mainly the case in architectures that get their diff --git a/include/linux/time64.h b/include/linux/time64.h index bb574b8..62f2b1a 100644 --- a/include/linux/time64.h +++ b/include/linux/time64.h @@ -37,6 +37,11 @@ struct itimerspec64 { #define inode_time timespec64 #endif
+#ifdef CONFIG_FS_USES_64BIT_TIME +#define CURRENT_TIME (current_kernel_time64()) +#define CURRENT_TIME_SEC ((struct timespec64) { ktime_get_seconds(), 0 }) +#endif + /* Parameters used to convert the timespec values: */ #define MSEC_PER_SEC 1000L #define USEC_PER_MSEC 1000L diff --git a/kernel/time/time.c b/kernel/time/time.c index 86751c6..92b6db1 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -237,11 +237,19 @@ SYSCALL_DEFINE1(adjtimex, struct timex __user *, txc_p) * Return the current time truncated to the time granularity supported by * the fs. */ +#ifdef CONFIG_FS_USES_64BIT_TIME +struct timespec64 current_fs_time(struct super_block *sb) +{ + struct timespec64 now = current_kernel_time64(); + return timespec64_trunc(now, sb->s_time_gran); +} +#else struct timespec current_fs_time(struct super_block *sb) { struct timespec now = current_kernel_time(); return timespec_trunc(now, sb->s_time_gran); } +#endif EXPORT_SYMBOL(current_fs_time);
/* @@ -294,6 +302,25 @@ EXPORT_SYMBOL(jiffies_to_usecs); * Truncate a timespec to a granularity. Always rounds down. gran must * not be 0 nor greater than a second (NSEC_PER_SEC, or 10^9 ns). */ +#ifdef CONFIG_FS_USES_64BIT_TIME +/* TODO: Change name to timespec64_trunc after the global switch to + * CONFIG_FS_USES_64BIT_TIME. + */ +struct timespec64 timespec_trunc(struct timespec64 t, unsigned gran) +{ + /* Avoid division in the common cases 1 ns and 1 s. */ + if (gran == 1) { + /* nothing */ + } else if (gran == NSEC_PER_SEC) { + t.tv_nsec = 0; + } else if (gran > 1 && gran < NSEC_PER_SEC) { + t.tv_nsec -= t.tv_nsec % gran; + } else { + WARN(1, "illegal file time granularity: %u", gran); + } + return t; +} +#else struct timespec timespec_trunc(struct timespec t, unsigned gran) { /* Avoid division in the common cases 1 ns and 1 s. */ @@ -308,6 +335,7 @@ struct timespec timespec_trunc(struct timespec t, unsigned gran) } return t; } +#endif EXPORT_SYMBOL(timespec_trunc);
/*