1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
From 80f801afe5ab42bdd363eed21faf7ef711404ba7 Mon Sep 17 00:00:00 2001
From: Brian Behlendorf <behlendorf1@llnl.gov>
Date: Sun, 12 Aug 2018 18:22:54 -0400
Subject: [PATCH] Linux 4.18 compat: inode timespec -> timespec64
Commit torvalds/linux@95582b0 changes the inode i_atime, i_mtime,
and i_ctime members form timespec's to timespec64's to make them
2038 safe. As part of this change the current_time() function was
also updated to return the timespec64 type.
Resolve this issue by introducing a new inode_timespec_t type which
is defined to match the timespec type used by the inode. It should
be used when working with inode timestamps to ensure matching types.
The timestruc_t type under Illumos was used in a similar fashion but
was specified to always be a timespec_t. Rather than incorrectly
define this type all timespec_t types have been replaced by the new
inode_timespec_t type.
Finally, the kernel and user space 'sys/time.h' headers were aligned
with each other. They define as appropriate for the context several
constants as macros and include static inline implementation of
gethrestime(), gethrestime_sec(), and gethrtime().
Reviewed-by: Chunwei Chen <tuxoko@gmail.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #7643
Backported-by: Richard Yao <ryao@gentoo.org>
---
config/kernel-inode-times.m4 | 25 +++++++++++++++++++++++++
config/spl-build.m4 | 1 +
include/sys/condvar.h | 1 +
include/sys/time.h | 25 +++++++++++++++++++------
include/sys/types.h | 3 ---
include/sys/vnode.h | 6 +++---
6 files changed, 49 insertions(+), 12 deletions(-)
create mode 100644 config/kernel-inode-times.m4
diff --git a/config/kernel-inode-times.m4 b/config/kernel-inode-times.m4
new file mode 100644
index 00000000..3a6acd8b
--- /dev/null
+++ b/config/kernel-inode-times.m4
@@ -0,0 +1,25 @@
+dnl #
+dnl # 4.18 API change
+dnl # i_atime, i_mtime, and i_ctime changed from timespec to timespec64.
+dnl #
+AC_DEFUN([SPL_AC_KERNEL_INODE_TIMES], [
+ AC_MSG_CHECKING([whether inode->i_*time's are timespec64])
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+ SPL_LINUX_TRY_COMPILE([
+ #include <linux/fs.h>
+ ],[
+ struct inode ip;
+ struct timespec ts;
+
+ memset(&ip, 0, sizeof(ip));
+ ts = ip.i_mtime;
+ ],[
+ AC_MSG_RESULT(no)
+ ],[
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_INODE_TIMESPEC64_TIMES, 1,
+ [inode->i_*time's are timespec64])
+ ])
+ EXTRA_KCFLAGS="$tmp_flags"
+])
diff --git a/config/spl-build.m4 b/config/spl-build.m4
index 5c6c02af..0dc5be81 100644
--- a/config/spl-build.m4
+++ b/config/spl-build.m4
@@ -43,6 +43,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
SPL_AC_2ARGS_VFS_GETATTR
SPL_AC_USLEEP_RANGE
SPL_AC_KMEM_CACHE_ALLOCFLAGS
+ SPL_AC_KERNEL_INODE_TIMES
SPL_AC_WAIT_ON_BIT
SPL_AC_INODE_LOCK
SPL_AC_GROUP_INFO_GID
diff --git a/include/sys/condvar.h b/include/sys/condvar.h
index 5fcc9068..ce3149aa 100644
--- a/include/sys/condvar.h
+++ b/include/sys/condvar.h
@@ -31,6 +31,7 @@
#include <sys/kmem.h>
#include <sys/mutex.h>
#include <sys/callo.h>
+#include <sys/time.h>
/*
* The kcondvar_t struct is protected by mutex taken externally before
diff --git a/include/sys/time.h b/include/sys/time.h
index ddda6dea..59557afd 100644
--- a/include/sys/time.h
+++ b/include/sys/time.h
@@ -52,15 +52,28 @@
#define NSEC2SEC(n) ((n) / (NANOSEC / SEC))
#define SEC2NSEC(m) ((hrtime_t)(m) * (NANOSEC / SEC))
+typedef longlong_t hrtime_t;
+typedef struct timespec timespec_t;
+
static const int hz = HZ;
#define TIMESPEC_OVERFLOW(ts) \
((ts)->tv_sec < TIME_MIN || (ts)->tv_sec > TIME_MAX)
+#if defined(HAVE_INODE_TIMESPEC64_TIMES)
+typedef struct timespec64 inode_timespec_t;
+#else
+typedef struct timespec inode_timespec_t;
+#endif
+
static inline void
-gethrestime(timestruc_t *now)
-{
- *now = current_kernel_time();
+gethrestime(inode_timespec_t *ts)
+ {
+#if defined(HAVE_INODE_TIMESPEC64_TIMES)
+ *ts = current_kernel_time64();
+#else
+ *ts = current_kernel_time();
+#endif
}
static inline time_t
@@ -74,9 +87,9 @@ gethrestime_sec(void)
static inline hrtime_t
gethrtime(void)
{
- struct timespec now;
- getrawmonotonic(&now);
- return (((hrtime_t)now.tv_sec * NSEC_PER_SEC) + now.tv_nsec);
+ struct timespec ts;
+ getrawmonotonic(&ts);
+ return (((hrtime_t)ts.tv_sec * NSEC_PER_SEC) + ts.tv_nsec);
}
#endif /* _SPL_TIME_H */
diff --git a/include/sys/types.h b/include/sys/types.h
index 2fe63b73..b9584622 100644
--- a/include/sys/types.h
+++ b/include/sys/types.h
@@ -49,9 +49,6 @@ typedef long long offset_t;
typedef struct task_struct kthread_t;
typedef struct task_struct proc_t;
typedef short pri_t;
-typedef struct timespec timestruc_t; /* definition per SVr4 */
-typedef struct timespec timespec_t;
-typedef longlong_t hrtime_t;
typedef unsigned short ushort_t;
typedef u_longlong_t len_t;
typedef longlong_t diskaddr_t;
diff --git a/include/sys/vnode.h b/include/sys/vnode.h
index 0ed47948..87f12d66 100644
--- a/include/sys/vnode.h
+++ b/include/sys/vnode.h
@@ -129,9 +129,9 @@ typedef struct vattr {
long va_nodeid; /* node # */
uint32_t va_nlink; /* # links */
uint64_t va_size; /* file size */
- struct timespec va_atime; /* last acc */
- struct timespec va_mtime; /* last mod */
- struct timespec va_ctime; /* last chg */
+ inode_timespec_t va_atime; /* last acc */
+ inode_timespec_t va_mtime; /* last mod */
+ inode_timespec_t va_ctime; /* last chg */
dev_t va_rdev; /* dev */
uint64_t va_nblocks; /* space used */
uint32_t va_blksize; /* block size */
|