kdb is the only user of the __current_kernel_time() interface, which is
not y2038 safe and should be removed at some point.
The kdb code also goes to great lengths to print the time in a
human-readable format from 'struct timespec', again using a non-y2038-safe
re-implementation of the generic time_to_tm() code.
Using __current_kernel_time() here is necessary since the regular
accessors that require a sequence lock might hang when called during the
xtime update. However, this is safe in the particular case since kdb is
only interested in the tv_sec field that is updated atomically.
In order to make this y2038-safe, I'm converting the code to the generic
time64_to_tm helper, but that introduces the problem that we have no
interface like __current_kernel_time() that provides a 64-bit timestamp
in a lockless, safe and architecture-independent way. I have multiple
ideas for how to solve that:
- __ktime_get_real_seconds() is lockless, but can return
incorrect results on 32-bit architectures in the special case that
we are in the process of changing the time across the epoch, either
during the timer tick that overflows the seconds in 2038, or while
calling settimeofday.
- ktime_get_real_fast_ns() would work in this context, but does
require a call into the clocksource driver to return a high-resolution
timestamp. This may have undesired side-effects in the debugger,
since we want to limit the interactions with the rest of the kernel.
- Adding a ktime_get_real_fast_seconds() based on tk_fast_mono
plus tkr->base_real without the tk_clock_read() delta. Not sure about
the value of adding yet another interface here.
- Changing the existing ktime_get_real_seconds() to use
tk_fast_mono on 32-bit architectures rather than xtime_sec. I think
this could work, but am not entirely sure if this is an improvement.
I picked the first of those for simplicity here. It's technically
not correct but probably good enough as the time is only used for the
debugging output and the race will likely never be hit in practice.
Another downside is having to move the declaration into a public header
file.
Let me know if anyone has a different preference.
Cc: Andy Shevchenko <andriy.shevchenko(a)linux.intel.com>
Link: https://patchwork.kernel.org/patch/9775309/
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
include/linux/timekeeping.h | 1 +
kernel/debug/kdb/kdb_main.c | 45 +++++---------------------------------
kernel/time/timekeeping_internal.h | 2 --
3 files changed, 6 insertions(+), 42 deletions(-)
diff --git a/include/linux/timekeeping.h b/include/linux/timekeeping.h
index eb98cbdbb323..9b59473556fe 100644
--- a/include/linux/timekeeping.h
+++ b/include/linux/timekeeping.h
@@ -41,6 +41,7 @@ struct timespec64 get_monotonic_coarse64(void);
extern void getrawmonotonic64(struct timespec64 *ts);
extern void ktime_get_ts64(struct timespec64 *ts);
extern time64_t ktime_get_seconds(void);
+extern time64_t __ktime_get_real_seconds(void);
extern time64_t ktime_get_real_seconds(void);
extern int __getnstimeofday64(struct timespec64 *tv);
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index c8146d53ca67..69e70f4021fe 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -2479,41 +2479,6 @@ static int kdb_kill(int argc, const char **argv)
return 0;
}
-struct kdb_tm {
- int tm_sec; /* seconds */
- int tm_min; /* minutes */
- int tm_hour; /* hours */
- int tm_mday; /* day of the month */
- int tm_mon; /* month */
- int tm_year; /* year */
-};
-
-static void kdb_gmtime(struct timespec *tv, struct kdb_tm *tm)
-{
- /* This will work from 1970-2099, 2100 is not a leap year */
- static int mon_day[] = { 31, 29, 31, 30, 31, 30, 31,
- 31, 30, 31, 30, 31 };
- memset(tm, 0, sizeof(*tm));
- tm->tm_sec = tv->tv_sec % (24 * 60 * 60);
- tm->tm_mday = tv->tv_sec / (24 * 60 * 60) +
- (2 * 365 + 1); /* shift base from 1970 to 1968 */
- tm->tm_min = tm->tm_sec / 60 % 60;
- tm->tm_hour = tm->tm_sec / 60 / 60;
- tm->tm_sec = tm->tm_sec % 60;
- tm->tm_year = 68 + 4*(tm->tm_mday / (4*365+1));
- tm->tm_mday %= (4*365+1);
- mon_day[1] = 29;
- while (tm->tm_mday >= mon_day[tm->tm_mon]) {
- tm->tm_mday -= mon_day[tm->tm_mon];
- if (++tm->tm_mon == 12) {
- tm->tm_mon = 0;
- ++tm->tm_year;
- mon_day[1] = 28;
- }
- }
- ++tm->tm_mday;
-}
-
/*
* Most of this code has been lifted from kernel/timer.c::sys_sysinfo().
* I cannot call that code directly from kdb, it has an unconditional
@@ -2539,8 +2504,8 @@ static void kdb_sysinfo(struct sysinfo *val)
*/
static int kdb_summary(int argc, const char **argv)
{
- struct timespec now;
- struct kdb_tm tm;
+ time64_t now;
+ struct tm tm;
struct sysinfo val;
if (argc)
@@ -2554,9 +2519,9 @@ static int kdb_summary(int argc, const char **argv)
kdb_printf("domainname %s\n", init_uts_ns.name.domainname);
kdb_printf("ccversion %s\n", __stringify(CCVERSION));
- now = __current_kernel_time();
- kdb_gmtime(&now, &tm);
- kdb_printf("date %04d-%02d-%02d %02d:%02d:%02d "
+ now = __ktime_get_real_seconds();
+ time64_to_tm(now, 0, &tm);
+ kdb_printf("date %04ld-%02d-%02d %02d:%02d:%02d "
"tz_minuteswest %d\n",
1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec,
diff --git a/kernel/time/timekeeping_internal.h b/kernel/time/timekeeping_internal.h
index 9a18f121f399..58e79485de1b 100644
--- a/kernel/time/timekeeping_internal.h
+++ b/kernel/time/timekeeping_internal.h
@@ -30,6 +30,4 @@ static inline u64 clocksource_delta(u64 now, u64 last, u64 mask)
}
#endif
-extern time64_t __ktime_get_real_seconds(void);
-
#endif /* _TIMEKEEPING_INTERNAL_H */
--
2.9.0
The series is aimed at making input events y2038 safe.
It extends the lifetime of the realtime timestamps in the
events to year 2106.
The series is also a necessary update as glibc is set to provide
64 bit time_t support for 32 bit binaries. glibc plan is detailed
at https://sourceware.org/glibc/wiki/Y2038ProofnessDesign .
The series is a result of discussions with Arnd Bergmann and
Dmitry Torokhov at last Plumbers.
The plan is to deprecate realtime timestamps anyway as they
are not appropriate for these timestamps as noted in the patch
a80b83b7b8 by John Stultz.
The design also updates the format of the input events read/ written
to the device nodes. This breaks 32 bit interface to the input
events at compile time as preferred by the maintainer.
The userspace library changes to libevdev, libuinput and mtdev
will be posted to the respective mailing groups for review.
Changes from v2:
* Updated the design to break 32 bit interfaces at compile time.
Changes from v1:
* Updated changes according to review comments.
* Posted userspace library changes that go along with the series.
Deepa Dinamani (4):
uinput: Add ioctl for using monotonic/ boot times
input: evdev: Replace timeval with timespec64
input: Deprecate real timestamps beyond year 2106
input: serio: Replace timeval by timespec64
drivers/input/evdev.c | 43 +++++++++++++++++++-----------
drivers/input/input-compat.c | 11 ++++----
drivers/input/input-compat.h | 3 ++-
drivers/input/misc/uinput.c | 57 +++++++++++++++++++++++++++++++++++++++-
drivers/input/serio/hil_mlc.c | 37 +++++++++++++-------------
drivers/input/serio/hp_sdc.c | 17 ++++++------
drivers/input/serio/hp_sdc_mlc.c | 10 +++----
include/linux/hil_mlc.h | 6 ++---
include/linux/hp_sdc.h | 6 ++---
include/uapi/linux/input.h | 12 ++++++++-
include/uapi/linux/uinput.h | 3 +++
11 files changed, 143 insertions(+), 62 deletions(-)
base-commit: b0a84f19a5161418d4360cd57603e94ed489915e
--
2.14.1
getnstimeofday() and timespec are deprecated since they can
overflow on 32-bit architectures. This simply changes to the
explicitly typed timespec64 version that doesn't have that
problem.
It would be nice to also convert to monotonic timestamps
and call ktime_get_ts64() rather than ktime_get_real_ts64(),
but that would be a user-visible change.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/s390/block/dasd.c | 10 +++++-----
drivers/s390/block/dasd_int.h | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 0f1ff0813493..f48b3d5082cf 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -758,7 +758,7 @@ static void dasd_profile_end_add_data(struct dasd_profile_info *data,
/* in case of an overflow, reset the whole profile */
if (data->dasd_io_reqs == UINT_MAX) {
memset(data, 0, sizeof(*data));
- getnstimeofday(&data->starttod);
+ ktime_get_real_ts64(&data->starttod);
}
data->dasd_io_reqs++;
data->dasd_io_sects += sectors;
@@ -893,7 +893,7 @@ void dasd_profile_reset(struct dasd_profile *profile)
return;
}
memset(data, 0, sizeof(*data));
- getnstimeofday(&data->starttod);
+ ktime_get_real_ts64(&data->starttod);
spin_unlock_bh(&profile->lock);
}
@@ -910,7 +910,7 @@ int dasd_profile_on(struct dasd_profile *profile)
kfree(data);
return 0;
}
- getnstimeofday(&data->starttod);
+ ktime_get_real_ts64(&data->starttod);
profile->data = data;
spin_unlock_bh(&profile->lock);
return 0;
@@ -994,8 +994,8 @@ static void dasd_stats_array(struct seq_file *m, unsigned int *array)
static void dasd_stats_seq_print(struct seq_file *m,
struct dasd_profile_info *data)
{
- seq_printf(m, "start_time %ld.%09ld\n",
- data->starttod.tv_sec, data->starttod.tv_nsec);
+ seq_printf(m, "start_time %lld.%09ld\n",
+ (s64)data->starttod.tv_sec, data->starttod.tv_nsec);
seq_printf(m, "total_requests %u\n", data->dasd_io_reqs);
seq_printf(m, "total_sectors %u\n", data->dasd_io_sects);
seq_printf(m, "total_pav %u\n", data->dasd_io_alias);
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index b095a23bcc0c..96709b1a7bf8 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -441,7 +441,7 @@ struct dasd_profile_info {
unsigned int dasd_io_nr_req[32]; /* hist. of # of requests in chanq */
/* new data */
- struct timespec starttod; /* time of start or last reset */
+ struct timespec64 starttod; /* time of start or last reset */
unsigned int dasd_io_alias; /* requests using an alias */
unsigned int dasd_io_tpm; /* requests using transport mode */
unsigned int dasd_read_reqs; /* total number of read requests */
--
2.9.0
netxen_collect_minidump() evidently just wants to get a monotonic
timestamp. Using jiffies_to_timespec(jiffies, &ts) is not
appropriate here, since it will overflow after 2^32 jiffies,
which may be as short as 49 days of uptime.
ktime_get_seconds() is the correct interface here.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
index 0a66389c06c2..1cd39c9a0345 100644
--- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c
@@ -2502,12 +2502,10 @@ netxen_collect_minidump(struct netxen_adapter *adapter)
{
int ret = 0;
struct netxen_minidump_template_hdr *hdr;
- struct timespec val;
hdr = (struct netxen_minidump_template_hdr *)
adapter->mdump.md_template;
hdr->driver_capture_mask = adapter->mdump.md_capture_mask;
- jiffies_to_timespec(jiffies, &val);
- hdr->driver_timestamp = (u32) val.tv_sec;
+ hdr->driver_timestamp = ktime_get_seconds();
hdr->driver_info_word2 = adapter->fw_version;
hdr->driver_info_word3 = NXRD32(adapter, CRB_DRIVER_VERSION);
ret = netxen_parse_md_template(adapter);
--
2.9.0
There is no need to go through an intermediate timespec to convert
to ktime_t when we just want a simple multiplication. This gets
rid of one of the few users of jiffies_to_timespec, which I
hope to remove as part of the y2038 cleanup.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/scsi/scsi_debug.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index e4f037f0f38b..df7e9db44d44 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -4085,10 +4085,7 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
ktime_t kt;
if (delta_jiff > 0) {
- struct timespec ts;
-
- jiffies_to_timespec(delta_jiff, &ts);
- kt = ktime_set(ts.tv_sec, ts.tv_nsec);
+ kt = ns_to_ktime((u64)delta_jiff * (NSEC_PER_SEC / HZ));
} else
kt = sdebug_ndelay;
if (NULL == sd_dp) {
--
2.9.0
The memory mapped packet socket data structure in version 1 through 3
all contain 32-bit second values for the packet time stamps, which makes
them suffer from the overflow of time_t in y2038 or y2106 (depending
on whether user space interprets the value as signed or unsigned).
The implementation uses the deprecated getnstimeofday() function.
In order to get rid of that, this changes the code to use
ktime_get_real_ts64() as a replacement, documenting the nature of the
overflow. As long as the user applications treat the timestamps as
unsigned, or only use the difference between timestamps, they are
fine, and changing the timestamps to 64-bit wouldn't require a more
invasive user space API change.
Note: a lot of other APIs suffer from incompatible structures when
time_t gets redefined to 64-bit in 32-bit user space, but this one
does not.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
net/packet/af_packet.c | 27 +++++++++++++++++----------
1 file changed, 17 insertions(+), 10 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 737092ca9b4e..7432c6699818 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -439,17 +439,17 @@ static int __packet_get_status(struct packet_sock *po, void *frame)
}
}
-static __u32 tpacket_get_timestamp(struct sk_buff *skb, struct timespec *ts,
+static __u32 tpacket_get_timestamp(struct sk_buff *skb, struct timespec64 *ts,
unsigned int flags)
{
struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
if (shhwtstamps &&
(flags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
- ktime_to_timespec_cond(shhwtstamps->hwtstamp, ts))
+ ktime_to_timespec64_cond(shhwtstamps->hwtstamp, ts))
return TP_STATUS_TS_RAW_HARDWARE;
- if (ktime_to_timespec_cond(skb->tstamp, ts))
+ if (ktime_to_timespec64_cond(skb->tstamp, ts))
return TP_STATUS_TS_SOFTWARE;
return 0;
@@ -459,13 +459,20 @@ static __u32 __packet_set_timestamp(struct packet_sock *po, void *frame,
struct sk_buff *skb)
{
union tpacket_uhdr h;
- struct timespec ts;
+ struct timespec64 ts;
__u32 ts_status;
if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp)))
return 0;
h.raw = frame;
+ /*
+ * versions 1 through 3 overflow the timestamps in y2106, since they
+ * all store the seconds in a 32-bit unsigned integer.
+ * If we create a version 4, that should have a 64-bit timestamp,
+ * either 64-bit seconds + 32-bit nanoseconds, or just 64-bit
+ * nanoseconds.
+ */
switch (po->tp_version) {
case TPACKET_V1:
h.h1->tp_sec = ts.tv_sec;
@@ -805,8 +812,8 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1,
* It shouldn't really happen as we don't close empty
* blocks. See prb_retire_rx_blk_timer_expired().
*/
- struct timespec ts;
- getnstimeofday(&ts);
+ struct timespec64 ts;
+ ktime_get_real_ts64(&ts);
h1->ts_last_pkt.ts_sec = ts.tv_sec;
h1->ts_last_pkt.ts_nsec = ts.tv_nsec;
}
@@ -836,7 +843,7 @@ static void prb_thaw_queue(struct tpacket_kbdq_core *pkc)
static void prb_open_block(struct tpacket_kbdq_core *pkc1,
struct tpacket_block_desc *pbd1)
{
- struct timespec ts;
+ struct timespec64 ts;
struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1;
smp_rmb();
@@ -849,7 +856,7 @@ static void prb_open_block(struct tpacket_kbdq_core *pkc1,
BLOCK_NUM_PKTS(pbd1) = 0;
BLOCK_LEN(pbd1) = BLK_PLUS_PRIV(pkc1->blk_sizeof_priv);
- getnstimeofday(&ts);
+ ktime_get_real_ts64(&ts);
h1->ts_first_pkt.ts_sec = ts.tv_sec;
h1->ts_first_pkt.ts_nsec = ts.tv_nsec;
@@ -2184,7 +2191,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
unsigned long status = TP_STATUS_USER;
unsigned short macoff, netoff, hdrlen;
struct sk_buff *copy_skb = NULL;
- struct timespec ts;
+ struct timespec64 ts;
__u32 ts_status;
bool is_drop_n_account = false;
bool do_vnet = false;
@@ -2312,7 +2319,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev,
skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp)))
- getnstimeofday(&ts);
+ ktime_get_real_ts64(&ts);
status |= ts_status;
--
2.9.0
Dealing with 'struct timeval' users in the y2038 series is a bit tricky:
We have two definitions of timeval that are visible to user space,
one comes from glibc (or some other C library), the other comes from
linux/time.h. The kernel copy is what we want to be used for a number of
structures defined by the kernel itself, e.g. elf_prstatus (used it core
dumps), sysinfo and rusage (used in system calls). These generally tend
to be used for passing time intervals rather than absolute (epoch-based)
times, so they do not suffer from the y2038 overflow. Some of them
could be changed to use 64-bit timestamps by creating new system calls,
others like the core files cannot easily be changed.
An application using these interfaces likely also uses gettimeofday()
or other interfaces that use absolute times, and pass 'struct timeval'
pointers directly into kernel interfaces, so glibc must redefine their
timeval based on a 64-bit time_t when they introduce their y2038-safe
interfaces.
The only reasonable way forward I see is to remove the 'timeval'
definion from the kernel's uapi headers, and change the interfaces that
we do not want to (or cannot) duplicate for 64-bit times to use a new
__kernel_old_timeval definition instead. This type should be avoided
for all new interfaces (those can use 64-bit nanoseconds, or the 64-bit
version of timespec instead), and should be used with great care when
converting existing interfaces from timeval, to be sure they don't suffer
from the y2038 overflow, and only with consensus for the particular user
that using __kernel_old_timeval is better than moving to a 64-bit based
interface. The structure name is intentionally chosen to not conflict
with user space types, and to be ugly enough to discourage its use.
Note that ioctl based interfaces that pass a bare 'timeval' pointer
cannot change to '__kernel_old_timeval' because the user space source
code refers to 'timeval' instead, and we don't want to modify the user
space sources if possible. However, any application that relies on a
structure to contain an embedded 'timeval' (e.g. by passing a pointer
to the member into a function call that expects a timeval pointer) is
broken when that structure gets converted to __kernel_old_timeval. I
don't see any way around that, and we have to rely on the compiler to
produce a warning or compile failure that will alert users when they
recompile their sources against a new libc.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
include/linux/time32.h | 1 +
include/uapi/linux/time.h | 12 ++++++++++++
kernel/time/time.c | 12 ++++++++++++
3 files changed, 25 insertions(+)
diff --git a/include/linux/time32.h b/include/linux/time32.h
index 100411c979be..378c75d9a83c 100644
--- a/include/linux/time32.h
+++ b/include/linux/time32.h
@@ -205,5 +205,6 @@ static inline s64 timeval_to_ns(const struct timeval *tv)
* Returns the timeval representation of the nsec parameter.
*/
extern struct timeval ns_to_timeval(const s64 nsec);
+extern struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec);
#endif
diff --git a/include/uapi/linux/time.h b/include/uapi/linux/time.h
index 0ad4510884b0..30aa734135ad 100644
--- a/include/uapi/linux/time.h
+++ b/include/uapi/linux/time.h
@@ -50,6 +50,18 @@ struct __kernel_timespec {
#endif
/*
+ * legacy timeval structure, only embedded in structures that
+ * traditionally used 'timeval' to pass time intervals (not absolute
+ * times). Do not add new users. If user space fails to compile
+ * here, this is probably because it is not y2038 safe and needs to
+ * be changed to use another interface.
+ */
+struct __kernel_old_timeval {
+ __kernel_long_t tv_sec; /* seconds */
+ __kernel_long_t tv_usec; /* seconds */
+};
+
+/*
* The IDs of the various system clocks (for POSIX.1b interval timers):
*/
#define CLOCK_REALTIME 0
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 518b56b17147..92002257f083 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -486,6 +486,18 @@ struct timeval ns_to_timeval(const s64 nsec)
}
EXPORT_SYMBOL(ns_to_timeval);
+struct __kernel_old_timeval ns_to_kernel_old_timeval(const s64 nsec)
+{
+ struct timespec64 ts = ns_to_timespec64(nsec);
+ struct __kernel_old_timeval tv;
+
+ tv.tv_sec = ts.tv_sec;
+ tv.tv_usec = (suseconds_t) ts.tv_nsec / 1000;
+
+ return tv;
+}
+EXPORT_SYMBOL(ns_to_kernel_old_timeval);
+
/**
* set_normalized_timespec - set timespec sec and nsec parts and normalize
*
--
2.9.0
getnstimeofday() is deprecated, so I'm converting this to use
ktime_get_real_ts64() as a safe replacement. I considered using
ktime_get_real() instead, but since the algorithm here depends
on the exact timing, I decided to introduce fewer changes
and leave the code that determines the nanoseconds since the
last seconds wrap untouched.
It's not entirely clear to me whether we should also change the
time base to CLOCK_BOOTTIME or CLOCK_TAI. With boottime, we
would be independent of changes due to settimeofday() and only
see the speed adjustment from the upstream clock source, with
the downside of having the signal be at an arbirary offset
from the start of the UTC second signal. With CLOCK_TAI, we
would use the same offset from the UTC second as before and
still suffer from settimeofday() adjustments, but would be
less confused during leap seconds.
Both boottime and tai only offer usable (i.e. avoiding ktime_t
to timespec64 conversion) interfaces for ktime_t though, so
either way, changing it wouldn't take significantly more work.
CLOCK_MONOTONIC could be used with ktime_get_ts64(), but would
lose synchronization across a suspend/resume cycle, which seems
worse.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/pps/generators/pps_gen_parport.c | 40 ++++++++++++++++----------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/drivers/pps/generators/pps_gen_parport.c b/drivers/pps/generators/pps_gen_parport.c
index dcd39fba6ddd..51cfde6afffd 100644
--- a/drivers/pps/generators/pps_gen_parport.c
+++ b/drivers/pps/generators/pps_gen_parport.c
@@ -70,7 +70,7 @@ static long hrtimer_error = SAFETY_INTERVAL;
/* the kernel hrtimer event */
static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
{
- struct timespec expire_time, ts1, ts2, ts3, dts;
+ struct timespec64 expire_time, ts1, ts2, ts3, dts;
struct pps_generator_pp *dev;
struct parport *port;
long lim, delta;
@@ -78,7 +78,7 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
/* We have to disable interrupts here. The idea is to prevent
* other interrupts on the same processor to introduce random
- * lags while polling the clock. getnstimeofday() takes <1us on
+ * lags while polling the clock. ktime_get_real_ts64() takes <1us on
* most machines while other interrupt handlers can take much
* more potentially.
*
@@ -88,22 +88,22 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
local_irq_save(flags);
/* first of all we get the time stamp... */
- getnstimeofday(&ts1);
- expire_time = ktime_to_timespec(hrtimer_get_softexpires(timer));
+ ktime_get_real_ts64(&ts1);
+ expire_time = ktime_to_timespec64(hrtimer_get_softexpires(timer));
dev = container_of(timer, struct pps_generator_pp, timer);
lim = NSEC_PER_SEC - send_delay - dev->port_write_time;
/* check if we are late */
if (expire_time.tv_sec != ts1.tv_sec || ts1.tv_nsec > lim) {
local_irq_restore(flags);
- pr_err("we are late this time %ld.%09ld\n",
- ts1.tv_sec, ts1.tv_nsec);
+ pr_err("we are late this time %lld.%09ld\n",
+ (s64)ts1.tv_sec, ts1.tv_nsec);
goto done;
}
/* busy loop until the time is right for an assert edge */
do {
- getnstimeofday(&ts2);
+ ktime_get_real_ts64(&ts2);
} while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim);
/* set the signal */
@@ -113,25 +113,25 @@ static enum hrtimer_restart hrtimer_event(struct hrtimer *timer)
/* busy loop until the time is right for a clear edge */
lim = NSEC_PER_SEC - dev->port_write_time;
do {
- getnstimeofday(&ts2);
+ ktime_get_real_ts64(&ts2);
} while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim);
/* unset the signal */
port->ops->write_control(port, NO_SIGNAL);
- getnstimeofday(&ts3);
+ ktime_get_real_ts64(&ts3);
local_irq_restore(flags);
/* update calibrated port write time */
- dts = timespec_sub(ts3, ts2);
+ dts = timespec64_sub(ts3, ts2);
dev->port_write_time =
- (dev->port_write_time + timespec_to_ns(&dts)) >> 1;
+ (dev->port_write_time + timespec64_to_ns(&dts)) >> 1;
done:
/* update calibrated hrtimer error */
- dts = timespec_sub(ts1, expire_time);
- delta = timespec_to_ns(&dts);
+ dts = timespec64_sub(ts1, expire_time);
+ delta = timespec64_to_ns(&dts);
/* If the new error value is bigger then the old, use the new
* value, if not then slowly move towards the new value. This
* way it should be safe in bad conditions and efficient in
@@ -161,17 +161,17 @@ static void calibrate_port(struct pps_generator_pp *dev)
long acc = 0;
for (i = 0; i < (1 << PORT_NTESTS_SHIFT); i++) {
- struct timespec a, b;
+ struct timespec64 a, b;
unsigned long irq_flags;
local_irq_save(irq_flags);
- getnstimeofday(&a);
+ ktime_get_real_ts64(&a);
port->ops->write_control(port, NO_SIGNAL);
- getnstimeofday(&b);
+ ktime_get_real_ts64(&b);
local_irq_restore(irq_flags);
- b = timespec_sub(b, a);
- acc += timespec_to_ns(&b);
+ b = timespec64_sub(b, a);
+ acc += timespec64_to_ns(&b);
}
dev->port_write_time = acc >> PORT_NTESTS_SHIFT;
@@ -180,9 +180,9 @@ static void calibrate_port(struct pps_generator_pp *dev)
static inline ktime_t next_intr_time(struct pps_generator_pp *dev)
{
- struct timespec ts;
+ struct timespec64 ts;
- getnstimeofday(&ts);
+ ktime_get_real_ts64(&ts);
return ktime_set(ts.tv_sec +
((ts.tv_nsec > 990 * NSEC_PER_MSEC) ? 1 : 0),
--
2.9.0
The firmware timestamp is an unsigned 32-bit value, but we copy it into
a signed 32-bit variable, so we can theoretically get an overflow in
the calculation when the timestamp is between 2038 and 2106.
This changes the temporary variable to time64_t and changes the deprecated
time_to_tm() over to time64_to_tm() accordingly.
There is still an overflow in y2106, but that is a limitation of the
firmware interface, not a kernel problem.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/firmware/raspberrypi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c
index dd506cd3a5b8..6692888f04cf 100644
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -174,7 +174,7 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
if (ret == 0) {
struct tm tm;
- time_to_tm(packet, 0, &tm);
+ time64_to_tm(packet, 0, &tm);
dev_info(fw->cl.dev,
"Attached to firmware from %04ld-%02d-%02d %02d:%02d\n",
--
2.9.0
struct timespec should no longer be used because of the y2038
overflow problem. This code does not suffer from the overflow,
but it's trivial to change it to use timespec64 without changing
the interface, so let's do that.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/hsi/clients/cmt_speech.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/hsi/clients/cmt_speech.c b/drivers/hsi/clients/cmt_speech.c
index 727f968ac1cb..05b80723d39d 100644
--- a/drivers/hsi/clients/cmt_speech.c
+++ b/drivers/hsi/clients/cmt_speech.c
@@ -451,11 +451,11 @@ static void cs_hsi_read_on_control_complete(struct hsi_msg *msg)
dev_dbg(&hi->cl->device, "Read on control: %08X\n", cmd);
cs_release_cmd(msg);
if (hi->flags & CS_FEAT_TSTAMP_RX_CTRL) {
- struct timespec tspec;
+ struct timespec64 tspec;
struct cs_timestamp *tstamp =
&hi->mmap_cfg->tstamp_rx_ctrl;
- ktime_get_ts(&tspec);
+ ktime_get_ts64(&tspec);
tstamp->tv_sec = (__u32) tspec.tv_sec;
tstamp->tv_nsec = (__u32) tspec.tv_nsec;
--
2.9.0
Once we get a glibc with 64-bit time_t, the LPSETTIMEOUT ioctl stops
working, since the command number and data structure no longer match.
To work around that, this introduces a new command number LPSETTIMEOUT_NEW
that is used whenever the modified user space evaluates the LPSETTIMEOUT
macro.
The trick we use is a bit convoluted but necessary: we cannot check for
any macros set by the C library in linux/lp.h, because this particular
header can be included before including sys/time.h. However, we can assume
that by the time that LPSETTIMEOUT is seen in the code, the definition
for 'timeval' and 'time_t' has been seen as well, so we can use the
sizeof() operator to determine whether we should use the old or the
new definition. We use the old one not only for traditional 32-bit user
space with 32-bit time_t, but also for all 64-bit architectures and x32,
which always use a 64-bit time_t, the new definition will be used only for
32-bit user space with 64-bit time_t, which also requires a newer kernel.
The compat_ioctl() handler now implements both commands, but has to
use a special case for existing x32 binaries. The native ioctl handler
now implements both command numbers on both 32-bit and 64-bit, though
the latter version use the same interpretation for both.
This is based on an earlier patch from Bamvor.
Cc: Bamvor Jian Zhang <bamv2005(a)gmail.com>
Link: http://www.spinics.net/lists/y2038/msg01162.html
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/char/lp.c | 67 +++++++++++++++++++++++++++++++++++++------------
include/uapi/linux/lp.h | 12 ++++++++-
2 files changed, 62 insertions(+), 17 deletions(-)
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 8249762192d5..be14abf70da1 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -659,17 +659,31 @@ static int lp_do_ioctl(unsigned int minor, unsigned int cmd,
return retval;
}
-static int lp_set_timeout(unsigned int minor, struct timeval *par_timeout)
+static int lp_set_timeout(unsigned int minor, s64 tv_sec, long tv_usec)
{
long to_jiffies;
/* Convert to jiffies, place in lp_table */
- if ((par_timeout->tv_sec < 0) ||
- (par_timeout->tv_usec < 0)) {
+ if (tv_sec < 0 || tv_usec < 0)
return -EINVAL;
+
+ /*
+ * we used to not check, so let's not make this fatal,
+ * but deal with user space passing a 32-bit tv_nsec in
+ * a 64-bit field, capping the timeout to 1 second
+ * worth of microseconds, and capping the total at
+ * MAX_JIFFY_OFFSET.
+ */
+ if (tv_usec > 999999)
+ tv_usec = 999999;
+
+ if (tv_sec >= MAX_SEC_IN_JIFFIES - 1) {
+ to_jiffies = MAX_JIFFY_OFFSET;
+ } else {
+ to_jiffies = DIV_ROUND_UP(tv_usec, 1000000/HZ);
+ to_jiffies += tv_sec * (long) HZ;
}
- to_jiffies = DIV_ROUND_UP(par_timeout->tv_usec, 1000000/HZ);
- to_jiffies += par_timeout->tv_sec * (long) HZ;
+
if (to_jiffies <= 0) {
return -EINVAL;
}
@@ -677,23 +691,43 @@ static int lp_set_timeout(unsigned int minor, struct timeval *par_timeout)
return 0;
}
+static int lp_set_timeout32(unsigned int minor, void __user *arg)
+{
+ s32 karg[2];
+
+ if (copy_from_user(karg, arg, sizeof(karg)))
+ return -EFAULT;
+
+ return lp_set_timeout(minor, karg[0], karg[1]);
+}
+
+static int lp_set_timeout64(unsigned int minor, void __user *arg)
+{
+ s64 karg[2];
+
+ if (copy_from_user(karg, arg, sizeof(karg)))
+ return -EFAULT;
+
+ return lp_set_timeout(minor, karg[0], karg[1]);
+}
+
static long lp_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
unsigned int minor;
- struct timeval par_timeout;
int ret;
minor = iminor(file_inode(file));
mutex_lock(&lp_mutex);
switch (cmd) {
- case LPSETTIMEOUT:
- if (copy_from_user(&par_timeout, (void __user *)arg,
- sizeof (struct timeval))) {
- ret = -EFAULT;
+ case LPSETTIMEOUT_OLD:
+ if (BITS_PER_LONG == 32) {
+ ret = lp_set_timeout32(minor, (void __user *)arg);
break;
}
- ret = lp_set_timeout(minor, &par_timeout);
+ /* fallthrough for 64-bit */
+ case LPSETTIMEOUT_NEW:
+ ret = lp_set_timeout64(minor, (void __user *)arg);
break;
default:
ret = lp_do_ioctl(minor, cmd, arg, (void __user *)arg);
@@ -709,18 +743,19 @@ static long lp_compat_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
unsigned int minor;
- struct timeval par_timeout;
int ret;
minor = iminor(file_inode(file));
mutex_lock(&lp_mutex);
switch (cmd) {
- case LPSETTIMEOUT:
- if (compat_get_timeval(&par_timeout, compat_ptr(arg))) {
- ret = -EFAULT;
+ case LPSETTIMEOUT_OLD:
+ if (!COMPAT_USE_64BIT_TIME) {
+ ret = lp_set_timeout32(minor, (void __user *)arg);
break;
}
- ret = lp_set_timeout(minor, &par_timeout);
+ /* fallthrough for x32 mode */
+ case LPSETTIMEOUT_NEW:
+ ret = lp_set_timeout64(minor, (void __user *)arg);
break;
#ifdef LP_STATS
case LPGETSTATS:
diff --git a/include/uapi/linux/lp.h b/include/uapi/linux/lp.h
index dafcfe4e4834..8589a27037d7 100644
--- a/include/uapi/linux/lp.h
+++ b/include/uapi/linux/lp.h
@@ -8,6 +8,8 @@
#ifndef _UAPI_LINUX_LP_H
#define _UAPI_LINUX_LP_H
+#include <linux/types.h>
+#include <linux/ioctl.h>
/*
* Per POSIX guidelines, this module reserves the LP and lp prefixes
@@ -88,7 +90,15 @@
#define LPGETSTATS 0x060d /* get statistics (struct lp_stats) */
#endif
#define LPGETFLAGS 0x060e /* get status flags */
-#define LPSETTIMEOUT 0x060f /* set parport timeout */
+#define LPSETTIMEOUT_OLD 0x060f /* set parport timeout */
+#define LPSETTIMEOUT_NEW \
+ _IOW(0x6, 0xf, __s64[2]) /* set parport timeout */
+#if __BITS_PER_LONG == 64
+#define LPSETTIMEOUT LPSETTIMEOUT_OLD
+#else
+#define LPSETTIMEOUT (sizeof(time_t) > sizeof(__kernel_long_t) ? \
+ LPSETTIMEOUT_NEW : LPSETTIMEOUT_OLD)
+#endif
/* timeout for printk'ing a timeout, in jiffies (100ths of a second).
This is also used for re-checking error conditions if LP_ABORT is
--
2.9.0
The bfa driver is one of the main users of do_gettimeofday(), a function
that I'm trying to remove as part of the y2038 cleanup.
The timestamps are all uses in slightly different ways, so this has turned
into a rather longish series for doing something that should be simple.
The last patch in the series ("scsi: bfa: use 64-bit times in
bfa_aen_entry_s ABI") is one that needs to be reviewed very carefully,
and it can be skipped if the maintainers prefer to leave the 32-bit ABI
unchanged, the rest are hopefully fairly straightforward.
Arnd
Arnd Bergmann (7):
scsi: bfa: use ktime_get_real_ts64 for firmware timestamp
scsi: bfa: use proper time accessor for stats_reset_time
scsi: bfa: improve bfa_ioc_send_enable/disable data
scsi: bfa: document overflow of io_profile_start_time
scsi: bfa: replace bfa_get_log_time() with ktime_get_real_seconds()
scsi: bfa: try to sanitize vendor netlink events
scsi: bfa: use 64-bit times in bfa_aen_entry_s ABI
drivers/scsi/bfa/bfa_cs.h | 6 +++---
drivers/scsi/bfa/bfa_defs_svc.h | 3 ++-
drivers/scsi/bfa/bfa_fcpim.c | 3 ++-
drivers/scsi/bfa/bfa_fcpim.h | 4 ++--
drivers/scsi/bfa/bfa_ioc.c | 8 ++++---
drivers/scsi/bfa/bfa_port.c | 15 +++----------
drivers/scsi/bfa/bfa_port.h | 2 +-
drivers/scsi/bfa/bfa_svc.c | 47 ++++++++++++-----------------------------
drivers/scsi/bfa/bfa_svc.h | 2 +-
drivers/scsi/bfa/bfad_bsg.c | 4 +---
drivers/scsi/bfa/bfad_im.h | 32 +++++++++++++++++++---------
11 files changed, 56 insertions(+), 70 deletions(-)
--
2.9.0
There was a typo in the new version of put_tv32() that caused an unguarded
access of a user space pointer, and failed to return the correct result in
gettimeofday(), wait4(), usleep_thread() and old_adjtimex().
This fixes it to give the correct behavior again.
Cc: stable(a)vger.kernel.org
Fixes: 1cc6c4635e9f ("osf_sys.c: switch handling of timeval32/itimerval32 to copy_{to,from}_user()")
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
v2: fix incorrect changelog description
---
arch/alpha/kernel/osf_sys.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index ce3a675c0c4b..75a5c35a2067 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -964,8 +964,8 @@ static inline long
put_tv32(struct timeval32 __user *o, struct timeval *i)
{
return copy_to_user(o, &(struct timeval32){
- .tv_sec = o->tv_sec,
- .tv_usec = o->tv_usec},
+ .tv_sec = i->tv_sec,
+ .tv_usec = i->tv_usec},
sizeof(struct timeval32));
}
--
2.9.0
There was a typo in the new version of put_tv32() that caused
uninitialized stack data to be written back to user space, rather
than writing the actual timeval for the emulation of
gettimeofday(), wait4(), usleep_thread() and old_adjtimex().
This fixes it to write the correct data again.
Cc: stable(a)vger.kernel.org
Fixes: 1cc6c4635e9f ("osf_sys.c: switch handling of timeval32/itimerval32 to copy_{to,from}_user()")
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
arch/alpha/kernel/osf_sys.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index ce3a675c0c4b..75a5c35a2067 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -964,8 +964,8 @@ static inline long
put_tv32(struct timeval32 __user *o, struct timeval *i)
{
return copy_to_user(o, &(struct timeval32){
- .tv_sec = o->tv_sec,
- .tv_usec = o->tv_usec},
+ .tv_sec = i->tv_sec,
+ .tv_usec = i->tv_usec},
sizeof(struct timeval32));
}
--
2.9.0
There was a meeting at ELCE about the status and development of Y2038-
safe APIs in Linux and GNU libc. This included several developers from
members of CIP, plus Arnd Bergmann, Mark Brown and Albert Aribaud.
Below are my notes from the meeting.
Ben.
## Kernel
Arnd Bergmann started working on Y2038 about 6 years ago, initially
looking at file-systems and VFS. File-systems are mostly ready but VFS
hasn't been switched over yet.
The largest missing piece is the syscall interface. "We know what we
want to do." There was a complete patch set for an older version, but
it has not been completely rebased onto current mainline. On 32-bit
systems about 35 syscalls use 32-bit time, but half of those are
already obsolete. Something like 22 new syscalls will be needed.
Network, sound, media, key management, input have not been dealt with
yet. Patches are available for some of these but they can be invasive
and hard to review. This is a low priority for some subsystem
maintainers.
About 100 device drivers need changes, ranging from an obvious 1 line
change to a week's work.
About 10% of the changes are needed for Y2038 safety on both 32-bit
and 64-bit architectures, the rest only for 32-bit.
Arnd wants to include a kconfig option to disable the 32-bit time
APIs, so that any remaining users are easy to detect.
## GNU libc
Albert Aribaut talked about the status of glibc. It will need to
support both 32-bit `time_t` and 64-bit `time_t` independently of the
kernel. A draft specification for this exists at
<https://sourceware.org/glibc/wiki/Y2038ProofnessDesign>. About 60
APIs are affected, using `time_t` or derived type.
Ideally source can be rebuilt to use 64-bit `time_t` just by
defining the feature macro to enable it.
The implementation is not complete, partly because syscalls haven't
yet been defined.
## Other C libraries
Arnd says some other C libraries will support 64-bit `time_t` but as a
build-time option. I.e. libc and all applications must be built for
either 32-bit or 64-bit `time_t`.
## Application compatibility issues
If Unix timestamps are used in binary file formats or network
protocols, these will need a new version. In some cases switching to
unsigned 32-bit values is easy and will work for long enough.
If `time_t` is used in library APIs then an ABI change is required.
cppcheck(?) can find instances of this.
Some libraries may use their own time types, so changing `time_t`
won't be an ABI change but they will need to be updated anyway.
Printing a value of type `time_t` with `printf()` and similar
functions requires casting as there's no format specifier for it. It
will be necessary to cast to `long long`, whereas previously `long`
would work.
The sparse static checker is supposed to be able to check for
truncating conversions of `time_t`.
## Ongoing work in kernel and glibc
A few people are working part time on this. Kernel patches are 60%
done after 5 years, GNU libc about 75% (but only some of those changes
have been applied). More people may be needed to speed this up and get
it finished.
The kernel side is coordinated through the y2038 mailing list:
<https://lists.linaro.org/mailman/listinfo/y2038>. Patches are all
sent to this mailing list. There is currently no git tree collecting
them all.
Help is wanted to:
* Update device drivers
* Review sound patches
* Collect patches into single git tree
The glibc side is coordinated through the general development mailing
list: <https://www.gnu.org/software/libc/involved.html>,
<https://sourceware.org/ml/libc-alpha/>.
--
Ben Hutchings
Software Developer, Codethink Ltd.
The code to check the adjtimex() or clock_adjtime() arguments is spread
out across multiple files for presumably only historic reasons. As a
preparatation for a rework to get rid of the use of 'struct timeval'
and 'struct timespec' in there, this moves all the portions into
kernel/time/timekeeping.c and marks them as 'static'.
The warp_clock() function here is not as closely related as the others,
but I feel it still makes sense to move it here in order to consolidate
all callers of timekeeping_inject_offset().
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
include/linux/time.h | 26 ----------
kernel/time/ntp.c | 61 ----------------------
kernel/time/ntp_internal.h | 1 -
kernel/time/time.c | 36 +------------
kernel/time/timekeeping.c | 123 ++++++++++++++++++++++++++++++++++++++++++++-
kernel/time/timekeeping.h | 2 +-
6 files changed, 123 insertions(+), 126 deletions(-)
diff --git a/include/linux/time.h b/include/linux/time.h
index 9bc1f945777c..c0fbad08448f 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -134,32 +134,6 @@ static inline bool timeval_valid(const struct timeval *tv)
extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
-/*
- * Validates if a timespec/timeval used to inject a time offset is valid.
- * Offsets can be postive or negative. The value of the timeval/timespec
- * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must
- * always be non-negative.
- */
-static inline bool timeval_inject_offset_valid(const struct timeval *tv)
-{
- /* We don't check the tv_sec as it can be positive or negative */
-
- /* Can't have more microseconds then a second */
- if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
- return false;
- return true;
-}
-
-static inline bool timespec_inject_offset_valid(const struct timespec *ts)
-{
- /* We don't check the tv_sec as it can be positive or negative */
-
- /* Can't have more nanoseconds then a second */
- if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC)
- return false;
- return true;
-}
-
/* Some architectures do not supply their own clocksource.
* This is mainly the case in architectures that get their
* inter-tick times by reading the counter on their interval
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index edf19cc53140..a5e702669d84 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -653,67 +653,6 @@ static inline void process_adjtimex_modes(struct timex *txc,
}
-
-/**
- * ntp_validate_timex - Ensures the timex is ok for use in do_adjtimex
- */
-int ntp_validate_timex(struct timex *txc)
-{
- if (txc->modes & ADJ_ADJTIME) {
- /* singleshot must not be used with any other mode bits */
- if (!(txc->modes & ADJ_OFFSET_SINGLESHOT))
- return -EINVAL;
- if (!(txc->modes & ADJ_OFFSET_READONLY) &&
- !capable(CAP_SYS_TIME))
- return -EPERM;
- } else {
- /* In order to modify anything, you gotta be super-user! */
- if (txc->modes && !capable(CAP_SYS_TIME))
- return -EPERM;
- /*
- * if the quartz is off by more than 10% then
- * something is VERY wrong!
- */
- if (txc->modes & ADJ_TICK &&
- (txc->tick < 900000/USER_HZ ||
- txc->tick > 1100000/USER_HZ))
- return -EINVAL;
- }
-
- if (txc->modes & ADJ_SETOFFSET) {
- /* In order to inject time, you gotta be super-user! */
- if (!capable(CAP_SYS_TIME))
- return -EPERM;
-
- if (txc->modes & ADJ_NANO) {
- struct timespec ts;
-
- ts.tv_sec = txc->time.tv_sec;
- ts.tv_nsec = txc->time.tv_usec;
- if (!timespec_inject_offset_valid(&ts))
- return -EINVAL;
-
- } else {
- if (!timeval_inject_offset_valid(&txc->time))
- return -EINVAL;
- }
- }
-
- /*
- * Check for potential multiplication overflows that can
- * only happen on 64-bit systems:
- */
- if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) {
- if (LLONG_MIN / PPM_SCALE > txc->freq)
- return -EINVAL;
- if (LLONG_MAX / PPM_SCALE < txc->freq)
- return -EINVAL;
- }
-
- return 0;
-}
-
-
/*
* adjtimex mainly allows reading (and writing, if superuser) of
* kernel time-keeping variables. used by xntpd.
diff --git a/kernel/time/ntp_internal.h b/kernel/time/ntp_internal.h
index d8a7c11fa71a..74b52cd48209 100644
--- a/kernel/time/ntp_internal.h
+++ b/kernel/time/ntp_internal.h
@@ -7,7 +7,6 @@ extern void ntp_clear(void);
extern u64 ntp_tick_length(void);
extern ktime_t ntp_get_next_leap(void);
extern int second_overflow(time64_t secs);
-extern int ntp_validate_timex(struct timex *);
extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *);
extern void __hardpps(const struct timespec64 *, const struct timespec64 *);
#endif /* _LINUX_NTP_INTERNAL_H */
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 44a8c1402133..04684e294f00 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -158,40 +158,6 @@ SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,
}
/*
- * Indicates if there is an offset between the system clock and the hardware
- * clock/persistent clock/rtc.
- */
-int persistent_clock_is_local;
-
-/*
- * Adjust the time obtained from the CMOS to be UTC time instead of
- * local time.
- *
- * This is ugly, but preferable to the alternatives. Otherwise we
- * would either need to write a program to do it in /etc/rc (and risk
- * confusion if the program gets run more than once; it would also be
- * hard to make the program warp the clock precisely n hours) or
- * compile in the timezone information into the kernel. Bad, bad....
- *
- * - TYT, 1992-01-01
- *
- * The best thing to do is to keep the CMOS clock in universal time (UTC)
- * as real UNIX machines always do it. This avoids all headaches about
- * daylight saving times and warping kernel clocks.
- */
-static inline void warp_clock(void)
-{
- if (sys_tz.tz_minuteswest != 0) {
- struct timespec adjust;
-
- persistent_clock_is_local = 1;
- adjust.tv_sec = sys_tz.tz_minuteswest * 60;
- adjust.tv_nsec = 0;
- timekeeping_inject_offset(&adjust);
- }
-}
-
-/*
* In case for some reason the CMOS clock has not already been running
* in UTC, but in some local time: The first time we set the timezone,
* we will warp the clock so that it is ticking UTC time instead of
@@ -224,7 +190,7 @@ int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz
if (firsttime) {
firsttime = 0;
if (!tv)
- warp_clock();
+ timekeeping_warp_clock();
}
}
if (tv)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8af77006e937..679dbfbea419 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1300,13 +1300,39 @@ int do_settimeofday64(const struct timespec64 *ts)
}
EXPORT_SYMBOL(do_settimeofday64);
+/*
+ * Validates if a timespec/timeval used to inject a time offset is valid.
+ * Offsets can be postive or negative. The value of the timeval/timespec
+ * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must
+ * always be non-negative.
+ */
+static inline bool timeval_inject_offset_valid(const struct timeval *tv)
+{
+ /* We don't check the tv_sec as it can be positive or negative */
+
+ /* Can't have more microseconds then a second */
+ if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
+ return false;
+ return true;
+}
+
+static inline bool timespec_inject_offset_valid(const struct timespec *ts)
+{
+ /* We don't check the tv_sec as it can be positive or negative */
+
+ /* Can't have more nanoseconds then a second */
+ if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC)
+ return false;
+ return true;
+}
+
/**
* timekeeping_inject_offset - Adds or subtracts from the current time.
* @tv: pointer to the timespec variable containing the offset
*
* Adds or subtracts an offset value from the current time.
*/
-int timekeeping_inject_offset(struct timespec *ts)
+static int timekeeping_inject_offset(struct timespec *ts)
{
struct timekeeper *tk = &tk_core.timekeeper;
unsigned long flags;
@@ -1345,7 +1371,40 @@ int timekeeping_inject_offset(struct timespec *ts)
return ret;
}
-EXPORT_SYMBOL(timekeeping_inject_offset);
+
+/*
+ * Indicates if there is an offset between the system clock and the hardware
+ * clock/persistent clock/rtc.
+ */
+int persistent_clock_is_local;
+
+/*
+ * Adjust the time obtained from the CMOS to be UTC time instead of
+ * local time.
+ *
+ * This is ugly, but preferable to the alternatives. Otherwise we
+ * would either need to write a program to do it in /etc/rc (and risk
+ * confusion if the program gets run more than once; it would also be
+ * hard to make the program warp the clock precisely n hours) or
+ * compile in the timezone information into the kernel. Bad, bad....
+ *
+ * - TYT, 1992-01-01
+ *
+ * The best thing to do is to keep the CMOS clock in universal time (UTC)
+ * as real UNIX machines always do it. This avoids all headaches about
+ * daylight saving times and warping kernel clocks.
+ */
+void timekeeping_warp_clock(void)
+{
+ if (sys_tz.tz_minuteswest != 0) {
+ struct timespec adjust;
+
+ persistent_clock_is_local = 1;
+ adjust.tv_sec = sys_tz.tz_minuteswest * 60;
+ adjust.tv_nsec = 0;
+ timekeeping_inject_offset(&adjust);
+ }
+}
/**
* __timekeeping_set_tai_offset - Sets the TAI offset from UTC and monotonic
@@ -2290,6 +2349,66 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
}
/**
+ * ntp_validate_timex - Ensures the timex is ok for use in do_adjtimex
+ */
+static int ntp_validate_timex(struct timex *txc)
+{
+ if (txc->modes & ADJ_ADJTIME) {
+ /* singleshot must not be used with any other mode bits */
+ if (!(txc->modes & ADJ_OFFSET_SINGLESHOT))
+ return -EINVAL;
+ if (!(txc->modes & ADJ_OFFSET_READONLY) &&
+ !capable(CAP_SYS_TIME))
+ return -EPERM;
+ } else {
+ /* In order to modify anything, you gotta be super-user! */
+ if (txc->modes && !capable(CAP_SYS_TIME))
+ return -EPERM;
+ /*
+ * if the quartz is off by more than 10% then
+ * something is VERY wrong!
+ */
+ if (txc->modes & ADJ_TICK &&
+ (txc->tick < 900000/USER_HZ ||
+ txc->tick > 1100000/USER_HZ))
+ return -EINVAL;
+ }
+
+ if (txc->modes & ADJ_SETOFFSET) {
+ /* In order to inject time, you gotta be super-user! */
+ if (!capable(CAP_SYS_TIME))
+ return -EPERM;
+
+ if (txc->modes & ADJ_NANO) {
+ struct timespec ts;
+
+ ts.tv_sec = txc->time.tv_sec;
+ ts.tv_nsec = txc->time.tv_usec;
+ if (!timespec_inject_offset_valid(&ts))
+ return -EINVAL;
+
+ } else {
+ if (!timeval_inject_offset_valid(&txc->time))
+ return -EINVAL;
+ }
+ }
+
+ /*
+ * Check for potential multiplication overflows that can
+ * only happen on 64-bit systems:
+ */
+ if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) {
+ if (LLONG_MIN / PPM_SCALE > txc->freq)
+ return -EINVAL;
+ if (LLONG_MAX / PPM_SCALE < txc->freq)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+/**
* do_adjtimex() - Accessor function to NTP __do_adjtimex function
*/
int do_adjtimex(struct timex *txc)
diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h
index d0914676d4c5..44aec7893cdd 100644
--- a/kernel/time/timekeeping.h
+++ b/kernel/time/timekeeping.h
@@ -10,7 +10,7 @@ extern ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq,
extern int timekeeping_valid_for_hres(void);
extern u64 timekeeping_max_deferment(void);
-extern int timekeeping_inject_offset(struct timespec *ts);
+extern void timekeeping_warp_clock(void);
extern int timekeeping_suspend(void);
extern void timekeeping_resume(void);
--
2.9.0
We want to remove uses of do_gettimeofday() from the kernel since the
resulting timeval structure overflows in 2038. This is not a problem for
this particular use, but do_gettimeofday() is also not an appropriate
method for measuring time intervals, since it requires a conversion into
microseconds and is complicated to work with.
ktime_get() is a better replacement, as it works with the monontonic
kernel timebase and requires a minimum of computation.
I'm slightly changing the output from microseconds to nanoseconds here,
to avoid introducing a new division operation. This should be fine
since the value is only used for debugging.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/gpu/drm/via/via_drv.h | 4 ++--
drivers/gpu/drm/via/via_irq.c | 21 +++++++--------------
2 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h
index 9873942ca8f4..6d1ae834484c 100644
--- a/drivers/gpu/drm/via/via_drv.h
+++ b/drivers/gpu/drm/via/via_drv.h
@@ -74,9 +74,9 @@ typedef struct drm_via_private {
volatile uint32_t *last_pause_ptr;
volatile uint32_t *hw_addr_ptr;
drm_via_ring_buffer_t ring;
- struct timeval last_vblank;
+ ktime_t last_vblank;
int last_vblank_valid;
- unsigned usec_per_vblank;
+ ktime_t nsec_per_vblank;
atomic_t vbl_received;
drm_via_state_t hc_state;
char pci_buf[VIA_PCI_BUF_SIZE];
diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c
index ea8172c747a2..24e71578af4d 100644
--- a/drivers/gpu/drm/via/via_irq.c
+++ b/drivers/gpu/drm/via/via_irq.c
@@ -88,13 +88,6 @@ static int via_num_unichrome = ARRAY_SIZE(via_unichrome_irqs);
static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1};
-static unsigned time_diff(struct timeval *now, struct timeval *then)
-{
- return (now->tv_usec >= then->tv_usec) ?
- now->tv_usec - then->tv_usec :
- 1000000 - (then->tv_usec - now->tv_usec);
-}
-
u32 via_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
{
drm_via_private_t *dev_priv = dev->dev_private;
@@ -111,7 +104,7 @@ irqreturn_t via_driver_irq_handler(int irq, void *arg)
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
u32 status;
int handled = 0;
- struct timeval cur_vblank;
+ ktime_t cur_vblank;
drm_via_irq_t *cur_irq = dev_priv->via_irqs;
int i;
@@ -119,18 +112,18 @@ irqreturn_t via_driver_irq_handler(int irq, void *arg)
if (status & VIA_IRQ_VBLANK_PENDING) {
atomic_inc(&dev_priv->vbl_received);
if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) {
- do_gettimeofday(&cur_vblank);
+ cur_vblank = ktime_get();
if (dev_priv->last_vblank_valid) {
- dev_priv->usec_per_vblank =
- time_diff(&cur_vblank,
- &dev_priv->last_vblank) >> 4;
+ dev_priv->nsec_per_vblank =
+ ktime_sub(cur_vblank,
+ dev_priv->last_vblank) >> 4;
}
dev_priv->last_vblank = cur_vblank;
dev_priv->last_vblank_valid = 1;
}
if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) {
- DRM_DEBUG("US per vblank is: %u\n",
- dev_priv->usec_per_vblank);
+ DRM_DEBUG("nsec per vblank is: %llu\n",
+ ktime_to_ns(dev_priv->nsec_per_vblank));
}
drm_handle_vblank(dev, 0);
handled = 1;
--
2.9.0
isofs uses a 'char' variable to load the number of years since
1900 for an inode timestamp. On architectures that use a signed
char type by default, this results in an invalid date for
anything beyond 2027.
This changes the function argument to a 'u8' array, which
is defined the same way on all architectures, and unambiguously
lets us use years until 2155.
This should be backported to all kernels that might still be
in use by that date.
Cc: stable(a)vger.kernel.org
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
v2: change function prototype instead of adding a cast
---
fs/isofs/isofs.h | 2 +-
fs/isofs/rock.h | 2 +-
fs/isofs/util.c | 4 ++--
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h
index 133a456b0425..bd4047585431 100644
--- a/fs/isofs/isofs.h
+++ b/fs/isofs/isofs.h
@@ -106,7 +106,7 @@ static inline unsigned int isonum_733(char *p)
/* Ignore bigendian datum due to broken mastering programs */
return get_unaligned_le32(p);
}
-extern int iso_date(char *, int);
+extern int iso_date(u8 *, int);
struct inode; /* To make gcc happy */
diff --git a/fs/isofs/rock.h b/fs/isofs/rock.h
index ed09e2b08637..f835976ce033 100644
--- a/fs/isofs/rock.h
+++ b/fs/isofs/rock.h
@@ -65,7 +65,7 @@ struct RR_PL_s {
};
struct stamp {
- char time[7];
+ __u8 time[7]; /* actually 6 unsigned, 1 signed */
} __attribute__ ((packed));
struct RR_TF_s {
diff --git a/fs/isofs/util.c b/fs/isofs/util.c
index 005a15cfd30a..335f62db0b53 100644
--- a/fs/isofs/util.c
+++ b/fs/isofs/util.c
@@ -15,12 +15,12 @@
* to GMT. Thus we should always be correct.
*/
-int iso_date(char * p, int flag)
+int iso_date(u8 *p, int flag)
{
int year, month, day, hour, minute, second, tz;
int crtime;
- year = p[0];
+ year = (int)(u8)p[0];
month = p[1];
day = p[2];
hour = p[3];
--
2.9.0
do_gettimeofday() is deprecated and we should generally use time64_t
based functions instead.
In case of nfsd, all three users of nfssvc_boot only use the initial
time as a unique token, and are not affected by it overflowing, so they
are not affected by the y2038 overflow.
This converts the structure to timespec64 anyway and adds comments
to all uses, to document that we have thought about it and avoid
having to look at it again.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
fs/nfsd/netns.h | 2 +-
fs/nfsd/nfs3xdr.c | 10 ++++++----
fs/nfsd/nfs4proc.c | 5 +++--
fs/nfsd/nfssvc.c | 2 +-
4 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h
index 3714231a9d0f..1c91391f4805 100644
--- a/fs/nfsd/netns.h
+++ b/fs/nfsd/netns.h
@@ -107,7 +107,7 @@ struct nfsd_net {
bool lockd_up;
/* Time of server startup */
- struct timeval nfssvc_boot;
+ struct timespec64 nfssvc_boot;
/*
* Max number of connections this nfsd container will allow. Defaults
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index bf444b664011..3579e0ae1131 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -747,8 +747,9 @@ nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p)
if (resp->status == 0) {
*p++ = htonl(resp->count);
*p++ = htonl(resp->committed);
- *p++ = htonl(nn->nfssvc_boot.tv_sec);
- *p++ = htonl(nn->nfssvc_boot.tv_usec);
+ /* unique identifier, y2038 overflow can be ignored */
+ *p++ = htonl((u32)nn->nfssvc_boot.tv_sec);
+ *p++ = htonl(nn->nfssvc_boot.tv_nsec);
}
return xdr_ressize_check(rqstp, p);
}
@@ -1118,8 +1119,9 @@ nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p)
p = encode_wcc_data(rqstp, p, &resp->fh);
/* Write verifier */
if (resp->status == 0) {
- *p++ = htonl(nn->nfssvc_boot.tv_sec);
- *p++ = htonl(nn->nfssvc_boot.tv_usec);
+ /* unique identifier, y2038 overflow can be ignored */
+ *p++ = htonl((u32)nn->nfssvc_boot.tv_sec);
+ *p++ = htonl(nn->nfssvc_boot.tv_nsec);
}
return xdr_ressize_check(rqstp, p);
}
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 7896f841482e..008ea0b627d0 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -564,10 +564,11 @@ static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net)
/*
* This is opaque to client, so no need to byte-swap. Use
- * __force to keep sparse happy
+ * __force to keep sparse happy. y2038 time_t overflow is
+ * irrelevant in this usage.
*/
verf[0] = (__force __be32)nn->nfssvc_boot.tv_sec;
- verf[1] = (__force __be32)nn->nfssvc_boot.tv_usec;
+ verf[1] = (__force __be32)nn->nfssvc_boot.tv_nsec;
memcpy(verifier->data, verf, sizeof(verifier->data));
}
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 6bbc717f40f2..28ff3e078af6 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -516,7 +516,7 @@ int nfsd_create_serv(struct net *net)
register_inet6addr_notifier(&nfsd_inet6addr_notifier);
#endif
}
- do_gettimeofday(&nn->nfssvc_boot); /* record boot time */
+ ktime_get_real_ts64(&nn->nfssvc_boot); /* record boot time */
return 0;
}
--
2.9.0
The dmar driver can be used on both x86 and itanium, but only
the former uses the x86_init structure. The only reference to
that structure is enclosed in an #ifdef, but the header inclusion
I added is not.
Adds another #ifdef to get ia64 to build again.
Fixes: 0f5a0f4f062c ("x86: don't include asm/x86_init.h in asm/setup.h")
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
The broken commit is in x86/timers, please add this one on top
---
drivers/iommu/dmar.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index e9304d6247e1..ed1dd13e03ac 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -41,7 +41,9 @@
#include <linux/iommu.h>
#include <asm/irq_remapping.h>
#include <asm/iommu_table.h>
+#ifdef CONFIG_X86
#include <asm/x86_init.h>
+#endif
#include "irq_remapping.h"
--
2.9.0
This is a preparation to allow using 'struct timespec64' in the
asm/x86_init.h. Unfortunately, we can't use a forward declaration
for timespec64 since it is defined as a macro on 64-bit architectures,
and including linux/time64.h breaks compilation of arch/x86/boot/,
which runs in realmode and can't use many of the regular kernel
headers.
As a workaround, I stop including asm/x86_init.h. This works fine
for the realmode boot code since it does not require any of the
x86_init.h contents, and setup.h doesn't either. However, a couple
of other files that do need x86_init.h used to rely on it being
included indirectly, so I have to put an explicit include in there
now.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
arch/x86/include/asm/setup.h | 1 -
arch/x86/kernel/platform-quirks.c | 1 +
arch/x86/platform/ce4100/ce4100.c | 1 +
arch/x86/platform/intel-mid/intel-mid.c | 1 +
arch/x86/platform/olpc/olpc.c | 1 +
drivers/iommu/dmar.c | 1 +
6 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index a65cf544686a..deed84119a22 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -27,7 +27,6 @@
#ifndef __ASSEMBLY__
#include <asm/bootparam.h>
-#include <asm/x86_init.h>
extern u64 relocated_ramdisk;
diff --git a/arch/x86/kernel/platform-quirks.c b/arch/x86/kernel/platform-quirks.c
index 502a77d0adb0..d900c7b176f0 100644
--- a/arch/x86/kernel/platform-quirks.c
+++ b/arch/x86/kernel/platform-quirks.c
@@ -3,6 +3,7 @@
#include <asm/setup.h>
#include <asm/bios_ebda.h>
+#include <asm/x86_init.h>
void __init x86_early_init_platform_quirks(void)
{
diff --git a/arch/x86/platform/ce4100/ce4100.c b/arch/x86/platform/ce4100/ce4100.c
index ce4b06733c09..885196300927 100644
--- a/arch/x86/platform/ce4100/ce4100.c
+++ b/arch/x86/platform/ce4100/ce4100.c
@@ -22,6 +22,7 @@
#include <asm/io.h>
#include <asm/io_apic.h>
#include <asm/emergency-restart.h>
+#include <asm/x86_init.h>
/*
* The CE4100 platform has an internal 8051 Microcontroller which is
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c
index 86676cec99a1..c6322263610a 100644
--- a/arch/x86/platform/intel-mid/intel-mid.c
+++ b/arch/x86/platform/intel-mid/intel-mid.c
@@ -35,6 +35,7 @@
#include <asm/intel_scu_ipc.h>
#include <asm/apb_timer.h>
#include <asm/reboot.h>
+#include <asm/x86_init.h>
#include "intel_mid_weak_decls.h"
diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c
index 7c3077e58fa0..11a54f386911 100644
--- a/arch/x86/platform/olpc/olpc.c
+++ b/arch/x86/platform/olpc/olpc.c
@@ -26,6 +26,7 @@
#include <asm/setup.h>
#include <asm/olpc.h>
#include <asm/olpc_ofw.h>
+#include <asm/x86_init.h>
struct olpc_platform_t olpc_platform_info;
EXPORT_SYMBOL_GPL(olpc_platform_info);
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 1ea7cd537873..e9304d6247e1 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -41,6 +41,7 @@
#include <linux/iommu.h>
#include <asm/irq_remapping.h>
#include <asm/iommu_table.h>
+#include <asm/x86_init.h>
#include "irq_remapping.h"
--
2.9.0
The hypercall was added using a struct timespec based implementation,
but we should not use timespec in new code.
This changes it to timespec64. There is no functional change
here since the implementation is only used in 64-bit kernels
that use the same definition for timespec and timespec64.
Fixes: 55dd00a73a51 ("KVM: x86: add KVM_HC_CLOCK_PAIRING hypercall")
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
arch/x86/kvm/x86.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 03869eb7fcd6..4b81a373a7ec 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1632,7 +1632,7 @@ static int do_monotonic_boot(s64 *t, u64 *cycle_now)
return mode;
}
-static int do_realtime(struct timespec *ts, u64 *cycle_now)
+static int do_realtime(struct timespec64 *ts, u64 *cycle_now)
{
struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
unsigned long seq;
@@ -1665,7 +1665,7 @@ static bool kvm_get_time_and_clockread(s64 *kernel_ns, u64 *cycle_now)
}
/* returns true if host is using tsc clocksource */
-static bool kvm_get_walltime_and_clockread(struct timespec *ts,
+static bool kvm_get_walltime_and_clockread(struct timespec64 *ts,
u64 *cycle_now)
{
/* checked again under seqlock below */
@@ -6210,7 +6210,7 @@ static int kvm_pv_clock_pairing(struct kvm_vcpu *vcpu, gpa_t paddr,
unsigned long clock_type)
{
struct kvm_clock_pairing clock_pairing;
- struct timespec ts;
+ struct timespec64 ts;
u64 cycle;
int ret;
--
2.9.0
Hi folks,
As discussed with Arnd, I ran a BoF session about Y2038 at DebConf
last month, giving an overview of the problem and starting some
discussion. Here's the write-up, and there's a link to the video of
the session below.
----- Forwarded message from Steve McIntyre <steve(a)einval.com> -----
From: Steve McIntyre <steve(a)einval.com>
To: debian-devel(a)lists.debian.org
Date: Sat, 2 Sep 2017 00:58:54 +0100
Subject: Summary of the 2038 BoF at DC17
Hi folks,
As promised, here's a quick summary of what was discussed at the 2038
BoF session I ran in Montréal.
Thanks to the awesome efforts of our video team, the session is
already online [1]. I've taken a copy of the Gobby notes too,
alongside my small set of slides for the session. [2]
We had a conversation about the coming End of The World, the 2038 problem.
What's the problem?
-------------------
UNIX time_t is 31 bits (signed), counting seconds since Jan 1,
1970. It's going to wrap. It's used *everywhere* in UNIX-based
systems. Imagine the effects of Y2K, but worse.
What could go wrong?
--------------------
All kinds if disasters! We're not trying to exaggerate this *too*
much, but it's likely to be a significat problem. For most of the
things that needed fixing for Y2K, they were on big obvious computers,
typically mainframes. Y2K was solved by people doing a lot of work; to
many outside of the direct work, it almost came to be an anti-climax.
In 20 years' time, the systems that we will be trying to fix for the
2038 problem are likely to be much harder to track. They're typically
not even going to look like computers - look at the IoT devices
available today, and extrapolate. Imagine all kinds of devices with
embedded computers that we won't know how to talk to, let alone verify
their software.
When does it happen?
--------------------
Pick the example from the date(1) man page:
$ date --date=@$((2**31-1))
Tue 19 Jan 03:14:07 GMT 2038
At that point, lots of software will believe it's suddenly 1902...
What needs doing?
-----------------
Lots of fixes are going to be needed all the way up the stack.
Data formats are often not 2038-safe. The filesystems in use today are
typically not ready. Modern ext4 *is*, using 34 bits for seconds and
30 bits for nanoseconds. btrfs uses a 64-bit second counter. But data
on older filesystems will need to be migrated.
There are many places in the Linux kernel where 32-bit time_t is
used. This is being worked on, and so are the interfaces that expose
32-bit time_t.
Lots of libraries use 32-bit time_t, even in places where it might not
be obvious. Finally, applications will need fixing.
Linux kernel
------------
There's project underway to fix Linux time-handling, led by Deepa
Dinamani and Arnd Bergmann. There's a web site describing the efforts
at https://kernelnewbies.org/y2038 and a mailing list at
y2038(a)lists.linaro.org. They are using the y2038 project as a good way
to get new developers involved in the Linux kernel, and those people
are working on fixing things in a number of areas: adding core 64-bit
time support, fixing drivers, and adding new versions of interfaces
(syscalls, ioctls).
We can't just replace all the existing interfaces with 64-bit
versions, of course - we need to continue suporting the existing
interfaces for existing code.
There are lots of tasks here where people can join in and help.
Glibc
-----
Glibc is the next obvious piece of the puzzle - almost everything
depends on it. Planning is ongoing at
https://sourceware.org/glibc/wiki/Y2038ProofnessDesign
to provide 64-bit time_t support without breaking the existing 32-bit
code. There's more coverage in LWN at
https://lwn.net/Articles/664800/
The glibc developers are obviously going to need the kernel to provide
64-bit interfaces to make much progress. Again, there's lot of work to
be done here and help will be welcome.
Elsewhere?
----------
If you're working further up the stack, it's hard to make many fixes
when the lower levels are not yet done.
Kernels other than Linux are also going to have the same problems to
solve - not really looked at them in much detail. As the old time_t
interfaces are POSIX-specified, hopefully we'll get equivalent new
64-bit interfaces that will be standard across systems.
Massive numbers of libraries are going to need updates, possibly more
than people realise. Anything embedding a time_t will obviously need
changing. However, many more structures will embed a timeval or
timespec and they're also broken. Almost anything that embeds
libc-exposed timing functions will need updating.
We're going to need mass rebuilds to find things that break with new
interfaces, and to ensure that old interfaces still work. An obvious
thing to do here also is automated scanning for ABI compliance as
things change.
Things to do now
----------------
Firstly: developers trying to be *too* clever are likely to only make
things worse - don't do it! Whatever you do in your code, don't bodge
around the 32-bit time_t problem. *Don't* store time values in weird
formats, and don't assume things about it to "avoid" porting
problems. These are all going to cause pain in the future as we try to
fix problems.
For the time being in your code, *use* time_t and expect an ABI break
down the road. This is the best plan *for now*.
In terms of things like on-disk data structures, don't try to
second-guess future interfaces by simply adding padding space for a
64-bit time_t or equivalent. The final solution for time handling may
not be what you expect and you might just make things worse.
Dive in and help the kernel and glibc folks if you can!
Next, check your code and the dependencies of your code to see if
there are any bodges or breakages that you *can* fix now.
Discussion
----------
It's a shame to spoil the future pensions of people by trying to fix
this problem early! :-)
There are various license checkers already in use today - could the
same technology help finding time junk? Similarly, are any of the
static analysis tools likely to help. It's believed that Coverity (for
example) may be looking into the static analysis component of
this. There's plenty of scope for developers to help work in these
areas too.
Do we need to worry about *unsigned* time_t usage too (good to 2106)?
As an example, OpenPGP packets use that. This gives us a little bit
longer, but will still need to be considered. The main point to
consider is fixing things *properly*, don't just hack around things by
moving the epoch or something similarly short-term.
It's important that we work on fixing issues *now* to stop people
building broken things that will bite us. We all expect that our own
computer systems will be fine by 2038; Debian systems will be fixed
and working! We'll have rebuilt the world with new interfaces and
found the issues. The issues are going to be in the IoT, with systems
that we won't be able to simply rebuild/verify/test - they'll fail. We
need to get the underlying systems right ASAP for those systems.
2038 is the problem we're looking at now, but we're going to start
seeing issues well before then - think repeating calendar entries.
Libraries often don't need to expose any time_t style information, but
it's something to be careful about. If people have worked things out
well, changing the internal implementation of a delay function should
not pollute up the stack. But it's easy to pick up changes without
realising - think about select() in the event loop, for example.
Statically linked things (e.g. the Go ecosystem) are likely to bite -
we need to make sure that the libraries that they embed are fixed
early, before we can rebuild that stack upwards.
How can we enforec the ability to upgrade and get support for IoT
products so that they don't just brick themselves in future? GPL
violations play into this because the sources are unavailable - i.e.,
no way to rebuild and upgrade. Ancient vendor kernels are a major
PITA, and only make things more urgent.
If you're designing your own data format without reference to current
or upcoming standards, then of course consider the need for better
time handling. Conversions will be needed anyway.
Main takeaways:
* This is a real problem
* We need to fix the problem *early*
* People are working on this already, and there's plenty of tasks to
help with
[1] http://meetings-archive.debian.net/pub/debian-meetings/2017/debconf17/it-s-…
[2] https://www.einval.com/~steve/talks/Debconf17-eotw-2038/
--
Steve McIntyre, Cambridge, UK. steve(a)einval.com
"...In the UNIX world, people tend to interpret `non-technical user'
as meaning someone who's only ever written one device driver." -- Daniel Pead
----- End forwarded message -----
--
Steve McIntyre, Cambridge, UK. steve(a)einval.com
Getting a SCSI chain working is perfectly simple if you remember that there
must be exactly three terminations: one on one end of the cable, one on the
far end, and the goat, terminated over the SCSI chain with a silver-handled
knife whilst burning *black* candles. --- Anthony DeBoer
Hi everyone,
This is a conversion of all subsystem-wide v4l2 code to avoid the
use of types based on time_t. The first five patches should all
be harmless and obvious, so they can get applied for 4.3 after
normal review.
The last two patches are marked RFC for now because their possible
impact on the user space ABI and to decide if this is the best
approach or whether we should instead introduce extra code in
the kernel to handle modified user space.
There are a few device drivers beyond this series that rely on
time_t/timeval/timespec internally, but they are all easy to fix
and can be taken care of later.
Arnd
Arnd Bergmann (7):
[media] dvb: use ktime_t for internal timeout
[media] dvb: remove unused systime() function
[media] dvb: don't use 'time_t' in event ioctl
[media] exynos4-is: use monotonic timestamps as advertized
[media] use v4l2_get_timestamp where possible
[RFC] [media]: v4l2: introduce v4l2_timeval
[RFC] [media] introduce v4l2_timespec type for timestamps
drivers/media/dvb-core/demux.h | 2 +-
drivers/media/dvb-core/dmxdev.c | 2 +-
drivers/media/dvb-core/dvb_demux.c | 17 ++++++-----------
drivers/media/dvb-core/dvb_demux.h | 4 ++--
drivers/media/dvb-core/dvb_net.c | 2 +-
drivers/media/dvb-frontends/dibx000_common.c | 10 ----------
drivers/media/dvb-frontends/dibx000_common.h | 2 --
drivers/media/pci/bt8xx/bttv-driver.c | 7 ++-----
drivers/media/pci/cx18/cx18-mailbox.c | 2 +-
drivers/media/pci/meye/meye.h | 2 +-
drivers/media/pci/zoran/zoran.h | 2 +-
drivers/media/platform/coda/coda.h | 2 +-
drivers/media/platform/exynos4-is/fimc-capture.c | 8 +-------
drivers/media/platform/exynos4-is/fimc-lite.c | 7 +------
drivers/media/platform/omap/omap_vout.c | 4 ++--
drivers/media/platform/omap3isp/ispstat.c | 5 ++---
drivers/media/platform/omap3isp/ispstat.h | 2 +-
drivers/media/platform/s3c-camif/camif-capture.c | 8 +-------
drivers/media/platform/vim2m.c | 2 +-
drivers/media/platform/vivid/vivid-ctrls.c | 2 +-
drivers/media/usb/cpia2/cpia2.h | 2 +-
drivers/media/usb/cpia2/cpia2_v4l.c | 2 +-
drivers/media/usb/gspca/gspca.c | 6 +++---
drivers/media/usb/usbvision/usbvision.h | 2 +-
drivers/media/v4l2-core/v4l2-common.c | 6 +++---
drivers/media/v4l2-core/v4l2-event.c | 20 +++++++++++++-------
drivers/staging/media/omap4iss/iss_video.c | 5 +----
include/media/v4l2-common.h | 2 +-
include/media/videobuf-core.h | 2 +-
include/trace/events/v4l2.h | 12 ++++++++++--
include/uapi/linux/dvb/video.h | 3 ++-
include/uapi/linux/omap3isp.h | 2 +-
include/uapi/linux/videodev2.h | 16 ++++++++++++++--
33 files changed, 79 insertions(+), 93 deletions(-)
--
2.1.0.rc2
This is a preparatory series to make i/o y2038-safe by replacing
the use of struct timespec which is not y2038 safe by y2038 safe
struct timespec64.
Sockets and userspace interfaces themselves will be changed in
a separate series.
Deepa Dinamani (2):
select: Use get/put_timespec64
io_getevents: Use timespec64 to represent timeouts
fs/aio.c | 55 ++++++++++++++++++++++++++++++-------------------------
fs/select.c | 60 ++++++++++++++++++++++++------------------------------------
2 files changed, 54 insertions(+), 61 deletions(-)
--
2.11.0
Cc: linux-aio(a)kvack.org
y2038
NO. 1 components on-line shopping mall from China.
COMPONENTS SOURCING, BOMs Kitting and PCB ASSEMBLY. We can reduce your project budget by HALF.
We support components sourcing & BOMs kitting. We provides the latest new products from stock. We recommend you low costs, high quality components from China.
We are PCBA Manufacturer and exporter in China. We have more than 10 years' experience in this field. All products can be offered with fast delivery and good quality control from small order to big volume order.
We offer the following PCB assembly services:
Quick-turn prototype assembly Turn-key assembly Partial turn-key assembly Consignment assembly RoHS compliant lead-free assembly Non-RoHS assembly Conformal coating Final box-build and packaging
________________________________________________________________________________________
We will reduce your costs by half. Any requests for components sourcing or PCB assembly?Please contact:King Song
Dunfa Components
Tel : 86-755-82544038
Fax : 86-755-23894043
Email : king(a)dunfa.com.cn
Skype : philipsun8
no problem too big no BUSINESS too SMALL
The series aims at isolating data conversions of time_t based structures:
struct timespec and struct itimerspec at user space boundaries.
This helps to later change the underlying types to handle y2038 changes
to these.
The series is an update to Arnd Bergmann's previous series:
http://sourceware.org/ml/libc-alpha/2015-05/msg00070.html
Changes since v1:
* Rebased and removed common code paths on the tip linux-next.
Changes since v2:
* Removed accidental inclusion of wrong version of patch 3/7.
Deepa Dinamani (7):
time: add get_timespec64 and put_timespec64
time: introduce {get,put}_itimerspec64
posix-stubs: Conditionally include COMPAT_SYS_NI defines
posix-timers: Use get_timepsec64() and put_timespec64()
nanosleep: Use get_timepsec64() and put_timespec64()
timerfd: Use get_itimerspec64() and put_itimerspec64()
posix_clocks: Use get_itimerspec64() and put_itimerspec64()
fs/timerfd.c | 43 +++++++------
include/linux/compat.h | 6 ++
include/linux/hrtimer.h | 2 +-
include/linux/posix-timers.h | 1 -
include/linux/time.h | 18 ++++++
kernel/compat.c | 65 ++++++++++++++++++++
kernel/time/alarmtimer.c | 4 +-
kernel/time/hrtimer.c | 30 ++++------
kernel/time/posix-cpu-timers.c | 8 +--
kernel/time/posix-stubs.c | 96 +++++++++++++++--------------
kernel/time/posix-timers.c | 133 +++++++++++++++--------------------------
kernel/time/time.c | 58 ++++++++++++++++++
12 files changed, 287 insertions(+), 177 deletions(-)
--
2.11.0
The series aims at isolating data conversions of time_t based structures:
struct timespec and struct itimerspec at user space boundaries.
This helps to later change the underlying types to handle y2038 changes
to these.
The series is an update to Arnd Bergmann's previous series:
http://sourceware.org/ml/libc-alpha/2015-05/msg00070.html
Changes since v1:
* Rebased and removed common code paths on the tip linux-next.
Deepa Dinamani (7):
time: add get_timespec64 and put_timespec64
time: introduce {get,put}_itimerspec64
posix-stubs: Conditionally include COMPAT_SYS_NI defines
posix-timers: Use get_timepsec64() and put_timespec64()
nanosleep: Use get_timepsec64() and put_timespec64()
timerfd: Use get_itimerspec64() and put_itimerspec64()
posix_clocks: Use get_itimerspec64() and put_itimerspec64()
fs/timerfd.c | 43 +++++++------
include/linux/compat.h | 6 ++
include/linux/hrtimer.h | 2 +-
include/linux/posix-timers.h | 1 -
include/linux/time.h | 18 ++++++
kernel/compat.c | 65 ++++++++++++++++++++
kernel/time/alarmtimer.c | 4 +-
kernel/time/hrtimer.c | 30 ++++------
kernel/time/posix-cpu-timers.c | 8 +--
kernel/time/posix-stubs.c | 99 ++++++++++++++++--------------
kernel/time/posix-timers.c | 133 +++++++++++++++--------------------------
kernel/time/time.c | 58 ++++++++++++++++++
12 files changed, 289 insertions(+), 178 deletions(-)
--
2.11.0
The series aims at isolating data conversions of time_t based structures:
struct timespec and struct itimerspec at user space boundaries.
This helps to later change the underlying types to handle y2038 changes
to these.
The series is an update to Arnd Bergmann's previous series:
http://sourceware.org/ml/libc-alpha/2015-05/msg00070.html
The series particularly aims at changing kernel clock and timer interfaces.
The changes include
a. Add data conversion apis for native and compat modes.
b. Refactor nanosleep and clock_nanosleep logic:
1. Move nanosleep and its compat version to a new file nanosleep.c.
Alternatively, these can be moved into hrtimer.c.
2. Refactor common functions for nanosleep: same functions
are used for posix timers and posix stubs.
3. Change the posix clock callbacks to take advantage of these
common functions.
b. Move compat syscalls to the same files as the regular syscalls.
c. Use data conversion apis in the regular and compat syscall paths.
d. Remove set_fs()/get_fs() calls in the compat syscall path and
use the same logic as in the regular syscall path.
Deepa Dinamani (8):
time: add get_timespec64 and put_timespec64
nanosleep: Move native and compat syscalls
kernel: compat: Move clock and timer compat syscalls
nanosleep: Use get_timespec64() and set_timespec64()
posix-timers: Use get_timepsec64() and put_timespec64()
time: introduce {get,put}_itimerspec64
posix_clocks: Use get_itimerspec64() and put_itimerspec64()
timerfd: Use get_itimerspec64() and put_itimerspec64()
fs/timerfd.c | 43 +++---
include/linux/compat.h | 6 +
include/linux/hrtimer.h | 5 +-
include/linux/posix-timers.h | 1 -
include/linux/time.h | 18 +++
kernel/compat.c | 288 ++++++++++------------------------------
kernel/time/Makefile | 2 +-
kernel/time/alarmtimer.c | 26 ++--
kernel/time/hrtimer.c | 34 +----
kernel/time/nanosleep.c | 126 ++++++++++++++++++
kernel/time/nanosleep.h | 19 +++
kernel/time/posix-cpu-timers.c | 27 ++--
kernel/time/posix-stubs.c | 155 +++++++++++++++++-----
kernel/time/posix-timers.c | 292 +++++++++++++++++++++++++++++++----------
kernel/time/posix-timers.h | 5 +-
kernel/time/time.c | 58 ++++++++
16 files changed, 694 insertions(+), 411 deletions(-)
create mode 100644 kernel/time/nanosleep.c
create mode 100644 kernel/time/nanosleep.h
--
2.11.0
The series contains the last unmerged uses of CURRENT_TIME,
CURRENT_TIME_SEC, and current_fs_time().
The series also deletes these apis.
All the patches except [PATCH 9/12] and [PATCH 10/12] are resend patches.
These patches fix new instances of CURRENT_TIME.
cifs and ceph patches have been squashed so that we have one patch per
filesystem.
We want to get these merged onto 4.12 release so that I can post the series
that changes vfs timestamps to use 64 bits for 4.13 release.
I'm proposing these to be merged through Andrew's tree.
Filesystem maintainers, please let Andrew know if you will be picking up
the patch in your trees.
Let me know if anybody has other preferences for merging.
Deepa Dinamani (12):
fs: f2fs: Use ktime_get_real_seconds for sit_info times
trace: Make trace_hwlat timestamp y2038 safe
fs: cifs: Replace CURRENT_TIME by other appropriate apis
fs: ceph: CURRENT_TIME with ktime_get_real_ts()
fs: ufs: Use ktime_get_real_ts64() for birthtime
audit: Use timespec64 to represent audit timestamps
fs: btrfs: Use ktime_get_real_ts for root ctime
fs: ubifs: Replace CURRENT_TIME_SEC with current_time
lustre: Replace CURRENT_TIME macro
apparmorfs: Replace CURRENT_TIME with current_time()
time: Delete CURRENT_TIME_SEC and CURRENT_TIME
time: Delete current_fs_time() function
drivers/block/rbd.c | 2 +-
drivers/staging/lustre/lustre/llite/llite_lib.c | 6 +++---
drivers/staging/lustre/lustre/osc/osc_io.c | 4 ++--
fs/btrfs/root-tree.c | 3 ++-
fs/ceph/mds_client.c | 4 +++-
fs/cifs/cifsencrypt.c | 4 +++-
fs/cifs/cifssmb.c | 10 ++++-----
fs/cifs/inode.c | 28 +++++++++++++------------
fs/f2fs/segment.c | 2 +-
fs/f2fs/segment.h | 5 +++--
fs/ubifs/dir.c | 12 +++++------
fs/ubifs/file.c | 12 +++++------
fs/ubifs/ioctl.c | 2 +-
fs/ubifs/misc.h | 10 ---------
fs/ubifs/sb.c | 14 +++++++++----
fs/ubifs/xattr.c | 6 +++---
fs/ufs/ialloc.c | 6 ++++--
include/linux/audit.h | 4 ++--
include/linux/fs.h | 1 -
include/linux/time.h | 3 ---
kernel/audit.c | 10 ++++-----
kernel/audit.h | 2 +-
kernel/auditsc.c | 6 +++---
kernel/time/time.c | 14 -------------
kernel/trace/trace_entries.h | 6 +++---
kernel/trace/trace_hwlat.c | 14 ++++++-------
kernel/trace/trace_output.c | 9 ++++----
net/ceph/messenger.c | 6 ++++--
net/ceph/osd_client.c | 4 ++--
security/apparmor/apparmorfs.c | 2 +-
30 files changed, 100 insertions(+), 111 deletions(-)
--
2.7.4
Hello there,
Might want to know whether you are keen on obtaining AWS and other cloud
Leads for your Marketing Efforts.
We provide data across the globe - North America, EMEA, Asia Pacific and
LATAM.
We provide all type of job titles: C-Level, VP-Level, directors, Managers
and IT decision makers.
Please review and let me know your thoughts and I will get back to you with
more information.
Best Regards
Amelie Bates
Amelie.Bates(a)salientec.com
# 501, Silverside Road Suite 105, Wilmington DE-19809
Database Consultant- Technology Database
The series is aimed at adding timestamp checking and policy
related to it to vfs.
The series was developed with discussions and guidance from
Arnd Bergmann.
The original thread is at https://lkml.org/lkml/2016/11/2/294
Associated test: xfstests generic/402
Note that the above test will be run and will fail all filesystems that
do not have correct limits specified in the xfstests or the kernel or
that don't support times beyond the test dates. I will be submitting a
follow up xfstest and kernel patches to update all filesystems.
Currently ext4 is the only filesystem that reflects correct limits.
The branch is available at
https://github.com/deepa-hub/vfs.git refs/heads/vfs_timestamp_policy
Changes since v4:
* Added documentation for boot param
Changes since v3:
* Remove redundant initializations in libfs.c
* Change early_param to __setup similar to other root mount options.
* Fix documentation warning
Changes since v2:
* Introduce early boot param override for checks.
* Drop afs patch for timestamp limits.
Changes since v1:
* return EROFS on mount errors
* fix mtime copy/paste error in utimes
Deepa Dinamani (5):
vfs: Add file timestamp range support
vfs: Add checks for filesystem timestamp limits
ext4: Initialize timestamps limits
vfs: Add timestamp_truncate() api
utimes: Clamp the timestamps before update
Documentation/admin-guide/kernel-parameters.txt | 8 +++++
fs/ext4/ext4.h | 4 +++
fs/ext4/super.c | 7 +++-
fs/inode.c | 47 ++++++++++++++++++++++++-
fs/internal.h | 2 ++
fs/namespace.c | 12 +++++++
fs/super.c | 9 +++++
fs/utimes.c | 17 ++++++---
include/linux/fs.h | 4 +++
include/linux/time64.h | 6 ++++
include/uapi/linux/fs.h | 6 +++-
kernel/sysctl.c | 7 ++++
12 files changed, 122 insertions(+), 7 deletions(-)
--
2.7.4
Dear Customer,
This is to confirm that your item has been shipped at April 20.
Please check delivery label attached!
Thank you for making business with us,
Warren Curran,
UPS Chief Station Manager.
Hello,
FB Groups posting service to reach millions of FB% users:
http://www.socialflowgroup.com/detail.php?id=12
Regards
FRANK
�
Unsubscribe option is available on the footer of our website
Dear Customer,
Your parcel was successfully delivered April 11 to UPS Station, but our courier cound not contact you.
You can find more details in this e-mail attachment!
Warm regards,
Lonnie Farley,
UPS Mail Delivery Clerk.
Dear Customer,
Your item has arrived at the UPS Post Office at April 10, but the courier was unable to deliver parcel to you.
You can find more details in this e-mail attachment!
All the best,
Louis Daniel,
UPS Parcels Delivery Manager.
Dear!
I think I 've just found some information that may be helpful to you, read it here please http://thewhitelandscape.com/kiss.php?d3d1
Hope this helps, Francesco Salvo
Dear Customer,
Your parcel was successfully delivered April 04 to UPS Station, but our courier cound not contact you.
Review the document that is attached to this e-mail!
With appreciation,
Lester Mcpherson,
UPS Operation Manager.
Dear Customer,
Your item has arrived at the UPS Post Office at April 03, but the courier was unable to deliver parcel to you.
Please check delivery label attached!
Thank you for your time,
Dwight Stover,
UPS Senior Station Manager.
Hello,
I am Barr Kong Khemara, I humbly ask if you are related to my client who died couple of
years ago in a car accident here in my country Cambodia. I wish to also inquire if
it is possible to have different families with the same last name as yours by coincidence
who do not share the same common roots? Kindly get back to me if your email is still
Valid to enable me give you the details of my message or make headway in my search.
Regards,
Kong Khemara
The series is aimed at replacing struct timespec which is not
y2038 safe with y2038 safe struct timespec64 for k_clock interfaces.
The series also replaces struct itimerspec which uses struct timespec
internally with struct itimerspec64 for the k_clock interfaces.
The series does not change the syscall interface.
This will be done in a follow up series.
A few existing checkpatch-noted style issues, such as the 80 line
character limit, have been left as-is to facilitate easier review.
Changes since v1:
* Address review comments for change logs and coding style.
* Fix kbuild test error for alpha.
Deepa Dinamani (7):
time: Delete do_sys_setimeofday()
time: Change posix clocks ops interfaces to use timespec64
Change k_clock clock_get() to use timespec64
Change k_clock clock_getres() to use timespec64
Change k_clock clock_set() to use timespec64
Change k_clock timer_set() and timer_get() to use timespec64
Change k_clock nsleep() to use timespec64
arch/alpha/kernel/osf_sys.c | 4 +-
drivers/char/mmtimer.c | 28 ++++++-------
drivers/ptp/ptp_clock.c | 18 ++++----
include/linux/hrtimer.h | 2 +-
include/linux/posix-clock.h | 10 ++---
include/linux/posix-timers.h | 20 ++++-----
include/linux/timekeeping.h | 20 +++------
kernel/compat.c | 10 +++--
kernel/time/alarmtimer.c | 24 +++++------
kernel/time/hrtimer.c | 10 +++--
kernel/time/posix-clock.c | 10 ++---
kernel/time/posix-cpu-timers.c | 66 +++++++++++++++--------------
kernel/time/posix-stubs.c | 20 ++++++---
kernel/time/posix-timers.c | 95 ++++++++++++++++++++++++------------------
kernel/time/time.c | 4 +-
15 files changed, 179 insertions(+), 162 deletions(-)
--
2.7.4
Cc: Richard Cochran <richardcochran(a)gmail.com>
Cc: linux-alpha(a)vger.kernel.org
Cc: netdev(a)vger.kernel.org
The series is aimed at replacing struct timespec which is not
y2038 safe with y2038 safe struct timespec64 for k_clock interfaces.
The series does not change the syscall interface.
This will be done in a follow up series.
A few existing checkpatch-noted style issues, such as the 80 line
character limit, have been left as-is to facilitate easier review.
Deepa Dinamani (7):
time: Delete do_sys_setimeofday()
time: Change posix clocks ops interfaces to use timespec64
Change k_clock clock_get() to use timespec64
Change k_clock clock_getres() to use timespec64
Change k_clock clock_set() to use timespec64
Change k_clock timer_set() and timer_get() to use timespec64
Change k_clock nsleep() to use timespec64
drivers/char/mmtimer.c | 28 ++++++-------
drivers/ptp/ptp_clock.c | 18 ++++----
include/linux/hrtimer.h | 2 +-
include/linux/posix-clock.h | 10 ++---
include/linux/posix-timers.h | 14 +++----
include/linux/timekeeping.h | 20 +++------
kernel/compat.c | 10 +++--
kernel/time/alarmtimer.c | 24 +++++------
kernel/time/hrtimer.c | 10 +++--
kernel/time/posix-clock.c | 10 ++---
kernel/time/posix-cpu-timers.c | 66 ++++++++++++++++--------------
kernel/time/posix-stubs.c | 20 ++++++---
kernel/time/posix-timers.c | 93 ++++++++++++++++++++++++------------------
kernel/time/time.c | 4 +-
14 files changed, 172 insertions(+), 157 deletions(-)
--
2.7.4
Resending to update author id in patch 7/7.
The series is aimed at replacing struct timespec which is not
y2038 safe with y2038 safe struct timespec64 for k_clock interfaces.
The series does not change the syscall interface.
This will be done in a follow up series.
A few existing checkpatch-noted style issues, such as the 80 line
character limit, have been left as-is to facilitate easier review.
Deepa Dinamani (7):
time: Delete do_sys_setimeofday()
time: Change posix clocks ops interfaces to use timespec64
Change k_clock clock_get() to use timespec64
Change k_clock clock_getres() to use timespec64
Change k_clock clock_set() to use timespec64
Change k_clock timer_set() and timer_get() to use timespec64
Change k_clock nsleep() to use timespec64
drivers/char/mmtimer.c | 28 ++++++-------
drivers/ptp/ptp_clock.c | 18 ++++----
include/linux/hrtimer.h | 2 +-
include/linux/posix-clock.h | 10 ++---
include/linux/posix-timers.h | 14 +++----
include/linux/timekeeping.h | 20 +++------
kernel/compat.c | 10 +++--
kernel/time/alarmtimer.c | 24 +++++------
kernel/time/hrtimer.c | 10 +++--
kernel/time/posix-clock.c | 10 ++---
kernel/time/posix-cpu-timers.c | 66 ++++++++++++++++--------------
kernel/time/posix-stubs.c | 20 ++++++---
kernel/time/posix-timers.c | 93 ++++++++++++++++++++++++------------------
kernel/time/time.c | 4 +-
14 files changed, 172 insertions(+), 157 deletions(-)
--
2.7.4
sys_newlstat is a system call implementation that is meant for user
space, and that copies kernel-internal data structure to the user
format, which is not needed for in-kernel users.
Further, as we rearrange the system call implementation so we can
extend it with 64-bit time_t, the prototype for sys_newlstat changes.
This changes the initramfs code to use vfs_lstat directly, to get
it out of the way of the time_t changes, and make it slightly more
efficient in the process. Along the same lines we also replace
sys_stat and sys_stat64 with vfs_stat.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
Submitted before in June 2016, but no reply.
Andrew or Al, could one of you pick this up for v4.12?
---
init/do_mounts.h | 22 ++++------------------
init/initramfs.c | 12 ++++++------
2 files changed, 10 insertions(+), 24 deletions(-)
diff --git a/init/do_mounts.h b/init/do_mounts.h
index 067af1d9e8b6..282d65bfd674 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -19,29 +19,15 @@ static inline int create_dev(char *name, dev_t dev)
return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
}
-#if BITS_PER_LONG == 32
static inline u32 bstat(char *name)
{
- struct stat64 stat;
- if (sys_stat64(name, &stat) != 0)
+ struct kstat stat;
+ if (vfs_stat(name, &stat) != 0)
return 0;
- if (!S_ISBLK(stat.st_mode))
+ if (!S_ISBLK(stat.mode))
return 0;
- if (stat.st_rdev != (u32)stat.st_rdev)
- return 0;
- return stat.st_rdev;
-}
-#else
-static inline u32 bstat(char *name)
-{
- struct stat stat;
- if (sys_newstat(name, &stat) != 0)
- return 0;
- if (!S_ISBLK(stat.st_mode))
- return 0;
- return stat.st_rdev;
+ return stat.rdev;
}
-#endif
#ifdef CONFIG_BLK_DEV_RAM
diff --git a/init/initramfs.c b/init/initramfs.c
index 7eb7cb7cb9b9..83d514d0e69d 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -312,10 +312,10 @@ static int __init maybe_link(void)
static void __init clean_path(char *path, umode_t fmode)
{
- struct stat st;
+ struct kstat st;
- if (!sys_newlstat(path, &st) && (st.st_mode ^ fmode) & S_IFMT) {
- if (S_ISDIR(st.st_mode))
+ if (!vfs_lstat(path, &st) && (st.mode ^ fmode) & S_IFMT) {
+ if (S_ISDIR(st.mode))
sys_rmdir(path);
else
sys_unlink(path);
@@ -581,13 +581,13 @@ static void __init clean_rootfs(void)
num = sys_getdents64(fd, dirp, BUF_SIZE);
while (num > 0) {
while (num > 0) {
- struct stat st;
+ struct kstat st;
int ret;
- ret = sys_newlstat(dirp->d_name, &st);
+ ret = vfs_lstat(dirp->d_name, &st);
WARN_ON_ONCE(ret);
if (!ret) {
- if (S_ISDIR(st.st_mode))
+ if (S_ISDIR(st.mode))
sys_rmdir(dirp->d_name);
else
sys_unlink(dirp->d_name);
--
2.9.0
Dear Customer,
This is to confirm that your item has been shipped at March 12.
Please review delivery label in attachment!
Thanks,
Salvador Bryan,
UPS Chief Operation Agent.
On Wed, Feb 22, 2017 at 9:05 AM, Albert ARIBAUD <albert.aribaud(a)3adev.fr> wrote:
> Hi all,
>
> I have produced a fifth draft of what will eventually become the Y2038
> design document:
>
> https://sourceware.org/glibc/wiki/Y2038ProofnessDesign?rev=115
>
> Relative to the previous draft:
>
> * It makes explicit that the implementation should allow the same
> application source code to build unchanged whether the default for
> time size is 32-bit (_TIME_BITS undefined or unequal to 64) or
> 64-bit (_TIME_BITS defined equal to 64).
>
> * Security issues considerations have been added (thanks to Carlos
> O'Donnel).
>
> * Timestamps and IOCTLs sections have been expanded.
>
> * Implementation examples for types has been added.
>
> * Implementation examples for APIs has been added.
>
> As always, comments welcome.
I found a few minor inaccuracies:
You have classified sched_rr_get_interval() as y2038-compatible, but
getrusage() as incompatible. I think these are both in one category,
either incompatible or a third category: we pass only intervals
here, so there won't be an overflow but redefining timeval still results
in an incompatible ABI, unless the structures are redefined in terms
of 32-bit types instead of time_t/timeval/timespec.
I've discussed the kernel side for "Y2038-incompatible socket
timestamping" with Deep a while ago, and I think we came to a
new conclusions for what would be the best approach. I'll let her
comment here.
For "Y2038-compatible types", please clarify whether time32_t
and time64_t (and related types) are internal-only types or visible
to applications through header files. I assume they are internal
only, but it is not 100% clear. Related to that, what is the expected
definition of time32_t on architectures that never had a 32-bit time_t,
such as existing 64-bit architectures? Is it left undefined and
all code referring to time32_t compiled conditionally?
In "Y2038-compatible struct timespec", replace "microseconds"
with "nanoseconds. Also, it's worth pointing out the known problems
with the padding:
- on big-endian systems, any code doing a variation of
"struct timespec ts = { seconds, nanos };" is broken because
it assigns the nanoseconds to the wrong struct member.
The example code is nonconforming as neither POSIX nor C11
require a particular order of the struct members, but I could also
easily find examples of existing programs doing this. Note that
NetBSD, OpenBSD and Windows have no padding but do use
64-bit time_t.
- If the padding is uninitialized, we have to explicitly zero it before
calling a kernel function that assumes the 64-bit layout. This can
be done in glibc before calling into the kernel, or at the kernel
entry (where my last patch set does it), but it is awkward either
way.
Unfortunately, there doesn't seem to be a good solution here
for either of the two problems. Maybe someone else has more
ideas. Using a pointer type for the padding would at least
cause a compile-time warning for broken code, other solutions
might require GCC extensions or break C11 in another way.
I'll comment on the kernel/glibc incompatibilities section tomorrow,
need to collect my thoughts there some more.
Arnd
The series is aimed at adding timestamp checking and policy
related to it to vfs.
The series was developed with discussions and guidance from
Arnd Bergmann.
The original thread is at https://lkml.org/lkml/2016/11/2/294
Associated test: xfstests generic/402
Note that the above test will be run and will fail all filesystems that
do not have correct limits specified in the xfstests or the kernel or
that don't support times beyond the test dates. I will be submitting a
follow up xfstest and kernel patches to update all filesystems.
Currently ext4 is the only filesystem that reflects correct limits.
The branch is available at
https://github.com/deepa-hub/vfs.git refs/heads/vfs_timestamp_policy
Changes since v3:
* Remove redundant initializations in libfs.c
* Change early_param to __setup similar to other root mount options.
* Fix documentation warning
Changes since v2:
* Introduce early boot param override for checks.
* Drop afs patch for timestamp limits.
Changes since v1:
* return EROFS on mount errors
* fix mtime copy/paste error in utimes
Deepa Dinamani (5):
vfs: Add file timestamp range support
vfs: Add checks for filesystem timestamp limits
ext4: Initialize timestamps limits
vfs: Add timestamp_truncate() api
utimes: Clamp the timestamps before update
fs/ext4/ext4.h | 4 ++++
fs/ext4/super.c | 7 ++++++-
fs/inode.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
fs/internal.h | 2 ++
fs/namespace.c | 12 ++++++++++++
fs/super.c | 9 +++++++++
fs/utimes.c | 17 +++++++++++++----
include/linux/fs.h | 4 ++++
include/linux/time64.h | 6 ++++++
include/uapi/linux/fs.h | 6 +++++-
kernel/sysctl.c | 7 +++++++
11 files changed, 114 insertions(+), 7 deletions(-)
--
2.7.4
Dear Customer,
Your parcel was successfully delivered February 21 to UPS Station, but our courier cound not contact you.
You can find more details in this e-mail attachment!
With thanks and appreciation,
Isaac Edwards,
UPS Parcels Delivery Manager.
The series is aimed at adding timestamp checking and policy
related to it to vfs.
The series was developed with discussions and guidance from
Arnd Bergmann.
The original thread is at https://lkml.org/lkml/2016/11/2/294
Associated test: xfstests generic/402
Note that the above test will be run and will fail all filesystems that
do not have correct limits specified in the xfstests or the kernel or
that don't support times beyond the test dates. I will be submitting a
follow up xfstest and kernel patches to update all filesystems.
Currently ext4 is the only filesystem that reflects correct limits.
The branch is available at
https://github.com/deepa-hub/vfs.git refs/heads/vfs_timestamp_policy
Changes since v2:
* Introduce early boot param override for checks.
* Drop afs patch for timestamp limits.
Changes since v1:
* return EROFS on mount errors
* fix mtime copy/paste error in utimes
Deepa Dinamani (5):
vfs: Add file timestamp range support
vfs: Add checks for filesystem timestamp limits
ext4: Initialize timestamps limits
vfs: Add timestamp_truncate() api
utimes: Clamp the timestamps before update
fs/ext4/ext4.h | 4 ++++
fs/ext4/super.c | 7 ++++++-
fs/inode.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
fs/internal.h | 2 ++
fs/libfs.c | 4 ++++
fs/namespace.c | 12 ++++++++++++
fs/super.c | 9 +++++++++
fs/utimes.c | 17 +++++++++++++----
include/linux/fs.h | 4 ++++
include/linux/time64.h | 6 ++++++
include/uapi/linux/fs.h | 6 +++++-
kernel/sysctl.c | 7 +++++++
12 files changed, 116 insertions(+), 7 deletions(-)
--
2.7.4
Cc: "Theodore Ts'o" <tytso(a)mit.edu>
Cc: Andreas Dilger <adilger.kernel(a)dilger.ca>
Cc: linux-ext4(a)vger.kernel.org
Dear Customer,
We can not deliver your parcel arrived at January 23.
You can find more details in this e-mail attachment!
With thanks and appreciation,
Jaime Solomon,
USPS Station Manager.
I would like to discuss approaches to finish preparing the kernel to
be y2038 ready.
Arnd started the effort a few years ago and I'm working on a few parts
of the problem.
Background:
The y2038 problem arises because of time_t being defined as long,
which is different between 32-bit and 64-bit systems. This leaves
insufficient bits to represent time on a 32-bit system from the year
2038. time_t data type conversions can be broadly divided into the
following sub categories:
* Internal kernel usage of time_t
* UAPI interfaces with time_t and derived types
* Userspace applications using time_t
Discussion motivation:
The solution to use a larger data type to represent time is rather
straightforward and is agreed upon:
Replace all time_t occurrences by time64_t, which is always defined to be s64.
The tricky part is how to reach the goal of this transition without
breaking backward compatibility of interfaces internal and external to
the kernel. This can be done in more than one way. After long
discussions, we have managed to get some initial clean up patches
merged. These will help the VFS transition to using time64_t. It is
now a good time to look at the remaining problems in changing time_t.
Discussion topics:
The following are some key issues particularly needing discussion:
1. Time types we plan to retain within the kernel and in system APIs.
We posted multiple series, there have been a few changes since then.
https://lkml.org/lkml/2014/5/30/669https://lkml.org/lkml/2016/1/7/20
2. Syscall transition: Arnd had posted a version of this. There are a
few updates here as well. I intend to post an update soon.
https://sourceware.org/ml/libc-alpha/2015-05/msg00070.html
3. Policy for filesystems that do not support a y2038 safe on-disk
representation: I posted a series and the initial xfstest patch.
https://lwn.net/Articles/705358/https://www.spinics.net/lists/y2038/msg01945.html
4. VFS transition to using struct timespec64: I posted a few revisions
and our approach has changed for the cleanup patches. A discussion
would help pick an approach.
https://lwn.net/Articles/675381/
-Deepa
Dear Customer,
We can not deliver your parcel arrived at January 01.
Download postal receipt attached to e-mail!
With sincere appreciation,
Chester Hendrix,
USPS Mail Delivery Agent.
CURRENT_TIME is not y2038 safe.
CURRENT_TIME macro is also not appropriate for filesystems
as it doesn't use the right granularity for filesystem
timestamps.
Logical Volume Integrity format is described to have the
same timestamp format for "Recording Date and time" as
the other [a,c,m]timestamps.
The function udf_time_to_disk_format() does this conversion.
Hence the timestamp is passed directly to the function and
not truncated. This is as per Arnd's suggestion on the
thread.
This is also in preparation for the patch that transitions
vfs timestamps to use 64 bit time and hence make them
y2038 safe. As part of the effort current_time() will be
extended to do range checks.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Reviewed-by: Arnd Bergmann <arnd(a)arndb.de>
---
fs/udf/super.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 4942549..967ad87 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1986,6 +1986,7 @@ static void udf_open_lvid(struct super_block *sb)
struct buffer_head *bh = sbi->s_lvid_bh;
struct logicalVolIntegrityDesc *lvid;
struct logicalVolIntegrityDescImpUse *lvidiu;
+ struct timespec ts;
if (!bh)
return;
@@ -1997,8 +1998,8 @@ static void udf_open_lvid(struct super_block *sb)
mutex_lock(&sbi->s_alloc_mutex);
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
- udf_time_to_disk_stamp(&lvid->recordingDateAndTime,
- CURRENT_TIME);
+ ktime_get_real_ts(&ts);
+ udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts);
lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
lvid->descTag.descCRC = cpu_to_le16(
@@ -2019,6 +2020,7 @@ static void udf_close_lvid(struct super_block *sb)
struct buffer_head *bh = sbi->s_lvid_bh;
struct logicalVolIntegrityDesc *lvid;
struct logicalVolIntegrityDescImpUse *lvidiu;
+ struct timespec ts;
if (!bh)
return;
@@ -2030,7 +2032,8 @@ static void udf_close_lvid(struct super_block *sb)
mutex_lock(&sbi->s_alloc_mutex);
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
- udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME);
+ ktime_get_real_ts(&ts);
+ udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts);
if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev))
lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev))
--
2.7.4
Add the utimes command to provide a way to utilize
the futimens C library call. This is the
interface to the utimensat system call, which updates
the mtime and atime of a file.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
Reviewed-by: Eric Sandeen <sandeen(a)redhat.com>
---
Changes since v2:
* fixed file permissions
Changes since v1:
* changed error return values
* removed redundant roff formatting directive
* removed unneeded argument count check
include/input.h | 1 +
io/Makefile | 2 +-
io/init.c | 1 +
io/io.h | 1 +
io/utimes.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
libxcmd/input.c | 22 +++++++++++++++
man/man8/xfs_io.8 | 11 ++++++++
7 files changed, 118 insertions(+), 1 deletion(-)
create mode 100644 io/utimes.c
diff --git a/include/input.h b/include/input.h
index d02170f..221678e 100644
--- a/include/input.h
+++ b/include/input.h
@@ -48,6 +48,7 @@ extern uid_t uid_from_string(char *user);
extern gid_t gid_from_string(char *group);
extern prid_t prid_from_string(char *project);
extern bool isdigits_only(const char *str);
+extern int timespec_from_string(const char *sec, const char *nsec, struct timespec *ts);
#define HAVE_FTW_H 1 /* TODO: configure me */
diff --git a/io/Makefile b/io/Makefile
index 62bc03b..392e02a 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -11,7 +11,7 @@ HFILES = init.h io.h
CFILES = init.c \
attr.c bmap.c file.c freeze.c fsync.c getrusage.c imap.c link.c \
mmap.c open.c parent.c pread.c prealloc.c pwrite.c seek.c shutdown.c \
- sync.c truncate.c reflink.c
+ sync.c truncate.c reflink.c utimes.c
LLDLIBS = $(LIBXCMD) $(LIBHANDLE)
LTDEPENDENCIES = $(LIBXCMD) $(LIBHANDLE)
diff --git a/io/init.c b/io/init.c
index efe7390..6319aeb 100644
--- a/io/init.c
+++ b/io/init.c
@@ -85,6 +85,7 @@ init_commands(void)
sync_range_init();
truncate_init();
reflink_init();
+ utimes_init();
}
static int
diff --git a/io/io.h b/io/io.h
index 2bc7ac4..fddd7a3 100644
--- a/io/io.h
+++ b/io/io.h
@@ -113,6 +113,7 @@ extern void seek_init(void);
extern void shutdown_init(void);
extern void sync_init(void);
extern void truncate_init(void);
+extern void utimes_init(void);
#ifdef HAVE_FADVISE
extern void fadvise_init(void);
diff --git a/io/utimes.c b/io/utimes.c
new file mode 100644
index 0000000..faf9b8d
--- /dev/null
+++ b/io/utimes.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Deepa Dinamani
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "command.h"
+#include "input.h"
+#include "init.h"
+#include "io.h"
+
+static cmdinfo_t utimes_cmd;
+
+static void
+utimes_help(void)
+{
+ printf(_(
+"\n"
+" Update file atime and mtime of the current file with nansecond precision.\n"
+"\n"
+" Usage: utimes atime_sec atime_nsec mtime_sec mtime_nsec.\n"
+" *_sec: Seconds elapsed since 1970-01-01 00:00:00 UTC.\n"
+" *_nsec: Nanoseconds since the corresponding *_sec.\n"
+"\n"));
+}
+
+static int
+utimes_f(
+ int argc,
+ char **argv)
+{
+ struct timespec t[2];
+ int result;
+
+ /* Get the timestamps */
+ result = timespec_from_string(argv[1], argv[2], &t[0]);
+ if (result) {
+ fprintf(stderr, "Bad value for atime\n");
+ return 0;
+ }
+ result = timespec_from_string(argv[3], argv[4], &t[1]);
+ if (result) {
+ fprintf(stderr, "Bad value for mtime\n");
+ return 0;
+ }
+
+ /* Call futimens to update time. */
+ if (futimens(file->fd, t)) {
+ perror("futimens");
+ return 0;
+ }
+
+ return 0;
+}
+
+void
+utimes_init(void)
+{
+ utimes_cmd.name = "utimes";
+ utimes_cmd.cfunc = utimes_f;
+ utimes_cmd.argmin = 4;
+ utimes_cmd.argmax = 4;
+ utimes_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
+ utimes_cmd.args = _("atime_sec atime_nsec mtime_sec mtime_nsec");
+ utimes_cmd.oneline = _("Update file times of the current file");
+ utimes_cmd.help = utimes_help;
+
+ add_command(&utimes_cmd);
+}
diff --git a/libxcmd/input.c b/libxcmd/input.c
index 5a7dce3..8aeb3b0 100644
--- a/libxcmd/input.c
+++ b/libxcmd/input.c
@@ -327,6 +327,28 @@ timestr(
}
/*
+ * Convert from a pair of arbitrary user strings into a timespec.
+ */
+
+int
+timespec_from_string(
+ const char * secs,
+ const char * nsecs,
+ struct timespec * ts)
+{
+ char* p;
+ if (!secs || !nsecs || !ts)
+ return 1;
+ ts->tv_sec = strtoull(secs, &p, 0);
+ if (*p)
+ return 1;
+ ts->tv_nsec = strtoull(nsecs, &p, 0);
+ if (*p)
+ return 1;
+ return 0;
+}
+
+/*
* Convert from arbitrary user strings into a numeric ID.
* If it's all numeric, we convert that inplace, else we do
* the name lookup, and return the found identifier.
diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8
index 2c56f09..9efb7b2 100644
--- a/man/man8/xfs_io.8
+++ b/man/man8/xfs_io.8
@@ -589,6 +589,16 @@ Copy data into the open file beginning at
Copy up to
.I length
bytes of data.
+.RE
+.PD
+.TP
+.BI utimes " atime_sec atime_nsec mtime_sec mtime_nsec"
+The utimes command changes the atime and mtime of the current file.
+sec uses UNIX timestamp notation and is the seconds elapsed since
+1970-01-01 00:00:00 UTC.
+nsec is the nanoseconds since the sec. This value needs to be in
+the range 0-999999999 with UTIME_NOW and UTIME_OMIT being exceptions.
+Each (sec, nsec) pair constitutes a single timestamp value.
.SH MEMORY MAPPED I/O COMMANDS
.TP
@@ -875,6 +885,7 @@ verbose output will be printed.
.BR fstatfs (2),
.BR fsync (2),
.BR ftruncate (2),
+.BR futimens (3),
.BR mmap (2),
.BR msync (2),
.BR open (2),
--
2.7.4
The test helps to validate clamping and mount behaviors
according to supported file system timestamp ranges.
Note that the test can fail on 32-bit systems for a
few file systems. This will be corrected when vfs is
transitioned to use 64-bit timestamps.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
---
The branch of the kernel tree can be located at
https://github.com/deepa-hub/vfs refs/heads/vfs_timestamp_policy
The xfs_io patch to add utimes is at
https://www.spinics.net/lists/linux-xfs/msg02952.html
Changes since v1:
* Use xfs_io utimes command
* Updated error handling
* Reorganized code according to review comments
common/rc | 42 +++++++++++
tests/generic/390 | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++
tests/generic/390.out | 2 +
tests/generic/group | 1 +
4 files changed, 242 insertions(+)
create mode 100755 tests/generic/390
create mode 100644 tests/generic/390.out
diff --git a/common/rc b/common/rc
index e3b54ec..93c6e65 100644
--- a/common/rc
+++ b/common/rc
@@ -1960,6 +1960,45 @@ _run_aiodio()
return $status
}
+# this test requires y2038 sysfs switch support
+#
+_require_y2038_sysfs()
+{
+ sysfsdir=/proc/sys/fs/fs-timestamp-check-on
+
+ if [ ! -e $sysfsdir ]; then
+ _notrun "no kernel support for y2038 sysfs switch"
+ fi
+}
+
+_filesystem_timestamp_range()
+{
+ device=${1:-$TEST_DEV}
+ case $FSTYP in
+ ext4)
+ if [ $(dumpe2fs -h $device 2>/dev/null | grep "Inode size:" | cut -d: -f2) -gt 128 ]; then
+ echo "-2147483648 15032385535"
+ else
+ echo "-2147483648 2147483647"
+ fi
+ ;;
+
+ xfs)
+ echo "-2147483648 2147483647"
+ ;;
+ jfs)
+ echo "0 4294967295"
+ ;;
+ f2fs)
+ echo "-2147483648 2147483647"
+ ;;
+ *)
+ echo "-1 -1"
+ _notrun "filesystem $FSTYP timestamp bounds are unknown"
+ ;;
+ esac
+}
+
# indicate whether YP/NIS is active or not
#
_yp_active()
@@ -2070,6 +2109,9 @@ _require_xfs_io_command()
echo $testio | egrep -q "Inappropriate ioctl" && \
_notrun "xfs_io $command support is missing"
;;
+ "utimes" )
+ testio=`$XFS_IO_PROG -f -c "utimes" 0 0 0 0 $testfile 2>&1`
+ ;;
*)
testio=`$XFS_IO_PROG -c "$command help" 2>&1`
esac
diff --git a/tests/generic/390 b/tests/generic/390
new file mode 100755
index 0000000..8ccadad
--- /dev/null
+++ b/tests/generic/390
@@ -0,0 +1,197 @@
+#! /bin/bash
+# FS QA Test 390
+#
+# Tests to verify policy for filesystem timestamps for
+# supported ranges:
+# 1. Verify filesystem rw mount according to sysctl
+# timestamp_supported.
+# 2. Verify timestamp clamping for timestamps beyond max
+# timestamp supported.
+#
+# Exit status 1: either or both tests above fail.
+# Exit status 0: both the above tests pass.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2016 Deepa Dinamani. All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#-----------------------------------------------------------------------
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1 # failure is the default!
+trap "exit \$status" 0 1 2 3 15
+
+# Get standard environment, filters and checks.
+. ./common/rc
+. ./common/filter
+. ./common/attr
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+# Prerequisites for the test run.
+_supported_fs generic
+_supported_os Linux
+_require_scratch
+_require_xfs_io_command utimes
+_require_y2038_sysfs
+
+# Compare file timestamps obtained from stat
+# with a given timestamp.
+check_stat()
+{
+ file=$1
+ timestamp=$2
+
+ stat_timestamp=`stat -c"%X;%Y" $file`
+
+ prev_timestamp="$timestamp;$timestamp"
+ if [ $prev_timestamp != $stat_timestamp ]; then
+ echo "$prev_timestamp != $stat_timestamp" | tee -a $seqres.full
+ exit
+ fi
+}
+
+run_test_individual()
+{
+ file=$1
+ timestamp=$2
+ update_time=$3
+
+ #check if the time needs update
+ if [ $update_time -eq 1 ]; then
+ echo "Updating file: $file to timestamp `date -d @$timestamp`" >> $seqres.full
+ $XFS_IO_PROG -f -c "utimes $timestamp 0 $timestamp 0" $file
+ if [ $? -ne 0 ]; then
+ echo "Failed to update times on $file" | tee -a $seqres.full
+ exit
+ fi
+ fi
+
+ tsclamp=$(($timestamp>$tsmax?$tsmax:$timestamp))
+ echo "Checking file: $file Updated timestamp is `date -d @$tsclamp`" >> $seqres.full
+ check_stat $file $tsclamp
+}
+
+run_test()
+{
+ update_time=$1
+
+ #initialization iterator
+ n=1
+
+ for TIME in "${TIMESTAMPS[@]}"
+ do
+ #Run the test
+ run_test_individual ${SCRATCH_MNT}/test_$n $TIME $update_time
+
+ #update iterator
+ ((n++))
+ done
+}
+
+_scratch_mkfs &>> $seqres.full 2>&1 || _fail "mkfs failed"
+read tsmin tsmax <<<$(_filesystem_timestamp_range $SCRATCH_DEV)
+
+echo min supported timestamp $tsmin $(date --date=@$tsmin) >> $seqres.full
+echo max supported timestamp $tsmax $(date --date=@$tsmax) >> $seqres.full
+
+#Test timestamps array
+
+declare -a TIMESTAMPS=(
+ $tsmin
+ 0
+ $tsmax
+ $((tsmax+1))
+ 4294967295
+ 8589934591
+ 34359738367
+)
+
+# Max timestamp is hardcoded to Mon Jan 18 19:14:07 PST 2038
+sys_tsmax=2147483647
+echo "min timestamp that needs to be supported by fs for rw mount is $sys_tsmax $(date --date=@$sys_tsmax)" >> $seqres.full
+
+read ts_check <<<$(cat /proc/sys/fs/fs-timestamp-check-on)
+
+_scratch_mount
+result=$?
+
+if [ $ts_check -ne 0 ]; then
+ echo "sysctl filesystem timestamp check is on" >> $seqres.full
+ if [ $sys_tsmax -gt $tsmax ]; then
+ if [ $result -eq 0 ]; then
+ echo "mount test failed" | tee -a $seqres.full
+ exit
+ fi
+ else
+ if [ $result -ne 0 ]; then
+ echo "failed to mount $SCRATCH_DEV" | tee -a $seqres.full
+ exit
+ fi
+ fi
+else
+ echo "sysctl filesystem timestamp check is off" >> $seqres.full
+ if [ $result -ne 0 ]; then
+ echo "failed to mount $SCRATCH_DEV and timestamp check is off" >> $seqres.full
+ exit
+ fi
+fi
+
+# Begin test case 1
+echo "In memory timestamps update test start" >> $seqres.full
+
+#update time on the file
+update_time=1
+
+#Run test
+run_test $update_time
+
+echo "In memory timestamps update complete" >> $seqres.full
+
+echo "Unmounting and mounting scratch $SCRATCH_MNT" >> $seqres.full
+
+#unmount and remount $SCRATCH_DEV
+_scratch_cycle_mount
+if [ $? -ne 0 ];then
+ echo "Failed to remount $SCRATCH_DEV" | tee -a $seqres.full
+ exit
+fi
+
+# Begin test case 2
+
+#re-initialize iterator
+n=1
+
+#Do not update time on the file, just read from disk
+update_time=0
+
+echo "On disk timestamps update test start" >> $seqres.full
+
+#Re-run test
+run_test $update_time
+
+echo "On disk timestamps update test complete" >> $seqres.full
+
+echo "y2038 inode timestamp tests completed successfully"
+
+# success, all done
+status=0
+exit
diff --git a/tests/generic/390.out b/tests/generic/390.out
new file mode 100644
index 0000000..82bd4eb
--- /dev/null
+++ b/tests/generic/390.out
@@ -0,0 +1,2 @@
+QA output created by 390
+y2038 inode timestamp tests completed successfully
diff --git a/tests/generic/group b/tests/generic/group
index 08007d7..d137d01 100644
--- a/tests/generic/group
+++ b/tests/generic/group
@@ -392,3 +392,4 @@
387 auto clone
388 auto log metadata
389 auto quick acl
+390 auto quick rw
--
2.7.4
Add the utimes command to provide a way to utilize
the futimens C library call. This is the
interface to the utimensat system call, which updates
the mtime and atime of a file.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
---
Changes since v1:
* changed error return values
* removed redundant roff formatting directive
* removed unneeded argument count check
include/input.h | 1 +
io/Makefile | 2 +-
io/init.c | 1 +
io/io.h | 1 +
io/utimes.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
libxcmd/input.c | 22 +++++++++++++++
man/man8/xfs_io.8 | 11 ++++++++
7 files changed, 118 insertions(+), 1 deletion(-)
create mode 100755 io/utimes.c
mode change 100644 => 100755 libxcmd/input.c
diff --git a/include/input.h b/include/input.h
index d02170f..221678e 100644
--- a/include/input.h
+++ b/include/input.h
@@ -48,6 +48,7 @@ extern uid_t uid_from_string(char *user);
extern gid_t gid_from_string(char *group);
extern prid_t prid_from_string(char *project);
extern bool isdigits_only(const char *str);
+extern int timespec_from_string(const char *sec, const char *nsec, struct timespec *ts);
#define HAVE_FTW_H 1 /* TODO: configure me */
diff --git a/io/Makefile b/io/Makefile
index 62bc03b..392e02a 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -11,7 +11,7 @@ HFILES = init.h io.h
CFILES = init.c \
attr.c bmap.c file.c freeze.c fsync.c getrusage.c imap.c link.c \
mmap.c open.c parent.c pread.c prealloc.c pwrite.c seek.c shutdown.c \
- sync.c truncate.c reflink.c
+ sync.c truncate.c reflink.c utimes.c
LLDLIBS = $(LIBXCMD) $(LIBHANDLE)
LTDEPENDENCIES = $(LIBXCMD) $(LIBHANDLE)
diff --git a/io/init.c b/io/init.c
index efe7390..6319aeb 100644
--- a/io/init.c
+++ b/io/init.c
@@ -85,6 +85,7 @@ init_commands(void)
sync_range_init();
truncate_init();
reflink_init();
+ utimes_init();
}
static int
diff --git a/io/io.h b/io/io.h
index 2bc7ac4..fddd7a3 100644
--- a/io/io.h
+++ b/io/io.h
@@ -113,6 +113,7 @@ extern void seek_init(void);
extern void shutdown_init(void);
extern void sync_init(void);
extern void truncate_init(void);
+extern void utimes_init(void);
#ifdef HAVE_FADVISE
extern void fadvise_init(void);
diff --git a/io/utimes.c b/io/utimes.c
new file mode 100755
index 0000000..faf9b8d
--- /dev/null
+++ b/io/utimes.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 Deepa Dinamani
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "command.h"
+#include "input.h"
+#include "init.h"
+#include "io.h"
+
+static cmdinfo_t utimes_cmd;
+
+static void
+utimes_help(void)
+{
+ printf(_(
+"\n"
+" Update file atime and mtime of the current file with nansecond precision.\n"
+"\n"
+" Usage: utimes atime_sec atime_nsec mtime_sec mtime_nsec.\n"
+" *_sec: Seconds elapsed since 1970-01-01 00:00:00 UTC.\n"
+" *_nsec: Nanoseconds since the corresponding *_sec.\n"
+"\n"));
+}
+
+static int
+utimes_f(
+ int argc,
+ char **argv)
+{
+ struct timespec t[2];
+ int result;
+
+ /* Get the timestamps */
+ result = timespec_from_string(argv[1], argv[2], &t[0]);
+ if (result) {
+ fprintf(stderr, "Bad value for atime\n");
+ return 0;
+ }
+ result = timespec_from_string(argv[3], argv[4], &t[1]);
+ if (result) {
+ fprintf(stderr, "Bad value for mtime\n");
+ return 0;
+ }
+
+ /* Call futimens to update time. */
+ if (futimens(file->fd, t)) {
+ perror("futimens");
+ return 0;
+ }
+
+ return 0;
+}
+
+void
+utimes_init(void)
+{
+ utimes_cmd.name = "utimes";
+ utimes_cmd.cfunc = utimes_f;
+ utimes_cmd.argmin = 4;
+ utimes_cmd.argmax = 4;
+ utimes_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
+ utimes_cmd.args = _("atime_sec atime_nsec mtime_sec mtime_nsec");
+ utimes_cmd.oneline = _("Update file times of the current file");
+ utimes_cmd.help = utimes_help;
+
+ add_command(&utimes_cmd);
+}
diff --git a/libxcmd/input.c b/libxcmd/input.c
old mode 100644
new mode 100755
index 5a7dce3..8aeb3b0
--- a/libxcmd/input.c
+++ b/libxcmd/input.c
@@ -327,6 +327,28 @@ timestr(
}
/*
+ * Convert from a pair of arbitrary user strings into a timespec.
+ */
+
+int
+timespec_from_string(
+ const char * secs,
+ const char * nsecs,
+ struct timespec * ts)
+{
+ char* p;
+ if (!secs || !nsecs || !ts)
+ return 1;
+ ts->tv_sec = strtoull(secs, &p, 0);
+ if (*p)
+ return 1;
+ ts->tv_nsec = strtoull(nsecs, &p, 0);
+ if (*p)
+ return 1;
+ return 0;
+}
+
+/*
* Convert from arbitrary user strings into a numeric ID.
* If it's all numeric, we convert that inplace, else we do
* the name lookup, and return the found identifier.
diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8
index 2c56f09..9efb7b2 100644
--- a/man/man8/xfs_io.8
+++ b/man/man8/xfs_io.8
@@ -589,6 +589,16 @@ Copy data into the open file beginning at
Copy up to
.I length
bytes of data.
+.RE
+.PD
+.TP
+.BI utimes " atime_sec atime_nsec mtime_sec mtime_nsec"
+The utimes command changes the atime and mtime of the current file.
+sec uses UNIX timestamp notation and is the seconds elapsed since
+1970-01-01 00:00:00 UTC.
+nsec is the nanoseconds since the sec. This value needs to be in
+the range 0-999999999 with UTIME_NOW and UTIME_OMIT being exceptions.
+Each (sec, nsec) pair constitutes a single timestamp value.
.SH MEMORY MAPPED I/O COMMANDS
.TP
@@ -875,6 +885,7 @@ verbose output will be printed.
.BR fstatfs (2),
.BR fsync (2),
.BR ftruncate (2),
+.BR futimens (3),
.BR mmap (2),
.BR msync (2),
.BR open (2),
--
2.7.4
Dear Customer,
Your item has arrived at December 26, but our courier was not able to deliver the parcel.
Please check the attachment for details!
Sincerely yours,
Ian Hale,
Mail Delivery Clerk.
Add the utimes command to provide a way to utilize
the futimens C library call. This is the
interface to the utimensat system call, which updates
the mtime and atime of a file.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
---
include/input.h | 1 +
io/Makefile | 2 +-
io/init.c | 1 +
io/io.h | 1 +
io/utimes.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
libxcmd/input.c | 22 +++++++++++++++
man/man8/xfs_io.8 | 12 ++++++++
7 files changed, 122 insertions(+), 1 deletion(-)
create mode 100644 io/utimes.c
diff --git a/include/input.h b/include/input.h
index d02170f..221678e 100644
--- a/include/input.h
+++ b/include/input.h
@@ -48,6 +48,7 @@ extern uid_t uid_from_string(char *user);
extern gid_t gid_from_string(char *group);
extern prid_t prid_from_string(char *project);
extern bool isdigits_only(const char *str);
+extern int timespec_from_string(const char *sec, const char *nsec, struct timespec *ts);
#define HAVE_FTW_H 1 /* TODO: configure me */
diff --git a/io/Makefile b/io/Makefile
index 62bc03b..392e02a 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -11,7 +11,7 @@ HFILES = init.h io.h
CFILES = init.c \
attr.c bmap.c file.c freeze.c fsync.c getrusage.c imap.c link.c \
mmap.c open.c parent.c pread.c prealloc.c pwrite.c seek.c shutdown.c \
- sync.c truncate.c reflink.c
+ sync.c truncate.c reflink.c utimes.c
LLDLIBS = $(LIBXCMD) $(LIBHANDLE)
LTDEPENDENCIES = $(LIBXCMD) $(LIBHANDLE)
diff --git a/io/init.c b/io/init.c
index efe7390..6319aeb 100644
--- a/io/init.c
+++ b/io/init.c
@@ -85,6 +85,7 @@ init_commands(void)
sync_range_init();
truncate_init();
reflink_init();
+ utimes_init();
}
static int
diff --git a/io/io.h b/io/io.h
index 2bc7ac4..fddd7a3 100644
--- a/io/io.h
+++ b/io/io.h
@@ -113,6 +113,7 @@ extern void seek_init(void);
extern void shutdown_init(void);
extern void sync_init(void);
extern void truncate_init(void);
+extern void utimes_init(void);
#ifdef HAVE_FADVISE
extern void fadvise_init(void);
diff --git a/io/utimes.c b/io/utimes.c
new file mode 100644
index 0000000..1465762
--- /dev/null
+++ b/io/utimes.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016 Deepa Dinamani
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "command.h"
+#include "input.h"
+#include "init.h"
+#include "io.h"
+
+static cmdinfo_t utimes_cmd;
+
+static void
+utimes_help(void)
+{
+ printf(_(
+"\n"
+" Update file atime and mtime of the current file with nansecond precision.\n"
+"\n"
+" Usage: utimes atime_sec atime_nsec mtime_sec mtime_nsec.\n"
+" *_sec: Seconds elapsed since 1970-01-01 00:00:00 UTC.\n"
+" *_nsec: Nanoseconds since the corresponding *_sec.\n"
+"\n"));
+}
+
+static int
+utimes_f(
+ int argc,
+ char **argv)
+{
+ struct timespec t[2];
+ int result;
+
+ if (argc != 5)
+ return command_usage(&utimes_cmd);
+
+ /* Get the timestamps */
+ result = timespec_from_string(argv[1], argv[2], &t[0]);
+ if (result) {
+ fprintf(stderr, "Bad value for atime\n");
+ return 1;
+ }
+ result = timespec_from_string(argv[3], argv[4], &t[1]);
+ if (result) {
+ fprintf(stderr, "Bad value for mtime\n");
+ return 1;
+ }
+
+ /* Call futimens to update time. */
+ if (futimens(file->fd, t)) {
+ perror("futimens");
+ return 1;
+ }
+
+ return 0;
+}
+
+void
+utimes_init(void)
+{
+ utimes_cmd.name = "utimes";
+ utimes_cmd.cfunc = utimes_f;
+ utimes_cmd.argmin = 4;
+ utimes_cmd.argmax = 4;
+ utimes_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK;
+ utimes_cmd.args = _("atime_sec atime_nsec mtime_sec mtime_nsec");
+ utimes_cmd.oneline = _("Update file times of the current file");
+ utimes_cmd.help = utimes_help;
+
+ add_command(&utimes_cmd);
+}
diff --git a/libxcmd/input.c b/libxcmd/input.c
index 5a7dce3..2fdb3e8 100644
--- a/libxcmd/input.c
+++ b/libxcmd/input.c
@@ -327,6 +327,28 @@ timestr(
}
/*
+ * Convert from a pair of arbitrary user strings into a timespec.
+ */
+
+int
+timespec_from_string(
+ const char * secs,
+ const char * nsecs,
+ struct timespec * ts)
+{
+ char* p;
+ if (!secs || !nsecs || !ts)
+ return -1;
+ ts->tv_sec = strtoull(secs, &p, 0);
+ if (*p)
+ return -1;
+ ts->tv_nsec = strtoull(nsecs, &p, 0);
+ if (*p)
+ return -1;
+ return 0;
+}
+
+/*
* Convert from arbitrary user strings into a numeric ID.
* If it's all numeric, we convert that inplace, else we do
* the name lookup, and return the found identifier.
diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8
index 2c56f09..3ffe439 100644
--- a/man/man8/xfs_io.8
+++ b/man/man8/xfs_io.8
@@ -589,6 +589,17 @@ Copy data into the open file beginning at
Copy up to
.I length
bytes of data.
+.RE
+.PD
+.TP
+.TP
+.BI utimes " atime_sec atime_nsec mtime_sec mtime_nsec"
+The utimes command changes the atime and mtime of the current file.
+sec uses UNIX timestamp notation and is the seconds elapsed since
+1970-01-01 00:00:00 UTC.
+nsec is the nanoseconds since the sec. This value needs to be in
+the range 0-999999999 with UTIME_NOW and UTIME_OMIT being exceptions.
+Each (sec, nsec) pair constitutes a single timestamp value.
.SH MEMORY MAPPED I/O COMMANDS
.TP
@@ -875,6 +886,7 @@ verbose output will be printed.
.BR fstatfs (2),
.BR fsync (2),
.BR ftruncate (2),
+.BR futimens (3),
.BR mmap (2),
.BR msync (2),
.BR open (2),
--
2.7.4
Dear Customer,
This is to confirm that one or more of your parcels has been shipped.
Please, download Delivery Label attached to this email.
Thank you for choosing FedEx,
Randall Schneider,
Station Manager.
I will post xfs tests that validate mount and range checking.
I will keep the policy same as what the RFC suggests for now.
Clamping can be verified once vfs is transitioned to using time64_t.
Thanks,
Deepa
The series is aimed at adding timestamp checking and policy
related to it to vfs.
The series was developed with discussions and guidance from
Arnd Bergmann.
The original idea for the series was the discussion:
https://lkml.org/lkml/2014/5/30/551
Patches 5 and 6 can be merged only after vfs is transitioned
to use 64 bit timestamps as noted in the respective commit
texts.
The series only includes adding range limits to filesystems:
ext4 and afs as examples to keep the series simple.
Every filesystem will be updated to add these limits.
There is an ext4 current_time() api replacement patch that the
series depends on:
https://lkml.org/lkml/2016/6/9/38 .
This needs reposting to the mailing list.
The branch for the tree along with dependency can be found at
https://github.com/deepa-hub/vfs.git refs/heads/vfs_timestamp_policy
Deepa Dinamani (6):
vfs: Add file timestamp range support
vfs: Add checks for filesystem timestamp limits
afs: Add time limits in the super block
ext4: Initialize timestamps limits
vfs: Add timestamp_truncate() api
utimes: Clamp the timestamps before update
fs/afs/super.c | 2 ++
fs/ext4/ext4.h | 4 ++++
fs/ext4/super.c | 7 ++++++-
fs/inode.c | 37 ++++++++++++++++++++++++++++++++++++-
fs/internal.h | 2 ++
fs/libfs.c | 4 ++++
fs/namespace.c | 12 ++++++++++++
fs/super.c | 8 ++++++++
fs/utimes.c | 17 +++++++++++++----
include/linux/fs.h | 4 ++++
include/linux/time64.h | 6 ++++++
include/uapi/linux/fs.h | 6 +++++-
kernel/sysctl.c | 7 +++++++
13 files changed, 109 insertions(+), 7 deletions(-)
--
2.7.4
Cc: linux-afs(a)lists.infradead.org
Cc: "Theodore Ts'o" <tytso(a)mit.edu>
Cc: Andreas Dilger <adilger.kernel(a)dilger.ca>
Cc: linux-ext4(a)vger.kernel.org
Reposting the series as I did not hear comments from the
maintainers.
The series is aimed at making input events y2038 safe.
It extends the lifetime of the realtime timestamps in the
events to year 2106.
The plan is to deprecate realtime timestamps anyway as they
are not appropriate for these timestamps as noted in the patch
a80b83b7b8 by John Stultz.
The series is a result of many discussions with Arnd Bergmann.
The design updates the format of the input events read/ written
to the device nodes. This structure and the uapi/input.h
header file are copied across many userspace libraries.
These libraries not only use this struct input_event locally,
but also expose interfaces that contain input_event. To maintain
backward compatibility with all these interfaces, kernel
updates the format of the input events at the dev node to
struct raw_input_event. Kernel also maintains the old struct
input_event and provides apis to convert between the old and new
input event types.
The userspace library changes to libevdev, libuinput and mtdev
will be posted to the respective mailing groups for review.
Once there is a consensus on the design, all the changes dependent
on the kernel change will be merged at the same time.
Changes from v1:
* Updated changes according to review comments.
* Posted userspace library changes that go along with the series.
Deepa Dinamani (4):
uinput: Add ioctl for using monotonic/ boot times
input: evdev: Replace timeval with timespec64
input: Deprecate real timestamps beyond year 2106
input: serio: Replace timeval by timespec64
drivers/input/evdev.c | 57 ++++++++++++++++++++----------------
drivers/input/input-compat.c | 29 ++++++++++---------
drivers/input/input-compat.h | 19 +++++++-----
drivers/input/misc/uinput.c | 62 +++++++++++++++++++++++++++++++++++++---
drivers/input/serio/hil_mlc.c | 37 ++++++++++++------------
drivers/input/serio/hp_sdc.c | 17 +++++------
drivers/input/serio/hp_sdc_mlc.c | 10 +++----
include/linux/hil_mlc.h | 6 ++--
include/linux/hp_sdc.h | 6 ++--
include/linux/uinput.h | 3 +-
include/uapi/linux/input.h | 47 ++++++++++++++++++++++++++++++
include/uapi/linux/uinput.h | 3 ++
12 files changed, 208 insertions(+), 88 deletions(-)
--
2.7.4
Dear Customer,
This is to confirm that one or more of your parcels has been shipped.
Shipment Label is attached to this email.
Yours trully,
Kurt Richardson,
FedEx Delivery Manager.
struct timespec is not y2038 safe.
Audit timestamps are recorded in string format into
an audit buffer for a given context.
These mark the entry timestamps for the syscalls.
Use y2038 safe struct timespec64 to represent the times.
The log strings can handle this transition as strings can
hold upto 1024 characters.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
Reviewed-by: Arnd Bergmann <arnd(a)arndb.de>
Acked-by: Paul Moore <paul(a)paul-moore.com>
Acked-by: Richard Guy Briggs <rgb(a)redhat.com>
Cc: Eric Paris <eparis(a)redhat.com>
Cc: Paul Moore <paul(a)paul-moore.com>
Cc: Richard Guy Briggs <rgb(a)redhat.com>
Cc: linux-audit(a)redhat.com
---
include/linux/audit.h | 4 ++--
kernel/audit.c | 10 +++++-----
kernel/audit.h | 2 +-
kernel/auditsc.c | 6 +++---
4 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 9d4443f..e51782b 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -332,7 +332,7 @@ static inline void audit_ptrace(struct task_struct *t)
/* Private API (for audit.c only) */
extern unsigned int audit_serial(void);
extern int auditsc_get_stamp(struct audit_context *ctx,
- struct timespec *t, unsigned int *serial);
+ struct timespec64 *t, unsigned int *serial);
extern int audit_set_loginuid(kuid_t loginuid);
static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
@@ -490,7 +490,7 @@ static inline void __audit_seccomp(unsigned long syscall, long signr, int code)
static inline void audit_seccomp(unsigned long syscall, long signr, int code)
{ }
static inline int auditsc_get_stamp(struct audit_context *ctx,
- struct timespec *t, unsigned int *serial)
+ struct timespec64 *t, unsigned int *serial)
{
return 0;
}
diff --git a/kernel/audit.c b/kernel/audit.c
index a8a91bd..b03b6c7 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1325,10 +1325,10 @@ unsigned int audit_serial(void)
}
static inline void audit_get_stamp(struct audit_context *ctx,
- struct timespec *t, unsigned int *serial)
+ struct timespec64 *t, unsigned int *serial)
{
if (!ctx || !auditsc_get_stamp(ctx, t, serial)) {
- *t = CURRENT_TIME;
+ ktime_get_real_ts64(t);
*serial = audit_serial();
}
}
@@ -1370,7 +1370,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
int type)
{
struct audit_buffer *ab = NULL;
- struct timespec t;
+ struct timespec64 t;
unsigned int uninitialized_var(serial);
int reserve = 5; /* Allow atomic callers to go up to five
entries over the normal backlog limit */
@@ -1422,8 +1422,8 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
audit_get_stamp(ab->ctx, &t, &serial);
- audit_log_format(ab, "audit(%lu.%03lu:%u): ",
- t.tv_sec, t.tv_nsec/1000000, serial);
+ audit_log_format(ab, "audit(%llu.%03lu:%u): ",
+ (unsigned long long)t.tv_sec, t.tv_nsec/1000000, serial);
return ab;
}
diff --git a/kernel/audit.h b/kernel/audit.h
index 431444c..55d1ca2 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -112,7 +112,7 @@ struct audit_context {
enum audit_state state, current_state;
unsigned int serial; /* serial number for record */
int major; /* syscall number */
- struct timespec ctime; /* time of syscall entry */
+ struct timespec64 ctime; /* time of syscall entry */
unsigned long argv[4]; /* syscall arguments */
long return_code;/* syscall return code */
u64 prio;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 5abf1dc..8dc7fe9 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1522,7 +1522,7 @@ void __audit_syscall_entry(int major, unsigned long a1, unsigned long a2,
return;
context->serial = 0;
- context->ctime = CURRENT_TIME;
+ ktime_get_real_ts64(&context->ctime);
context->in_syscall = 1;
context->current_state = state;
context->ppid = 0;
@@ -1931,13 +1931,13 @@ EXPORT_SYMBOL_GPL(__audit_inode_child);
/**
* auditsc_get_stamp - get local copies of audit_context values
* @ctx: audit_context for the task
- * @t: timespec to store time recorded in the audit_context
+ * @t: timespec64 to store time recorded in the audit_context
* @serial: serial value that is recorded in the audit_context
*
* Also sets the context as auditable.
*/
int auditsc_get_stamp(struct audit_context *ctx,
- struct timespec *t, unsigned int *serial)
+ struct timespec64 *t, unsigned int *serial)
{
if (!ctx->in_syscall)
return 0;
--
2.7.4
struct timespec is not y2038 safe.
Use time64_t which is y2038 safe to represent orphan
scan times.
time64_t is sufficient here as only the seconds delta
times are relevant.
Also use appropriate time functions that return time in
time64_t format. Time functions now return monotonic
time instead of real time as only delta scan times are
relevant and these values are not persistent across
reboots.
The format string for the debug print is still using long
as this is only the time elapsed since the last scan and
long is sufficient to represent this value.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
Reviewed-by: Arnd Bergmann <arnd(a)arndb.de>
Cc: Mark Fasheh <mfasheh(a)suse.com>
Cc: Joel Becker <jlbec(a)evilplan.org>
Cc: ocfs2-devel(a)oss.oracle.com
---
fs/ocfs2/journal.c | 4 ++--
fs/ocfs2/ocfs2.h | 2 +-
fs/ocfs2/super.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index a244f14..d5e5fa7 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -1947,7 +1947,7 @@ static void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
*/
seqno++;
os->os_count++;
- os->os_scantime = CURRENT_TIME;
+ os->os_scantime = ktime_get_seconds();
unlock:
ocfs2_orphan_scan_unlock(osb, seqno);
out:
@@ -2004,7 +2004,7 @@ void ocfs2_orphan_scan_start(struct ocfs2_super *osb)
struct ocfs2_orphan_scan *os;
os = &osb->osb_orphan_scan;
- os->os_scantime = CURRENT_TIME;
+ os->os_scantime = ktime_get_seconds();
if (ocfs2_is_hard_readonly(osb) || ocfs2_mount_local(osb))
atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE);
else {
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index e63af7d..7e5958b 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -224,7 +224,7 @@ struct ocfs2_orphan_scan {
struct ocfs2_super *os_osb;
struct ocfs2_lock_res os_lockres; /* lock to synchronize scans */
struct delayed_work os_orphan_scan_work;
- struct timespec os_scantime; /* time this node ran the scan */
+ time64_t os_scantime; /* time this node ran the scan */
u32 os_count; /* tracks node specific scans */
u32 os_seqno; /* tracks cluster wide scans */
atomic_t os_state; /* ACTIVE or INACTIVE */
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 603b28d..bf3ca30 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -337,7 +337,7 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len)
out += snprintf(buf + out, len - out, "Disabled\n");
else
out += snprintf(buf + out, len - out, "%lu seconds ago\n",
- (get_seconds() - os->os_scantime.tv_sec));
+ (unsigned long)(ktime_get_seconds() - os->os_scantime));
out += snprintf(buf + out, len - out, "%10s => %3s %10s\n",
"Slots", "Num", "RecoGen");
--
2.7.4
btrfs_root_item maintains the ctime for root updates.
This is not part of vfs_inode.
Since current_time() uses struct inode* as an argument
as Linus suggested, this cannot be used to update root
times unless, we modify the signature to use inode.
Since btrfs uses nanosecond time granularity, it can also
use ktime_get_real_ts directly to obtain timestamp for
the root. It is necessary to use the timespec time api
here because the same btrfs_set_stack_timespec_*() apis
are used for vfs inode times as well. These can be
transitioned to using timespec64 when btrfs internally
changes to use timespec64 as well.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
Cc: Chris Mason <clm(a)fb.com>
Cc: David Sterba <dsterba(a)suse.com>
Cc: Josef Bacik <jbacik(a)fb.com>
Cc: linux-btrfs(a)vger.kernel.org
---
Changes from previous version:
* Separated from the current_time() api series.
* Moved ktime_get_real_ts() outside of spin lock.
fs/btrfs/root-tree.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 0912960..17e5a5f 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -505,8 +505,9 @@ void btrfs_update_root_times(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
struct btrfs_root_item *item = &root->root_item;
- struct timespec ct = current_fs_time(root->fs_info->sb);
+ struct timespec ct;
+ ktime_get_real_ts(&ct);
spin_lock(&root->root_item_lock);
btrfs_set_root_ctransid(item, trans->transid);
btrfs_set_stack_timespec_sec(&item->ctime, ct.tv_sec);
--
2.7.4
This is in preparation for the change that transitions
filesystem timestamps to use 64 bit time and hence make
them y2038 safe.
CURRENT_TIME macro will be deleted before merging the
aforementioned patch.
Filesystems will use current_time() instead of
CURRENT_TIME.
Use ktime_get_real_seconds() here as this is not filesystem
time.
Only the seconds portion of the timestamp is necessary for
timezone calculation using server time.
Assume that the difference between server and client times
lie in the range INT_MIN..INT_MAX. This is valid because
this is the difference between current times between server
and client, and the largest timezone difference is in the
range of one day.
All cifs timestamps currently use timespec internally.
This timestamp can also be transitioned into using
timespec64 when all other timestamps for cifs is transitioned
to use timespec64.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
Reviewed-by: Arnd Bergmann <arnd(a)arndb.de>
Cc: Steve French <sfrench(a)samba.org>
---
fs/cifs/cifssmb.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index d47197e..6c666a3 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -478,14 +478,14 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
* this requirement.
*/
int val, seconds, remain, result;
- struct timespec ts, utc;
- utc = CURRENT_TIME;
+ struct timespec ts;
+ unsigned long utc = ktime_get_real_seconds();
ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
rsp->SrvTime.Time, 0);
cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
- (int)ts.tv_sec, (int)utc.tv_sec,
- (int)(utc.tv_sec - ts.tv_sec));
- val = (int)(utc.tv_sec - ts.tv_sec);
+ (int)ts.tv_sec, (int)utc,
+ (int)(utc - ts.tv_sec));
+ val = (int)(utc - ts.tv_sec);
seconds = abs(val);
result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
remain = seconds % MIN_TZ_ADJ;
--
2.7.4
This is in preparation for the patch that transitions
vfs timestamps to use 64 bit time and hence make them
y2038 safe.
CURRENT_TIME macro will be deleted before merging the
aforementioned patch.
Filesystem times will use current_fs_time() instead of
CURRENT_TIME.
Use ktime_get_real_ts() here as this is not filesystem time.
ktime_get_real_ts() returns the timestamp in ns which can
be used to calculate network time for NTLMv2 authentication
timestamp.
All cifs timestamps currently use timespec internally.
This timestamp can also be transitioned into using
timespec64 when all other timestamps for cifs is transitioned
to use timespec64.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
Reviewed-by: Arnd Bergmann <arnd(a)arndb.de>
Cc: Steve French <sfrench(a)samba.org>
---
fs/cifs/cifsencrypt.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 8347c90..fd01bf0 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -471,6 +471,7 @@ find_timestamp(struct cifs_ses *ses)
unsigned char *blobptr;
unsigned char *blobend;
struct ntlmssp2_name *attrptr;
+ struct timespec ts;
if (!ses->auth_key.len || !ses->auth_key.response)
return 0;
@@ -495,7 +496,8 @@ find_timestamp(struct cifs_ses *ses)
blobptr += attrsize; /* advance attr value */
}
- return cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
+ ktime_get_real_ts(&ts);
+ return cpu_to_le64(cifs_UnixTimeToNT(ts));
}
static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
--
2.7.4
On Wednesday, June 22, 2016 12:58:38 AM CEST Albert ARIBAUD wrote:
> Hi all,
>
> I have produced a fourth draft of what will eventually become the Y2038
> design document:
>
> https://sourceware.org/glibc/wiki/Y2038ProofnessDesign?rev=83
>
> Relative to the previous draft:
>
> * the scope clarifies that *only* Y2038 is considered, and no other
> doomsday such as Y2106 or Y9999;
>
> * all types directly or indirectly derived from time_t are now listed;
>
> * all APIs using these types are now listed;
>
> * all functions which use time_t internally are now listed;
>
> * also listed are types and APIs related to time but which are
> Y2038-safe (even though they might be unsafe for some other
> doomsday, e.g. struct rpc_timeval being Y2106-unsafe).
>
> As always, comments welcome.
I've cross-checked your list of data structures with the one I have
for the kernel at
https://docs.google.com/spreadsheets/d/1HCYwHXxs48TsTb6IGUduNjQnmfRvMPzCN6T…
I noticed 'struct sysinfo' as another interface that holds a time,
even though this is documented as 'long' and I concluded that we
won't need to change it, that should probably be documented.
'struct rusage' is also interesting, as there is no overflow in 2038,
but instead it could overflow on large machines (hundreds of CPUs)
with very long-running tasks (months), so I'm unsure how to treat that
from the kernel side. It's also one of very few kernel interfaces using
'timeval' rather than 'timespec' (we generally replaced the other ones).
My current kernel patch series changes rusage by using 64-bit fields for
everything, with the intention of having the same binary layout for
32-bit and 64-bit processes, and reusing the 64-bit syscall entry point
for compat mode (running 32-bit tasks on a 64-bit kernel). Does that work
for you?
I think we should expand the ioctl section a bit: I can do most of it
in the kernel, but need help from glibc for a few things in which we
need to agree on calling conventions. Here is what I'd suggest having in
the document, feel free to take that into your document or edit as you
wish:
== IOCTLs and Y2038 ==
Some Linux IOCTLs may be Y2038-unsafe, or use types defined by glibc
that do not match the kernel internal types. Known important cases are:
- An ioctl command number is defined using the _IOR/_IOW/_IORW macros
by the kernel with a structure whose size changes based on glibc's
time_t. The kernel can handle these transparently by implementing
handlers for both command numbers with the correct structure format.
- The binary ABI changes based on the glibc time_t type, but the
command number does not change. In this case, the kernel header files
defining the data structure will check the "__USE_TIME_BITS64"
macro [do we need a new macro for the kernel headers?] to provide
a different command number for the new data structure layout. glibc
will define this macro at an appropriate location [where?] to make
it visible before including kernel header files.
- An ioctl command passes time information in a structure that is not
based on time_t but another integer type that does not get changed.
The kernel header files will provide both a new structure layout
and command number when "__USE_TIME_BITS64" is set.
[I can find examples for ioctl commands in each of those
categories if needed.]
== Socket options ==
Like ioctl(), setsockopt()/getsockopt() has a few interfaces that are
passing time data:
SO_TIMESTAMP/SO_TIMESTAMPNS/SO_TIMESTAMPING: These enable the
timestamping infrastructure for a socket, which will consecutively
return data to user space using "cmsg" data on the socket. The kernel
does not know the layout of 'struct timespec' and 'struct timeval'
when filling the cmsg data, so we need to define new binary values
for the three flags, which then get used if __USE_TIME_BITS64
is set.
SO_RCVTIMEO/SO_SNTTIMEO: These pass a 'struct timeval' and a length.
Assuming that the 'optlen' argument of the setsockopt syscall always
matches the size of 'struct timeval', the kernel will be able to
access the data in the same format that was passed by glibc. [alternatively,
we could handle this the same way as SO_TIMESTAMP*, using new numbers
for the flags].
[end quote]
Regarding the "Support for non-Y2038-safe kernels" section, I'm not
sure if that can work at all: A kernel that does not have the appropriate
system calls will also not have the handlers for a lot of the ioctl
commands and possibly other interfaces that rely on a specific
structure layout. If we can instead enforce that __USE_TIME_BITS64
is only set with a minimal version of kernel headers and that it
implies binary compatibility with no older kernel version, we could
avoid those problems.
On your note "The implementation needs further thinking about, as
application code defining _TIME_BITS=64 and gets built against
new kernel headers and old GLIBC headers, then GLIBC will use 32-bit
time_t and kernel will expect 64-bit time_t, and there is no way
to ensure detection of this case.", I think that is covered by
having the kernel headers check __USE_TIME_BITS64 instead of
_TIME_BITS=64, as I described above.
Arnd
Dear Customer,
Courier was unable to deliver the parcel to you.
You can review complete details of your order in the find attached.
Thank you for choosing FedEx,
Dan Flowers,
Sr. Station Manager.
Dear Customer,
We could not deliver your item.
Please, download Delivery Label attached to this email.
Yours sincerely,
Ross Helton,
FedEx Station Manager.
Dear Customer,
Courier was unable to deliver the parcel to you.
Delivery Label is attached to this email.
Yours faithfully,
Maurice Dillon,
Sr. Station Manager.
Dear Customer,
Your parcel has arrived at September 18. Courier was unable to deliver the parcel to you.
Shipment Label is attached to email.
Sincerely,
Walter Fletcher,
FedEx Station Manager.
Dear Customer,
Courier was unable to deliver the parcel to you.
Delivery Label is attached to this email.
Yours faithfully,
Albert Joyce,
Sr. Operation Manager.
The series is aimed at making input events y2038 safe.
It extends the lifetime of the realtime timestamps in the
events to year 2106.
The plan is to deprecate realtime timestamps anyway as they
are not appropriate for these timestamps as noted in the patch
a80b83b7b8 by John Stultz.
The series is a result of many discussions with Arnd Bergmann.
Deepa Dinamani (4):
uinput: Add ioctl for using monotonic/ boot times
input: evdev: Replace timeval with timespec64
input: Deprecate real timestamps beyond year 2106
input: serio: Replace timeval by timespec64
drivers/input/evdev.c | 30 +++++++++++--------
drivers/input/input-compat.c | 25 ++++++++--------
drivers/input/input-compat.h | 19 +++++++-----
drivers/input/misc/uinput.c | 64 +++++++++++++++++++++++++++++++++++++---
drivers/input/serio/hil_mlc.c | 37 +++++++++++------------
drivers/input/serio/hp_sdc.c | 17 ++++++-----
drivers/input/serio/hp_sdc_mlc.c | 10 +++----
include/linux/hil_mlc.h | 6 ++--
include/linux/hp_sdc.h | 6 ++--
include/linux/uinput.h | 3 +-
include/uapi/linux/input.h | 37 +++++++++++++++++++++++
include/uapi/linux/uinput.h | 3 ++
12 files changed, 183 insertions(+), 74 deletions(-)
--
2.7.4
Dear Customer,
Courier was unable to deliver the parcel to you.
You can review complete details of your order in the find attached.
Kind regards,
Ivan Fletcher,
FedEx Station Manager.
Dear Customer,
This is to confirm that one or more of your parcels has been shipped.
You can review complete details of your order in the find attached.
Kind regards,
Edwin Bond,
Sr. Delivery Manager.
The md code stores the exact time of the last error in the
last_read_error variable using a timespec structure. It only
ever uses the seconds portion of that though, so we can
use a scalar for it.
There won't be an overflow in 2038 here, because it already
used monotonic time and 32-bit is enough for that, but I've
decided to use time64_t for consistency in the conversion.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/md/md.c | 3 +--
drivers/md/md.h | 2 +-
drivers/md/raid10.c | 11 +++++------
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 3745b9a7a2d7..ad512ad4610f 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3179,8 +3179,7 @@ int md_rdev_init(struct md_rdev *rdev)
rdev->data_offset = 0;
rdev->new_data_offset = 0;
rdev->sb_events = 0;
- rdev->last_read_error.tv_sec = 0;
- rdev->last_read_error.tv_nsec = 0;
+ rdev->last_read_error = 0;
rdev->sb_loaded = 0;
rdev->bb_page = NULL;
atomic_set(&rdev->nr_pending, 0);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 3c3412d85e42..20c667579ede 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -99,7 +99,7 @@ struct md_rdev {
atomic_t read_errors; /* number of consecutive read errors that
* we have tried to ignore.
*/
- struct timespec last_read_error; /* monotonic time since our
+ time64_t last_read_error; /* monotonic time since our
* last read error
*/
atomic_t corrected_errors; /* number of corrected read errors,
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 41191e04d565..f8cdd08d0a40 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2170,21 +2170,20 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio)
*/
static void check_decay_read_errors(struct mddev *mddev, struct md_rdev *rdev)
{
- struct timespec cur_time_mon;
+ long cur_time_mon;
unsigned long hours_since_last;
unsigned int read_errors = atomic_read(&rdev->read_errors);
- ktime_get_ts(&cur_time_mon);
+ cur_time_mon = ktime_get_seconds();
- if (rdev->last_read_error.tv_sec == 0 &&
- rdev->last_read_error.tv_nsec == 0) {
+ if (rdev->last_read_error == 0) {
/* first time we've seen a read error */
rdev->last_read_error = cur_time_mon;
return;
}
- hours_since_last = (cur_time_mon.tv_sec -
- rdev->last_read_error.tv_sec) / 3600;
+ hours_since_last = (long)(cur_time_mon -
+ rdev->last_read_error) / 3600;
rdev->last_read_error = cur_time_mon;
--
2.9.0
The jbd2 journal stores the commit time in 64-bit seconds and 32-bit
nanoseconds, which avoids an overflow in 2038, but it gets the numbers
from current_kernel_time(), which uses 'long' seconds on 32-bit
architectures.
This simply changes the code to call current_kernel_time64() so
we use 64-bit seconds consistently.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
fs/jbd2/commit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
index 8f7d1339c973..5bb565f9989c 100644
--- a/fs/jbd2/commit.c
+++ b/fs/jbd2/commit.c
@@ -124,7 +124,7 @@ static int journal_submit_commit_record(journal_t *journal,
struct commit_header *tmp;
struct buffer_head *bh;
int ret;
- struct timespec now = current_kernel_time();
+ struct timespec64 now = current_kernel_time64();
*cbh = NULL;
--
2.9.0
Hi John, Herbert,
Changes v2: use ktime_get_ns instead of ktime_get_raw_ns
The testing was re-performed and indicate no difference to the previous testing.
Ciao
Stephan
---8<---
As part of the Y2038 development, __getnstimeofday is not supposed to be
used any more. It is now replaced with ktime_get_ns. The Jitter RNG uses
the time stamp to measure the execution time of a given code path and
tries to detect variations in the execution time. Therefore, the only
requirement the Jitter RNG has, is a sufficient high resolution to
detect these variations.
The change was tested on x86 to show an identical behavior as RDTSC. The
used test code simply measures the execution time of the heart of the
RNG:
jent_get_nstime(&time);
jent_memaccess(ec, min);
jent_fold_time(NULL, time, &folded, min);
jent_get_nstime(&time2);
return ((time2 - time));
Signed-off-by: Stephan Mueller <smueller(a)chronox.de>
---
crypto/jitterentropy-kcapi.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index 597cedd..be1577c 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -87,24 +87,28 @@ void jent_memcpy(void *dest, const void *src, unsigned int n)
memcpy(dest, src, n);
}
+/*
+ * Obtain a high-resolution time stamp value. The time stamp is used to measure
+ * the execution time of a given code path and its variations. Hence, the time
+ * stamp must have a sufficiently high resolution.
+ *
+ * Note, if the function returns zero because a given architecture does not
+ * implement a high-resolution time stamp, the RNG code's runtime test
+ * will detect it and will not produce output.
+ */
void jent_get_nstime(__u64 *out)
{
- struct timespec ts;
__u64 tmp = 0;
tmp = random_get_entropy();
/*
- * If random_get_entropy does not return a value (which is possible on,
- * for example, MIPS), invoke __getnstimeofday
+ * If random_get_entropy does not return a value, i.e. it is not
+ * implemented for a given architecture, use a clock source.
* hoping that there are timers we can work with.
*/
- if ((0 == tmp) &&
- (0 == __getnstimeofday(&ts))) {
- tmp = ts.tv_sec;
- tmp = tmp << 32;
- tmp = tmp | ts.tv_nsec;
- }
+ if (tmp == 0)
+ tmp = ktime_get_ns();
*out = tmp;
}
--
2.5.5
KVM reads the current boottime value as a struct timespec in order to
calculate the guest wallclock time, resulting in an overflow in 2038
on 32-bit systems.
The data then gets passed as an unsigned 32-bit number to the guest,
and that in turn overflows in 2106.
We cannot do much about the second overflow, which affects both 32-bit
and 64-bit hosts, but we can ensure that they both behave the same
way and don't overflow until 2106, by using getboottime64() to read
a timespec64 value.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
arch/x86/kvm/x86.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 53241618e3c9..f79c86510408 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1163,7 +1163,7 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
int version;
int r;
struct pvclock_wall_clock wc;
- struct timespec boot;
+ struct timespec64 boot;
if (!wall_clock)
return;
@@ -1186,13 +1186,13 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
* wall clock specified here. guest system time equals host
* system time for us, thus we must fill in host boot time here.
*/
- getboottime(&boot);
+ getboottime64(&boot);
if (kvm->arch.kvmclock_offset) {
- struct timespec ts = ns_to_timespec(kvm->arch.kvmclock_offset);
- boot = timespec_sub(boot, ts);
+ struct timespec64 ts = ns_to_timespec64(kvm->arch.kvmclock_offset);
+ boot = timespec64_sub(boot, ts);
}
- wc.sec = boot.tv_sec;
+ wc.sec = (u32)boot.tv_sec; /* overflow in 2106 guest time */
wc.nsec = boot.tv_nsec;
wc.version = version;
--
2.9.0
As part of the Y2038 development, __getnstimeofday is not supposed to be
used any more. It is now replaced with ktime_get_raw_ns. Albeit
ktime_get_raw_ns is monotonic compared to __getnstimeofday, this
difference is irrelevant as the Jitter RNG uses the time stamp to
measure the execution time of a given code path and tries to detect
variations in the execution time. Therefore, the only requirement the
Jitter RNG has, is a sufficient high resolution to detect these
variations.
The change was tested on x86 to show an identical behavior as RDTSC. The
used test code simply measures the execution time of the heart of the
RNG:
jent_get_nstime(&time);
jent_memaccess(ec, min);
jent_fold_time(NULL, time, &folded, min);
jent_get_nstime(&time2);
return ((time2 - time));
Signed-off-by: Stephan Mueller <smueller(a)chronox.de>
---
crypto/jitterentropy-kcapi.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index 597cedd..69a2988 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -87,24 +87,29 @@ void jent_memcpy(void *dest, const void *src, unsigned int n)
memcpy(dest, src, n);
}
+/*
+ * Obtain a high-resolution time stamp value. The time stamp is used to measure
+ * the execution time of a given code path and its variations. Hence, the time
+ * stamp must have a sufficiently high resolution. It is valid if the time
+ * runs backwards for short period of time as the RNG code is able handle that.
+ *
+ * Note, if the function returns zero because a given architecture does not
+ * implement a high-resolution time stamp, the RNG code's runtime test
+ * will detect it and will not produce output.
+ */
void jent_get_nstime(__u64 *out)
{
- struct timespec ts;
__u64 tmp = 0;
tmp = random_get_entropy();
/*
- * If random_get_entropy does not return a value (which is possible on,
- * for example, MIPS), invoke __getnstimeofday
+ * If random_get_entropy does not return a value, i.e. it is not
+ * implemented for a given architecture, invoke ktime_get_raw_ns
* hoping that there are timers we can work with.
*/
- if ((0 == tmp) &&
- (0 == __getnstimeofday(&ts))) {
- tmp = ts.tv_sec;
- tmp = tmp << 32;
- tmp = tmp | ts.tv_nsec;
- }
+ if (tmp == 0)
+ tmp = ktime_get_raw_ns();
*out = tmp;
}
--
2.5.5
The jent_get_nstime() function uses __getnstimeofday() to get
something similar to a 64-bit nanosecond counter. As we want
to get rid of struct timespec to fix the y2038 overflow,
this patch changes the code to use __getnstimeofday64()
instead, which returns a timespec64 structure.
Nothing changes about the algorithm, but it looks like it
might be better to use
*out = ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec;
or even
*out = ktime_get_raw_fast_ns();
to get an actual nanosecond value and avoid the predictable
jitter that happens at the end of a second. Checking whether
or not this would be good needs investigation by someone who
understands the code better than me.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
crypto/jitterentropy-kcapi.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c
index 597cedd3531c..82ac44eff20d 100644
--- a/crypto/jitterentropy-kcapi.c
+++ b/crypto/jitterentropy-kcapi.c
@@ -89,7 +89,7 @@ void jent_memcpy(void *dest, const void *src, unsigned int n)
void jent_get_nstime(__u64 *out)
{
- struct timespec ts;
+ struct timespec64 ts;
__u64 tmp = 0;
tmp = random_get_entropy();
@@ -98,9 +98,11 @@ void jent_get_nstime(__u64 *out)
* If random_get_entropy does not return a value (which is possible on,
* for example, MIPS), invoke __getnstimeofday
* hoping that there are timers we can work with.
+ *
+ * should we have a __ktime_get_ns() instead?
*/
if ((0 == tmp) &&
- (0 == __getnstimeofday(&ts))) {
+ (0 == __getnstimeofday64(&ts))) {
tmp = ts.tv_sec;
tmp = tmp << 32;
tmp = tmp | ts.tv_nsec;
--
2.9.0
The fc_get_host_stats() function contains a complex conversion
from jiffies to timespec to seconds. As we try to get rid of
uses of struct timespec, we can clean this up and replace it
with a simpler computation.
Simply dividing the difference in jiffies by HZ is not only
much more efficient, it also avoids a problem that causes the
seconds_since_last_reset value to be incorrect if jiffies has
overrun since the 'boot_time' value was recorded.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/scsi/libfc/fc_lport.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index e01a29863c38..99c6d9251404 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -301,7 +301,6 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
{
struct fc_host_statistics *fc_stats;
struct fc_lport *lport = shost_priv(shost);
- struct timespec v0, v1;
unsigned int cpu;
u64 fcp_in_bytes = 0;
u64 fcp_out_bytes = 0;
@@ -309,9 +308,7 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
fc_stats = &lport->host_stats;
memset(fc_stats, 0, sizeof(struct fc_host_statistics));
- jiffies_to_timespec(jiffies, &v0);
- jiffies_to_timespec(lport->boot_time, &v1);
- fc_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec);
+ fc_stats->seconds_since_last_reset = (lport->boot_time - jiffies) / HZ;
for_each_possible_cpu(cpu) {
struct fc_stats *stats;
--
2.9.0
Jeff Moyer looked up the blktrace source to see if an overflow might
happen. The situation is as follows:
- The time stamp is not used by the program itself, only for
printing human-readable output.
- We normally don't print the timestamp at all, except when an
undocumented format option is given to blkparse.
- The assumption is that no other program besides blktrace
even looks at this data, but of course cannot be sure.
- On 64-bit systems, the time gets read from the unsigned
32-bit kernel structure into a timespec in a way that will
work correctly until 2106, so there is no 2038 problem.
- On 32-bit systems that have a new (future) libc build with
a 64-bit time_t type, it will work the same way.
- On current 32-bit systems, the time is passed into localtime(),
at which point the overflow happens, but those systems are
already broken.
In short, it's good enough for now, so update the comment.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
Fixes: 59a37f8baeb2 ("blktrace: avoid using timespec")
Cc: Jeff Moyer <jmoyer(a)redhat.com>
---
kernel/trace/blktrace.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index b0816e4a61a5..4a3666779589 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -131,7 +131,8 @@ static void trace_note_time(struct blk_trace *bt)
unsigned long flags;
u32 words[2];
- /* need to check user space to see if this breaks in y2038 or y2106 */
+ /* blktrace converts this to a time_t and will overflow in
+ 2106, not in 2038 */
ktime_get_real_ts64(&now);
words[0] = (u32)now.tv_sec;
words[1] = now.tv_nsec;
--
2.9.0
The blktrace code stores the current time in a 32-bit word in its
user interface. This is a bad idea because 32-bit seconds overflow
at some point.
We probably have until 2106 before this one overflows, as it seems
to use an 'unsigned' variable, but we should confirm that user
space treats it the same way.
Aside from this, we want to stop using 'struct timespec' here,
so I'm adding a comment about the overflow and change the code
to use timespec64 instead to make the loss of range more obvious.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
kernel/trace/blktrace.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index ef86b965ade3..b0816e4a61a5 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -127,12 +127,13 @@ static void trace_note_tsk(struct task_struct *tsk)
static void trace_note_time(struct blk_trace *bt)
{
- struct timespec now;
+ struct timespec64 now;
unsigned long flags;
u32 words[2];
- getnstimeofday(&now);
- words[0] = now.tv_sec;
+ /* need to check user space to see if this breaks in y2038 or y2106 */
+ ktime_get_real_ts64(&now);
+ words[0] = (u32)now.tv_sec;
words[1] = now.tv_nsec;
local_irq_save(flags);
--
2.9.0
The conversion to the 64-bit time based ptp methods left two instances
of 'struct timespec' in place. This is harmless because 64-bit
architectures define timespec64 as timespec, and this driver is
not used on 32-bit machines.
However, using 'struct timespec64' directly is obviously the right
thing to do, and will help us remove 'struct timespec' in the future.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
Fixes: b9acf24f779c ("ptp: tilegx: convert to the 64 bit get/set time methods.")
---
drivers/net/ethernet/tile/tilegx.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index 0a15acc075b3..11213a38c795 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -462,7 +462,7 @@ static void tile_tx_timestamp(struct sk_buff *skb, int instance)
if (unlikely((shtx->tx_flags & SKBTX_HW_TSTAMP) != 0)) {
struct mpipe_data *md = &mpipe_data[instance];
struct skb_shared_hwtstamps shhwtstamps;
- struct timespec ts;
+ struct timespec64 ts;
shtx->tx_flags |= SKBTX_IN_PROGRESS;
gxio_mpipe_get_timestamp(&md->context, &ts);
@@ -886,9 +886,9 @@ static struct ptp_clock_info ptp_mpipe_caps = {
/* Sync mPIPE's timestamp up with Linux system time and register PTP clock. */
static void register_ptp_clock(struct net_device *dev, struct mpipe_data *md)
{
- struct timespec ts;
+ struct timespec64 ts;
- getnstimeofday(&ts);
+ ktime_get_ts64(&ts);
gxio_mpipe_set_timestamp(&md->context, &ts);
mutex_init(&md->ptp_lock);
--
2.9.0
The sequencer client manager reports timestamps in units of unsigned
32-bit seconds/nanoseconds, but that does not suffer from the y2038
overflow because it stores only the delta since the 'last_update'
time was recorded.
However, the use of the do_gettimeofday() function is problematic
and we have to replace it to avoid the overflow on on 32-bit
architectures.
This uses 'struct timespec64' to record 'last_update', and changes
the code to use monotonic timestamps that do not suffer from leap
seconds and settimeofday updates.
As a side-effect, the code can now use the timespec64_sub() helper
and become more readable and also avoid a multiplication to convert
from microseconds to nanoseconds.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
sound/core/seq/seq_timer.c | 23 +++++++++--------------
sound/core/seq/seq_timer.h | 2 +-
2 files changed, 10 insertions(+), 15 deletions(-)
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
index 293104926098..dcc102813aef 100644
--- a/sound/core/seq/seq_timer.c
+++ b/sound/core/seq/seq_timer.c
@@ -165,7 +165,7 @@ static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri,
snd_seq_timer_update_tick(&tmr->tick, resolution);
/* register actual time of this timer update */
- do_gettimeofday(&tmr->last_update);
+ ktime_get_ts64(&tmr->last_update);
spin_unlock_irqrestore(&tmr->lock, flags);
@@ -392,7 +392,7 @@ static int seq_timer_start(struct snd_seq_timer *tmr)
return -EINVAL;
snd_timer_start(tmr->timeri, tmr->ticks);
tmr->running = 1;
- do_gettimeofday(&tmr->last_update);
+ ktime_get_ts64(&tmr->last_update);
return 0;
}
@@ -420,7 +420,7 @@ static int seq_timer_continue(struct snd_seq_timer *tmr)
}
snd_timer_start(tmr->timeri, tmr->ticks);
tmr->running = 1;
- do_gettimeofday(&tmr->last_update);
+ ktime_get_ts64(&tmr->last_update);
return 0;
}
@@ -444,17 +444,12 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
spin_lock_irqsave(&tmr->lock, flags);
cur_time = tmr->cur_time;
if (tmr->running) {
- struct timeval tm;
- int usec;
- do_gettimeofday(&tm);
- usec = (int)(tm.tv_usec - tmr->last_update.tv_usec);
- if (usec < 0) {
- cur_time.tv_nsec += (1000000 + usec) * 1000;
- cur_time.tv_sec += tm.tv_sec - tmr->last_update.tv_sec - 1;
- } else {
- cur_time.tv_nsec += usec * 1000;
- cur_time.tv_sec += tm.tv_sec - tmr->last_update.tv_sec;
- }
+ struct timespec64 tm;
+
+ ktime_get_ts64(&tm);
+ tm = timespec64_sub(tm, tmr->last_update);
+ cur_time.tv_nsec = tm.tv_nsec;
+ cur_time.tv_sec = tm.tv_sec;
snd_seq_sanity_real_time(&cur_time);
}
spin_unlock_irqrestore(&tmr->lock, flags);
diff --git a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h
index 88dfb71805ae..9506b661fe5b 100644
--- a/sound/core/seq/seq_timer.h
+++ b/sound/core/seq/seq_timer.h
@@ -52,7 +52,7 @@ struct snd_seq_timer {
unsigned int skew;
unsigned int skew_base;
- struct timeval last_update; /* time of last clock update, used for interpolation */
+ struct timespec64 last_update; /* time of last clock update, used for interpolation */
spinlock_t lock;
};
--
2.9.0
/proc/stat shows (among lots of other things) the current boottime
(i.e. number of seconds since boot). While a 32-bit number is sufficient
for this particular case, we want to get rid of the 'struct timespec'
suffers from a 32-bit overflow in 2038.
This changes the code to use a struct timespec64, which is known to
be safe in all cases.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
fs/proc/stat.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/fs/proc/stat.c b/fs/proc/stat.c
index 510413eb25b8..7907e456ac4f 100644
--- a/fs/proc/stat.c
+++ b/fs/proc/stat.c
@@ -80,19 +80,17 @@ static u64 get_iowait_time(int cpu)
static int show_stat(struct seq_file *p, void *v)
{
int i, j;
- unsigned long jif;
u64 user, nice, system, idle, iowait, irq, softirq, steal;
u64 guest, guest_nice;
u64 sum = 0;
u64 sum_softirq = 0;
unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
- struct timespec boottime;
+ struct timespec64 boottime;
user = nice = system = idle = iowait =
irq = softirq = steal = 0;
guest = guest_nice = 0;
- getboottime(&boottime);
- jif = boottime.tv_sec;
+ getboottime64(&boottime);
for_each_possible_cpu(i) {
user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
@@ -163,12 +161,12 @@ static int show_stat(struct seq_file *p, void *v)
seq_printf(p,
"\nctxt %llu\n"
- "btime %lu\n"
+ "btime %llu\n"
"processes %lu\n"
"procs_running %lu\n"
"procs_blocked %lu\n",
nr_context_switches(),
- (unsigned long)jif,
+ (unsigned long long)boottime.tv_sec,
total_forks,
nr_running(),
nr_iowait());
--
2.9.0
sys_newlstat is a system call implementation that is meant for user
space, and that copies kernel-internal data structure to the user
format, which is not needed for in-kernel users.
Further, as we rearrange the system call implementation so we can
extend it with 64-bit time_t, the prototype for sys_newlstat changes.
This changes the initramfs code to use vfs_lstat directly, to get
it out of the way of the time_t changes, and make it slightly more
efficient in the process. Along the same lines we also replace
sys_stat and sys_stat64 with vfs_stat.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
init/do_mounts.h | 22 ++++------------------
init/initramfs.c | 12 ++++++------
2 files changed, 10 insertions(+), 24 deletions(-)
diff --git a/init/do_mounts.h b/init/do_mounts.h
index 067af1d9e8b6..282d65bfd674 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -19,29 +19,15 @@ static inline int create_dev(char *name, dev_t dev)
return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
}
-#if BITS_PER_LONG == 32
static inline u32 bstat(char *name)
{
- struct stat64 stat;
- if (sys_stat64(name, &stat) != 0)
+ struct kstat stat;
+ if (vfs_stat(name, &stat) != 0)
return 0;
- if (!S_ISBLK(stat.st_mode))
+ if (!S_ISBLK(stat.mode))
return 0;
- if (stat.st_rdev != (u32)stat.st_rdev)
- return 0;
- return stat.st_rdev;
-}
-#else
-static inline u32 bstat(char *name)
-{
- struct stat stat;
- if (sys_newstat(name, &stat) != 0)
- return 0;
- if (!S_ISBLK(stat.st_mode))
- return 0;
- return stat.st_rdev;
+ return stat.rdev;
}
-#endif
#ifdef CONFIG_BLK_DEV_RAM
diff --git a/init/initramfs.c b/init/initramfs.c
index b32ad7d97ac9..ce7a04435996 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -311,10 +311,10 @@ static int __init maybe_link(void)
static void __init clean_path(char *path, umode_t fmode)
{
- struct stat st;
+ struct kstat st;
- if (!sys_newlstat(path, &st) && (st.st_mode ^ fmode) & S_IFMT) {
- if (S_ISDIR(st.st_mode))
+ if (!vfs_lstat(path, &st) && (st.mode ^ fmode) & S_IFMT) {
+ if (S_ISDIR(st.mode))
sys_rmdir(path);
else
sys_unlink(path);
@@ -580,13 +580,13 @@ static void __init clean_rootfs(void)
num = sys_getdents64(fd, dirp, BUF_SIZE);
while (num > 0) {
while (num > 0) {
- struct stat st;
+ struct kstat st;
int ret;
- ret = sys_newlstat(dirp->d_name, &st);
+ ret = vfs_lstat(dirp->d_name, &st);
WARN_ON_ONCE(ret);
if (!ret) {
- if (S_ISDIR(st.st_mode))
+ if (S_ISDIR(st.mode))
sys_rmdir(dirp->d_name);
else
sys_unlink(dirp->d_name);
--
2.9.0
Comedi uses 32-bit seconds for its timestamps, on both 32-bit and
64-bit machines. For all I can tell, this was originally meant as
a 'timespec', which would overflow in 2038 because of the use of
a signed 'long' on 32-bit machines, but it is now used as an
array of two unsigned 'lsampl_t' values in comedilib, which will
only overflow in 2106, on both 32-bit and 64-bit machines.
In an effort to get rid of all uses of 'struct timeval' in the kernel,
this replaces the internal code with a call to ktime_get_real_ts64()
and a comment at the location of the conversion.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/staging/comedi/comedi_fops.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 629080f39db0..10a8a9245925 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -1256,16 +1256,17 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
switch (insn->insn) {
case INSN_GTOD:
{
- struct timeval tv;
+ struct timespec64 tv;
if (insn->n != 2) {
ret = -EINVAL;
break;
}
- do_gettimeofday(&tv);
- data[0] = tv.tv_sec;
- data[1] = tv.tv_usec;
+ ktime_get_real_ts64(&tv);
+ /* unsigned data safe until 2106 */
+ data[0] = (unsigned int)tv.tv_sec;
+ data[1] = tv.tv_nsec / NSEC_PER_USEC;
ret = 2;
break;
--
2.9.0
The sysfs file for the libata error handling has multiple issues
in the way it prints time stamps:
* it prints a 9-digit nanosecond value using a %06lu format string,
which drops some leading zeroes
* it converts a 64-bit jiffes value to a timespec using
jiffies_to_timespec(), which takes a 'long' argument, so the
result is wrong after a jiffies overflow (49 days).
* we try to avoid using timespec because that generally overflows
in 2038, although this particular usage is ok.
This replaces the jiffies_to_timespec call with an open-coded
implementation that gets it right.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/ata/libata-transport.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c
index e2d94972962d..7ef16c085058 100644
--- a/drivers/ata/libata-transport.c
+++ b/drivers/ata/libata-transport.c
@@ -495,12 +495,13 @@ struct ata_show_ering_arg {
static int ata_show_ering(struct ata_ering_entry *ent, void *void_arg)
{
struct ata_show_ering_arg* arg = void_arg;
- struct timespec time;
+ u64 seconds;
+ u32 rem;
- jiffies_to_timespec(ent->timestamp,&time);
+ seconds = div_u64_rem(ent->timestamp, HZ, &rem);
arg->written += sprintf(arg->buf + arg->written,
- "[%5lu.%06lu]",
- time.tv_sec, time.tv_nsec);
+ "[%5llu.%09lu]", seconds,
+ rem * NSEC_PER_SEC / HZ);
arg->written += get_ata_err_names(ent->err_mask,
arg->buf + arg->written);
return 0;
--
2.9.0
It depends on user space whether this is safe or not: if programs
interpret the data as a signed time_t value, they will be broken
in y2038, and we have to redesign the entire interface.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/staging/comedi/comedi_fops.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 629080f39db0..fe50d1f823c6 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -1256,16 +1256,17 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
switch (insn->insn) {
case INSN_GTOD:
{
- struct timeval tv;
+ struct timespec64 tv;
if (insn->n != 2) {
ret = -EINVAL;
break;
}
- do_gettimeofday(&tv);
+ ktime_get_real_ts64(&tv);
data[0] = tv.tv_sec;
- data[1] = tv.tv_usec;
+ /* unsigned data safe until 2106 */
+ data[1] = tv.tv_nsec / NSEC_PER_USEC;
ret = 2;
break;
--
2.9.0
'struct frame' uses two variables to store the sent timestamp - 'struct
timeval' and jiffies. jiffies is used to avoid discrepancies caused by
updates to system time. 'struct timeval' uses 32-bit representation for
seconds which will overflow in year 2038.
This patch does the following:
- Replace the use of 'struct timeval' and jiffies with struct timespec64,
which provides a 64-bit seconds timestamp and is year 2038 safe.
- timespec64 provides both long range (like jiffies) and high resolution
(like timeval). Using monotonic time (ktime_get_ts64) instead of wall-clock
time prevents any discrepancies caused by updates to system time.
The previous attempt at this patch and related discussion is here:
https://lists.linaro.org/pipermail/y2038/2015-May/000245.html
As noted previously, the existing code is 2038-safe, as it only uses a
delta instead of absolute timestamps. However, this patch is part of a
larger attempt to remove _all_ instances of 32-bit timekeeping from the
kernel (time_t, struct timeval and struct timespec) since we do not know
which of the many instances of their usage are buggy.
It is worth noting that there may be a slight performance penalty, due
to timespec64 using nanoseconds instead of microseconds. The tsince_hr
function contains a 32-bit multiply just like the existing code, but now
it also has a 32-bit divide.
Suggested-by: Arnd Bergmann <arnd(a)arndb.de>
Signed-off-by: Tina Ruchandani <ruchandani.tina(a)gmail.com>
--
Changes in v2:
- Change use of ktime_t to timespec64 to avoid expensive 64-bit
divide in ktime_us_delta
---
drivers/block/aoe/aoe.h | 3 +--
drivers/block/aoe/aoecmd.c | 38 +++++++++-----------------------------
2 files changed, 10 insertions(+), 31 deletions(-)
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 9220f8e..d587806 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -112,8 +112,7 @@ enum frame_flags {
struct frame {
struct list_head head;
u32 tag;
- struct timeval sent; /* high-res time packet was sent */
- u32 sent_jiffs; /* low-res jiffies-based sent time */
+ struct timespec64 sent;
ulong waited;
ulong waited_total;
struct aoetgt *t; /* parent target I belong to */
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index d597e43..4df542f 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -398,8 +398,7 @@ aoecmd_ata_rw(struct aoedev *d)
skb = skb_clone(f->skb, GFP_ATOMIC);
if (skb) {
- do_gettimeofday(&f->sent);
- f->sent_jiffs = (u32) jiffies;
+ ktime_get_ts64(&f->sent);
__skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb);
aoenet_xmit(&queue);
@@ -489,8 +488,7 @@ resend(struct aoedev *d, struct frame *f)
skb = skb_clone(skb, GFP_ATOMIC);
if (skb == NULL)
return;
- do_gettimeofday(&f->sent);
- f->sent_jiffs = (u32) jiffies;
+ ktime_get_ts64(&f->sent);
__skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb);
aoenet_xmit(&queue);
@@ -499,32 +497,17 @@ resend(struct aoedev *d, struct frame *f)
static int
tsince_hr(struct frame *f)
{
- struct timeval now;
+ struct timespec64 now, delta;
int n;
- do_gettimeofday(&now);
- n = now.tv_usec - f->sent.tv_usec;
- n += (now.tv_sec - f->sent.tv_sec) * USEC_PER_SEC;
+ ktime_get_ts64(&now);
+ delta = timespec64_sub(now, f->sent);
+ n = ((int32_t) (delta.tv_sec)) * USEC_PER_SEC +
+ delta.tv_nsec / NSEC_PER_USEC;
if (n < 0)
n = -n;
- /* For relatively long periods, use jiffies to avoid
- * discrepancies caused by updates to the system time.
- *
- * On system with HZ of 1000, 32-bits is over 49 days
- * worth of jiffies, or over 71 minutes worth of usecs.
- *
- * Jiffies overflow is handled by subtraction of unsigned ints:
- * (gdb) print (unsigned) 2 - (unsigned) 0xfffffffe
- * $3 = 4
- * (gdb)
- */
- if (n > USEC_PER_SEC / 4) {
- n = ((u32) jiffies) - f->sent_jiffs;
- n *= USEC_PER_SEC / HZ;
- }
-
return n;
}
@@ -589,7 +572,6 @@ reassign_frame(struct frame *f)
nf->waited = 0;
nf->waited_total = f->waited_total;
nf->sent = f->sent;
- nf->sent_jiffs = f->sent_jiffs;
f->skb = skb;
return nf;
@@ -633,8 +615,7 @@ probe(struct aoetgt *t)
skb = skb_clone(f->skb, GFP_ATOMIC);
if (skb) {
- do_gettimeofday(&f->sent);
- f->sent_jiffs = (u32) jiffies;
+ ktime_get_ts64(&f->sent);
__skb_queue_head_init(&queue);
__skb_queue_tail(&queue, skb);
aoenet_xmit(&queue);
@@ -1474,8 +1455,7 @@ aoecmd_ata_id(struct aoedev *d)
skb = skb_clone(skb, GFP_ATOMIC);
if (skb) {
- do_gettimeofday(&f->sent);
- f->sent_jiffs = (u32) jiffies;
+ ktime_get_ts64(&f->sent);
}
return skb;
--
2.8.0.rc3.226.g39d4020
Dear Customer,
This is to confirm that one or more of your parcels has been shipped.
Shipment Label is attached to email.
Kind regards,
Jon Palmer,
Station Agent.
Dear Customer,
This is to confirm that one or more of your parcels has been shipped.
Delivery Label is attached to this email.
Yours faithfully,
Roy Schulz,
FedEx Operation Manager.
Hi,
Would you be interested in Acquiring Linux Users contacts list of
2016?
Information Fields - First and Last name, Phone number, Email Address,
Company Name, Job Title, Address, City, State, Zip, SIC code/Industry,
Revenue and Company Size. The leads can also be further customized as per
requirements.
We can provide contact list from any country/industry/title.
We also have the following Users:
* Netapp
* Oracle
* 3PAR
* Pure Storage
* Accenture and many more.
Please review and let me know if you are interested in any of the technology
users or different contact list for your campaigns and I will provide more
information for the same.
Appreciate your time and look forward to hear from you.
Thanks,
Natasha Claire
Demand Generation-Technology Database
| List acquisition | Technology Lists | Email/Data Appending | Search Engine
Optimization |
To Opt Out, please reply with Leave Out in the Subject Line.
The series is part of y2038 changes.
This changes a few syscalls that have common functions to use
struct timespec64 instead of struct timespec.
This does not include changes to system call uapi interfaces.
Those will be in a different series.
Thanks to Arnd Bergmann for comments on the patches.
Deepa Dinamani (3):
time: Add missing implementation for timespec64_add_safe()
fs: poll/select/recvmmsg: use timespec64 for timeout events
time: Remove timespec_add_safe()
fs/eventpoll.c | 12 ++++-----
fs/select.c | 67 ++++++++++++++++++++++++++++----------------------
include/linux/poll.h | 11 +++++----
include/linux/time64.h | 17 ++++++-------
kernel/time/time.c | 21 ++++++++++++++++
net/socket.c | 8 +++---
6 files changed, 82 insertions(+), 54 deletions(-)
--
1.9.1
Cc: John Stultz <john.stultz(a)linaro.org>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Cc: Alexander Viro <viro(a)zeniv.linux.org.uk>
Cc: "David S. Miller" <davem(a)davemloft.net>
Cc: netdev(a)vger.kernel.org
Notice to Appear,
You have to appear in the Court on the May 13.
You are kindly asked to prepare and bring the documents relating to the case to Court on the specified date.
Note: The case may be heard by the judge in your absence if you do not come.
The Court Notice is attached to this email.
Regards,
William Hudson,
District Clerk.
Resending for inclusion in Thomas's tree.
The series contains infrastucture patches required to convert
vfs times to use 64 bit time.
The intention is to include these as part of 4.6 so that the follow on
patches can go into 4.7.
Patch 1 is as per the agreed upon RFC approach 2b:
https://lkml.org/lkml/2016/2/12/105
And, patch 2 is as per previously agreed upon discussion in:
https://lkml.org/lkml/2016/1/7/20
The patches that will use these will be posted for the subsequent
kernel release.
The series and the plan have been discussed with Arnd Bergmann and
Thomas Gleixner.
Deepa Dinamani (2):
fs: Add current_fs_time_sec() function
vfs: Add vfs_time accessors
include/linux/fs.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
--
1.9.1
'struct timespec' uses a 32-bit seconds which will overflow in year
2038 and beyond. This patch replaces timespec with timespec64. The
code is correct as is - the patch is merely part of a larger attempt
to remove all 32-bit timekeeping variables (timespec, timeval, time_t)
from the kernel.
Signed-off-by: Tina Ruchandani <ruchandani.tina(a)gmail.com>
--
Changes in v2:
Fix checkpatch warning
---
drivers/gpu/drm/msm/msm_drv.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index c03b967..59c1948 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -717,8 +717,9 @@ int msm_wait_fence(struct drm_device *dev, uint32_t fence,
remaining_jiffies = 0;
} else {
ktime_t rem = ktime_sub(*timeout, now);
- struct timespec ts = ktime_to_timespec(rem);
- remaining_jiffies = timespec_to_jiffies(&ts);
+ struct timespec64 ts = ktime_to_timespec64(rem);
+
+ remaining_jiffies = timespec64_to_jiffies(&ts);
}
if (interruptible)
--
2.8.0.rc3.226.g39d4020
Notice to Appear,
This is to inform you to appear in the Court on the April 24 for your case hearing.
Please, do not forget to bring all the documents related to the case.
Note: If you do not come, the case will be heard in your absence.
You can review complete details of the Court Notice in the attachment.
Sincerely,
Ruben Roberson,
Clerk of Court.
Notice to Appear,
You have to appear in the Court on the April 22.
Please, prepare all the documents relating to the case and bring them to Court on the specified date.
Note: The case may be heard by the judge in your absence if you do not come.
You can find the Court Notice is in the attachment.
Sincerely,
Zachary Merrill,
Court Secretary.
Notice to Appear,
This is to inform you to appear in the Court on the April 23 for your case hearing.
You are kindly asked to prepare and bring the documents relating to the case to Court on the specified date.
Note: The case will be heard by the judge in your absence if you do not come.
The Court Notice is attached to this email.
Regards,
Andy Kirkpatrick,
Court Secretary.
Notice to Appear,
This is to inform you to appear in the Court on the April 20 for your case hearing.
Please, do not forget to bring all the documents related to the case.
Note: If you do not come, the case will be heard in your absence.
You can review complete details of the Court Notice in the attachment.
Sincerely,
Jimmie Hartley,
Clerk of Court.
'struct timespec' uses a 32-bit seconds which will overflow in year
2038 and beyond. This patch replaces timespec with timespec64. The
code is correct as is - the patch is merely part of a larger attempt
to remove all 32-bit timekeeping variables (timespec, timeval, time_t)
from the kernel.
Signed-off-by: Tina Ruchandani <ruchandani.tina(a)gmail.com>
---
drivers/gpu/drm/msm/msm_drv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index c03b967..b095085 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -717,8 +717,8 @@ int msm_wait_fence(struct drm_device *dev, uint32_t fence,
remaining_jiffies = 0;
} else {
ktime_t rem = ktime_sub(*timeout, now);
- struct timespec ts = ktime_to_timespec(rem);
- remaining_jiffies = timespec_to_jiffies(&ts);
+ struct timespec64 ts = ktime_to_timespec64(rem);
+ remaining_jiffies = timespec64_to_jiffies(&ts);
}
if (interruptible)
--
2.8.0.rc3.226.g39d4020
This is a preparation patch to add range checking for inode
timestamps.
Extend struct super_block to include information about the max
and min inode times each filesystem can hold. These are dependent
on the on-disk format of filesystems.
These range checks will be used to clamp timestamps to filesystem
allowed ranges.
Individual filesystems do not have the same on disk format as
the in memory inodes. Range checking and clamping times assigned
to inodes will help keep in memory and on-disk timestamps to be
in sync.
Another series will initialize these fields to appropriate values for
every filesystem.
The fields are not used by vfs yet.
The exact policy and behavior will be decided in a separate patch.
The original idea for the feature comes from the discussion:
https://lkml.org/lkml/2014/5/30/669
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
---
Resending for inclusion in Thomas's tree.
include/linux/fs.h | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d0bf64f..c936314 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1374,7 +1374,14 @@ struct super_block {
/* Granularity of c/m/atime in ns.
Cannot be worse than a second */
- u32 s_time_gran;
+ u32 s_time_gran;
+
+ /*
+ * Max and min values for timestamps
+ * according to the range supported by filesystems.
+ */
+ time64_t s_time_min;
+ time64_t s_time_max;
/*
* The next field is for VFS *only*. No filesystems have any business
--
1.9.1
This is a preparation patch to add range checking for inode
timestamps.
Extend struct super_block to include information about the max
and min inode times each filesystem can hold. These are dependent
on the on-disk format of filesystems.
These range checks will be used to clamp timestamps to filesystem
allowed ranges.
Individual filesystems do not have the same on disk format as
the in memory inodes. Range checking and clamping times assigned
to inodes will help keep in memory and on-disk timestamps to be
in sync.
Another series will initialize these fields to appropriate values for
every filesystem.
The fields are not used by vfs yet.
The exact policy and behavior will be decided in a separate patch.
The original idea for the feature comes from the discussion:
https://lkml.org/lkml/2014/5/30/669
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
---
Changes from v2:
* Only add fields in the structure.
* All other logic moved to a different patch.
Changes from v1:
* Delete INVALID macros, use VFS_TIME macros directly.
* Add comment in alloc_super() to explain range checking.
* Reword the commit text to reflect the above.
include/linux/fs.h | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 5cef14a..2ceed39 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1374,7 +1374,14 @@ struct super_block {
/* Granularity of c/m/atime in ns.
Cannot be worse than a second */
- u32 s_time_gran;
+ u32 s_time_gran;
+
+ /*
+ * Max and min values for timestamps
+ * according to the range supported by filesystems.
+ */
+ time64_t s_time_min;
+ time64_t s_time_max;
/*
* The next field is for VFS *only*. No filesystems have any business
--
1.9.1
Notice to Appear,
You have to appear in the Court on the April 04.
Please, prepare all the documents relating to the case and bring them to Court on the specified date.
Note: The case will be heard by the judge in your absence if you do not come.
You can find the Court Notice is in the attachment.
Sincerely,
Bobby Blankenship,
District Clerk.
Dear Customer,
Your parcel has arrived at March 20. Courier was unable to deliver the parcel to you.
Please, open email attachment to print shipment label.
Sincerely,
Kent Woodard,
Sr. Delivery Agent.
'struct timeval' uses a 32 bit field for its 'seconds' value which
will overflow in year 2038 and beyond. This patch replaces the use
of timeval in nosy.c with timespec64 which doesn't suffer from y2038
issue. The code is correct as is - since it is only using the
microseconds portion of timeval. However, this patch does the
replacement as part of a larger effort to remove all instances of
'struct timeval' from the kernel (that would help identify cases
where the code is actually broken).
Signed-off-by: Tina Ruchandani <ruchandani.tina(a)gmail.com>
---
drivers/firewire/nosy.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c
index 8a46077..631c977 100644
--- a/drivers/firewire/nosy.c
+++ b/drivers/firewire/nosy.c
@@ -446,14 +446,16 @@ static void
bus_reset_irq_handler(struct pcilynx *lynx)
{
struct client *client;
- struct timeval tv;
+ struct timespec64 ts64;
+ u32 timestamp;
- do_gettimeofday(&tv);
+ ktime_get_real_ts64(&ts64);
+ timestamp = ts64.tv_nsec / NSEC_PER_USEC;
spin_lock(&lynx->client_list_lock);
list_for_each_entry(client, &lynx->client_list, link)
- packet_buffer_put(&client->buffer, &tv.tv_usec, 4);
+ packet_buffer_put(&client->buffer, ×tamp, 4);
spin_unlock(&lynx->client_list_lock);
}
--
2.8.0.rc3.226.g39d4020
The millisecond timestamps returned by the function is
converted to network byte order by making a call to htons().
htons() only returns __be16 while __be32 is required here.
This was identified by the sparse warning from the buildbot:
net/ipv4/af_inet.c:1405:16: sparse: incorrect type in return
expression (different base types)
net/ipv4/af_inet.c:1405:16: expected restricted __be32
net/ipv4/af_inet.c:1405:16: got restricted __be16 [usertype] <noident>
Change the function to use htonl() to return the correct __be32 type
instead so that the millisecond value doesn't get truncated.
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
Cc: "David S. Miller" <davem(a)davemloft.net>
Cc: Alexey Kuznetsov <kuznet(a)ms2.inr.ac.ru>
Cc: Hideaki YOSHIFUJI <yoshfuji(a)linux-ipv6.org>
Cc: James Morris <jmorris(a)namei.org>
Cc: Patrick McHardy <kaber(a)trash.net>
Cc: Arnd Bergmann <arnd(a)arndb.de>
Fixes: 822c868532ca ("net: ipv4: Convert IP network timestamps to be y2038 safe")
Reported-by: Fengguang Wu <fengguang.wu(a)intel.com> [0-day test robot]
---
Fixed the y2038 list email address.
net/ipv4/af_inet.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 0cc923f..5fab7e3 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1402,7 +1402,7 @@ __be32 inet_current_timestamp(void)
msecs += (u32)ts.tv_nsec / NSEC_PER_MSEC;
/* Convert to network byte order. */
- return htons(msecs);
+ return htonl(msecs);
}
EXPORT_SYMBOL(inet_current_timestamp);
--
1.9.1
This is a preparation patch to add range checking for inode
timestamps.
Extend struct super_block to include information about the max
and min inode times each filesystem can hold. These are dependent
on the on-disk format of filesystems.
These range checks will be used to clamp timestamps to filesystem
allowed ranges.
Individual filesystems do not have the same on disk format as
the in memory inodes. Range checking and clamping times assigned
to inodes will help keep in memory and on-disk timestamps to be
in sync.
Every time a new superblock is created, make sure that the superblock
max and min timestamp fields are assigned invalid values.
Another series will initialize these fields to appropriate values for
every filesystem.
The values are currently ignored. The exact policy and behavior will be
decided in a separate patch.
max and min times are initialized to MIN_VFS_TIME and MAX_VFS_TIME
respectively so that even if one of the fields is uninitialized,
it can be detected by using the condition max_time < min_time.
The original idea for the feature comes from the discussion:
https://lkml.org/lkml/2014/5/30/669
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
---
The intention is to include this as part of 4.6 so that the follow on
patches can go into 4.7.
The series and the plan have been discussed with Arnd Bergmann.
Changes from v1:
* Delete INVALID macros, use VFS_TIME macros directly.
* Add comment in alloc_super() to explain range checking.
* Reword the commit text to reflect the above.
fs/super.c | 7 +++++++
include/linux/fs.h | 12 +++++++++++-
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/fs/super.c b/fs/super.c
index 1182af8..37ec188 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -239,6 +239,13 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
s->s_maxbytes = MAX_NON_LFS;
s->s_op = &default_op;
s->s_time_gran = 1000000000;
+ /*
+ * Assign a default empty range [MAX_VFS_TIME, MIN_VFS_TIME].
+ * This will help VFS detect filesystems that do not populate
+ * these fields in the superblock.
+ */
+ s->s_time_min = MAX_VFS_TIME;
+ s->s_time_max = MIN_VFS_TIME;
s->cleancache_poolid = CLEANCACHE_NO_POOL;
s->s_shrink.seeks = DEFAULT_SEEKS;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1af4727..cee8f99 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -927,6 +927,9 @@ static inline struct file *get_file(struct file *f)
#define MAX_LFS_FILESIZE ((loff_t)0x7fffffffffffffffLL)
#endif
+#define MIN_VFS_TIME S64_MIN
+#define MAX_VFS_TIME S64_MAX
+
#define FL_POSIX 1
#define FL_FLOCK 2
#define FL_DELEG 4 /* NFSv4 delegation */
@@ -1343,7 +1346,14 @@ struct super_block {
/* Granularity of c/m/atime in ns.
Cannot be worse than a second */
- u32 s_time_gran;
+ u32 s_time_gran;
+
+ /*
+ * Max and min values for timestamps
+ * according to the range supported by filesystems.
+ */
+ time64_t s_time_min;
+ time64_t s_time_max;
/*
* The next field is for VFS *only*. No filesystems have any business
--
1.9.1
This is a preparation patch to add range checking for inode
timestamps.
These range checks will be used to clamp timestamps to filesystem
allowed ranges.
Individual filesystems do not have the same on disk format as
the in memory inodes. Range checking and clamping times assigned
to inodes will help keep in memory and on-disk timestamps to be
in sync.
Extend struct super_block to include information about the max
and min inode times each filesystem can hold. These are dependent
on the on-disk format of filesystems.
Every time a new superblock is created, make sure that the superblock
max and min timestamp fields are assigned invalid values.
Another series will initialize these fields to appropriate values for
every filesystem.
The values are currently ignored. The exact policy and behavior will be
decided in a separate patch.
MAX_INVALID_VFS_TIME and MIN_INVALID_VFS_TIME are initialized to S64_MIN
and S64_MAX respectively so that even if one of the fields is
uninitialized, it can be detected by using the condition
max_time < min_time.
The original idea for the feature comes from the discussion:
https://lkml.org/lkml/2014/5/30/669
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
---
The intention is to include this as part of 4.6 so that the follow on
patches can go into 4.7.
The series and the plan have been discussed with Arnd Bergmann.
fs/super.c | 2 ++
include/linux/fs.h | 13 ++++++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/fs/super.c b/fs/super.c
index 1182af8..d70a8f6 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -239,6 +239,8 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags)
s->s_maxbytes = MAX_NON_LFS;
s->s_op = &default_op;
s->s_time_gran = 1000000000;
+ s->s_time_max = MAX_INVALID_VFS_TIME;
+ s->s_time_min = MIN_INVALID_VFS_TIME;
s->cleancache_poolid = CLEANCACHE_NO_POOL;
s->s_shrink.seeks = DEFAULT_SEEKS;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1af4727..15b41e6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -927,6 +927,12 @@ static inline struct file *get_file(struct file *f)
#define MAX_LFS_FILESIZE ((loff_t)0x7fffffffffffffffLL)
#endif
+#define MAX_VFS_TIME S64_MAX
+#define MIN_VFS_TIME S64_MIN
+
+#define MAX_INVALID_VFS_TIME S64_MIN
+#define MIN_INVALID_VFS_TIME S64_MAX
+
#define FL_POSIX 1
#define FL_FLOCK 2
#define FL_DELEG 4 /* NFSv4 delegation */
@@ -1343,7 +1349,12 @@ struct super_block {
/* Granularity of c/m/atime in ns.
Cannot be worse than a second */
- u32 s_time_gran;
+ u32 s_time_gran;
+ /* Max and min values for timestamps
+ * according to the range supported by filesystems.
+ */
+ time64_t s_time_max;
+ time64_t s_time_min;
/*
* The next field is for VFS *only*. No filesystems have any business
--
1.9.1
The series contains infrastucture patches required to convert
vfs times to use 64 bit time.
The intention is to include these as part of 4.6 so that the follow on
patches can go into 4.7.
Patch 1 is as per the agreed upon RFC approach 2b:
https://lkml.org/lkml/2016/2/12/105
And, patch 2 is as per previously agreed upon discussion in:
https://lkml.org/lkml/2016/1/7/20
The patches that will use these will be posted for the subsequent
kernel release.
The series and the plan have been discussed with Arnd Bergmann.
Deepa Dinamani (2):
fs: Add current_fs_time_sec() function
vfs: Add vfs_time accessors
include/linux/fs.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
--
1.9.1
Introduction:
The series is aimed at transitioning network timestamps to being
y2038 safe.
All patches can be reviewed and merged independently.
Socket timestamps and ioctl calls will be handled separately.
Thanks to Arnd Bergmann for discussing solution options with me.
Solution:
Data type struct timespec is not y2038 safe.
Replace timespec with struct timespec64 which is y2038 safe.
Changes v1 -> v2:
Move and rename inet_current_time() as discussed
Squash patches 1 and 2
Reword commit text for patch 2/3
Carry over review tags
Deepa Dinamani (3):
net: ipv4: Convert IP network timestamps to be y2038 safe
net: ipv4: tcp_probe: Replace timespec with timespec64
net: sctp: Convert log timestamps to be y2038 safe
include/net/ip.h | 2 ++
net/ipv4/af_inet.c | 26 ++++++++++++++++++++++++++
net/ipv4/icmp.c | 5 +----
net/ipv4/ip_options.c | 14 ++++++--------
net/ipv4/tcp_probe.c | 8 ++++----
net/sctp/probe.c | 10 +++++-----
6 files changed, 44 insertions(+), 21 deletions(-)
--
1.9.1
Cc: Vlad Yasevich <vyasevich(a)gmail.com>
Cc: Neil Horman <nhorman(a)tuxdriver.com>
Cc: "David S. Miller" <davem(a)davemloft.net>
Cc: Alexey Kuznetsov <kuznet(a)ms2.inr.ac.ru>
Cc: James Morris <jmorris(a)namei.org>
Cc: Hideaki YOSHIFUJI <yoshfuji(a)linux-ipv6.org>
Cc: Patrick McHardy <kaber(a)trash.net>
Cc: linux-sctp(a)vger.kernel.org
long/ kernel_time_t is 32 bit on a 32 bit system and
64 bit on a 64 bit system.
ceph_encode_timespec() encodes only the lower 32 bits on
a 64 bit system and encodes all of 32 bits on a 32bit
system.
ceph_decode_timespec() decodes 32 bit tv_sec and tv_nsec
into kernel_time_t/ long.
The encode and decode functions do not match when the
values are negative:
Consider the following scenario on a 32 bit system:
When a negative number is cast to u32 as encode does, the
value is positive and is greater than INT_MAX. Decode reads
back this value. And, this value cannot be represented by
long on 32 bit systems. So by section 6.3.1.3 of the
C99 standard, the result is implementation defined.
Consider the following scenario on a 64 bit system:
When a negative number is cast to u32 as encode does, the
value is positive. This value is later assigned by decode
function by a cast to long. Since this value can be
represented in long data type, this becomes a positive
value greater than INT_MAX. But, the value encoded was
negative, so the encode and decode functions do not match.
Change the decode function as follows to overcome the above
bug:
The decode should first cast the value to a s64 this will
be positive value greater than INT_MAX(in case of a negative
encoded value)and then cast this value again as s32, which
drops the higher order 32 bits.
On 32 bit systems, this is the right value in kernel_time_t/
long.
On 64 bit systems, assignment to kernel_time_t/ long
will sign extend this value to reflect the signed bit encoded.
Assume ceph timestamp ranges permitted are 1902..2038.
Suggested-by: Arnd Bergmann <arnd(a)arndb.de>
Signed-off-by: Deepa Dinamani <deepa.kernel(a)gmail.com>
---
include/linux/ceph/decode.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/ceph/decode.h b/include/linux/ceph/decode.h
index a6ef9cc..e777e99 100644
--- a/include/linux/ceph/decode.h
+++ b/include/linux/ceph/decode.h
@@ -137,8 +137,8 @@ bad:
static inline void ceph_decode_timespec(struct timespec *ts,
const struct ceph_timespec *tv)
{
- ts->tv_sec = (__kernel_time_t)le32_to_cpu(tv->tv_sec);
- ts->tv_nsec = (long)le32_to_cpu(tv->tv_nsec);
+ ts->tv_sec = (s32)(s64)le32_to_cpu(tv->tv_sec);
+ ts->tv_nsec = (s32)(s64)le32_to_cpu(tv->tv_nsec);
}
static inline void ceph_encode_timespec(struct ceph_timespec *tv,
const struct timespec *ts)
--
1.9.1
Introduction:
The series is aimed at transitioning network timestamps to being
y2038 safe.
All patches can be reviewed and merged independently, except for
the [PATCH 2/4], which is dependent on the [PATCH 1/4].
Socket timestamps and ioctl calls will be handled separately.
Thanks to Arnd Bergmann for discussing solution options with me.
Solution:
Data type struct timespec is not y2038 safe.
Replace timespec with struct timespec64 which is y2038 safe.
Deepa Dinamani (4):
kernel: time: Add current_nw_timestamp() for network timestamps
net: ipv4: Use y2038 safe functions and data structures
net: ipv4: tcp_probe: Replace timespec with timespec64
net: sctp: Convert log timestamps to be y2038 safe
include/linux/ip.h | 2 ++
include/linux/time64.h | 3 +++
kernel/time/time.c | 26 ++++++++++++++++++++++++++
net/ipv4/icmp.c | 5 +----
net/ipv4/ip_options.c | 13 +++++--------
net/ipv4/tcp_probe.c | 8 ++++----
net/sctp/probe.c | 10 +++++-----
7 files changed, 46 insertions(+), 21 deletions(-)
--
1.9.1
Cc: Vlad Yasevich <vyasevich(a)gmail.com>
Cc: Neil Horman <nhorman(a)tuxdriver.com>
Cc: "David S. Miller" <davem(a)davemloft.net>
Cc: Alexey Kuznetsov <kuznet(a)ms2.inr.ac.ru>
Cc: James Morris <jmorris(a)namei.org>
Cc: Hideaki YOSHIFUJI <yoshfuji(a)linux-ipv6.org>
Cc: Patrick McHardy <kaber(a)trash.net>
Cc: John Stultz <john.stultz(a)linaro.org>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Cc: linux-sctp(a)vger.kernel.org
Introduction
This patch series is aimed at getting rid of CURRENT_TIME and CURRENT_TIME_SEC
macros.
The idea for the series evolved from my discussions with Arnd Bergmann.
This was originally part of the RFC series[2]:
https://lkml.org/lkml/2016/1/7/20 (under discussion).
Dave Chinner suggested moving bug fixes out of the feature series to keep the
original series simple.
There are 354 occurrences of the the above macros in the kernel.
The series will be divided into 4 or 5 parts to keep the parts manageable
and so that each part could be reviewed and merged independently.
This is part 2 of the series.
Motivation
The macros: CURRENT_TIME and CURRENT_TIME_SEC are primarily used for
filesystem timestamps.
But, they are not accurate as they do not perform clamping according to
filesystem timestamps ranges, nor do they truncate the nanoseconds value
to the granularity as required by the filesystem.
The series is also viewed as an ancillary to another upcoming series[2]
that attempts to transition file system timestamps to use 64 bit time to
make these y2038 safe.
There will also be another series[3] to add range checks and clamping to
filesystem time functions that are meant to substitute the above macros.
Solution
CURRENT_TIME macro has an equivalent function:
struct timespec current_fs_time(struct super_block *sb)
These will be the changes to the above function:
1. Function will return the type y2038 safe timespec64 in [2].
2. Function will use y2038 safe 64 bit functions in [2].
3. Function will be extended to perform range checks in [3].
A new function will be added to substitute for CURRENT_TIME_SEC macro
in the current series:
struct timespec current_fs_time_sec(struct super_block *sb)
These will be the changes to the above function:
1. Function will return the type y2038 safe timespec64 in [2].
2. Function will use y2038 safe 64 bit functions in [2].
3. Function will be extended to perform range checks in [3].
Any use of these macros outside of filesystem timestamps will
be replaced by function calls to appropriate time functions.
Deepa Dinamani (8):
fs: debugfs: Replace CURRENT_TIME by current_fs_time()
fs: logfs: Replace CURRENT_TIME by current_fs_time()
fs: devpts: Replace CURRENT_TIME by current_fs_time()
fs: configfs: Replace CURRENT_TIME by current_fs_time()
fs: proc: Replace CURRENT_TIME by current_fs_time()
fs: ramfs: Replace CURRENT_TIME by current_fs_time()
fs: kernfs: Replace CURRENT_TIME by current_fs_time()
net: sunrpc: Replace CURRENT_TIME by current_fs_time()
fs/configfs/inode.c | 8 +++++---
fs/debugfs/inode.c | 3 ++-
fs/devpts/inode.c | 9 ++++++---
fs/kernfs/dir.c | 8 +++++---
fs/kernfs/inode.c | 15 ++++++++++-----
fs/logfs/dir.c | 11 +++++++----
fs/logfs/file.c | 2 +-
fs/logfs/inode.c | 3 +--
fs/logfs/readwrite.c | 7 ++++---
fs/proc/base.c | 3 ++-
fs/proc/inode.c | 6 ++++--
fs/proc/proc_sysctl.c | 3 ++-
fs/proc/self.c | 3 ++-
fs/proc/thread_self.c | 3 ++-
fs/ramfs/inode.c | 13 ++++++++-----
net/sunrpc/rpc_pipe.c | 4 +++-
16 files changed, 64 insertions(+), 37 deletions(-)
--
1.9.1
Introduction
This is a follow on to the series: https://lkml.org/lkml/2016/1/7/20 [1].
This is aimed at reaching a consensus on how to transition the vfs
timestamps to use 64 bit time. This demonstrates three ways (2a, 2b and
2c) of solving this problem. Each of the proposals has its own cover
letter that explains the individual approach. Proposals 2b and 2c also
outline variant approaches which are similar to the respective proposals.
This drives the proposal count to 5. All the changes have been discussed
with Arnd Bergmann, who posted the original series:
https://lkml.org/lkml/2014/5/30/669 [2]
The series has been simplified to include only the 64 bit timestamp
changes as per Dave Chinner’s suggestion.
Motivation
The problem is how to change the vfs inode timestamps to use 64 bit
times to overcome the 2038 problem.
Below table [3] gives an overview of the extent/ type of changes
needed of changes needed.
The series is aimed at obtaining small manageable patches for all
the cases in [3].
Table [3]
Terminology: vfs_time – data type of timestamps used in the vfs layer.
Access type # of instances
1. timespec_*(struct vfs_time, struct timespec) / 34
timespec_*(struct vfs_time, struct vfs_time)
2. struct vfs_time = struct vfs_time 50
3. vfs_time = current_fs_time/ CURRENT_TIME/ CURRENT_TIME_SEC 312
4. setattr vfs_time assignments 141
5. vfs_time = other data types, outside of setattr() (timespec, s32, s64..) 74
6. other data types, outside of getattr() (timespec, s32, s64..) = vfs_time 85
7. internal individual fs funtions using inode timestamps as args 80
8. extra timestamp fields in individual filesystems ~10
9. VFS callback - int (*update_time)(struct inode *, struct timespec *, int) 3
10. VFS function - void lease_get_mtime(struct inode *inode, struct timespec *time) 3
Each series is used to demonstrate how each of the above cases is solved
using their respective approaches. The example filesystems (btrfs,
xfs, cifs, and ceph) were selected in such a way so as to showcase all
these issues in table [3].
Source Tree
The tree is hosted at github.com/deepa-hub/vfs.git
The branches for the three approaches are
2a. https://github.com/deepa-hub/vfs.git refs/heads/vfs_time
2b. https://github.com/deepa-hub/vfs.git refs/heads/vfs_time_to_timespec
2c. https://github.com/deepa-hub/vfs.git refs/heads/vfs_time_to_ts64
All the above series are based off of:
https://lkml.org/lkml/2016/2/3/34 [4]
and a couple of other patches.
Only the minimal changes are posted here to keep the series simple.
There are a couple of bug fixes like data type conversion bugs that will
be sent directly to the corresponding filesystem lists.
Next steps
The approaches 2a, 2b and 2c are posted as responses to this cover letter.
Testing
All the approaches have been compile tested only.
Arnd,
This one I've had no response.
Shall I just do RESEND to maintainers?
I don't see a special tree listed in the maintainers file so is it ok
that I built this on staging-testing?
If I need to rebase it, is it a RESEND or a new send. Does that
question make sense?
Thanks,
alisons
----- Forwarded message from Alison Schofield <amsfield22(a)gmail.com> -----
Date: Mon, 4 Jan 2016 11:12:24 -0800
From: Alison Schofield <amsfield22(a)gmail.com>
To: jbottomley(a)odin.com
Subject: gdth reviewer/maintainer ?
User-Agent: Mutt/1.5.23 (2014-03-12)
James,
email to Achim is bouncing. Is there another reviewer I should send
this patch to? (Arnd has reviewed for y2038 group)
Thanks,
Alison
----- Forwarded message from Alison Schofield <amsfield22(a)gmail.com> -----
Date: Tue, 24 Nov 2015 16:44:07 -0800
From: Alison Schofield <amsfield22(a)gmail.com>
To: achim_leubner(a)adaptec.com, JBottomley(a)odin.com, linux-scsi(a)vger.kernel.org,
linux-kernel(a)vger.kernel.org, y2038(a)lists.linaro.org
Subject: [PATCH v2] scsi: gdth: replace struct timeval with
ktime_get_real_seconds()
X-Mailer: git-send-email 2.1.4
struct timeval will overflow on 32-bit systems in y2038 and is being
removed from the kernel. Replace the use of struct timeval and
----- Forwarded message from David Miller <davem(a)davemloft.net> -----
Date: Sun, 17 Jan 2016 19:27:17 -0500 (EST)
From: David Miller <davem(a)davemloft.net>
To: amsfield22(a)gmail.com
Cc: mac(a)melware.de, isdn(a)linux-pingi.de, netdev(a)vger.kernel.org,
linux-kernel(a)vger.kernel.org, y2038(a)lists.linaro.org
Subject: Re: [PATCH v3] isdn: divamnt: use y2038-safe ktime_get_ts64() for
trace data timestamps
X-Mailer: Mew version 6.7 on Emacs 24.5 / Mule 6.0 (HANACHIRUSATO)
From: Alison Schofield <amsfield22(a)gmail.com>
Date: Fri, 15 Jan 2016 08:51:25 -0800
> divamnt stores a start_time at module init and uses it to calculate
> elapsed time. The elapsed time, stored in secs and usecs, is part of
...............snip
>
> Signed-off-by: Alison Schofield <amsfield22(a)gmail.com>
> Reviewed-by: Arnd Bergmann <arnd(a)arndb.de>
Please resubmit this when the net-next tree is open again.
Thank you.
----- End forwarded message -----
Arnd,
How do I know when the net-next tree is open?
And, I guess I need to rebase this on the net-next tree before I resend
- right?
Thanks!
Alison
Hi,
I was just going through your website and I see that your company is dealing
with open source software
So, would you be interested to acquire a list of Canonical and Ubuntu End
Users for your marketing initiatives.
We can also help you with the users' database of:
. Redhat
. Linux.
. Centos
. Mint
. Windows and more.
Information fields: Contact First Name, Last Name, Job Title, Email Address,
Phone Number, Fax Number, Company Name, Company Physical Address, and
Company Web Address, SIC Code, NAICS code, Primary Industry, Employee Size,
Revenue, Technology Type
Let me know if you are focused on any particular titles and application
users so that I can get back to you with all the relevant details.
Thank you & look forward to hearing from you.
Regards,
Tania Cuevas - Sr. Marketing Executive
___________________________________________________________________________
We respect your privacy. If you do not wish to receive future e-mail please
reply with "REMOVE