The get_seconds function is deprecated now since it returns a 32-bit
value that will eventually overflow, and we are replacing it throughout
the kernel with ktime_get_seconds() or ktime_get_real_seconds() that
return a time64_t.
bcache uses get_seconds() to read the current system time and store it in
the superblock as well as in uuid_entry structures that are user visible.
Unfortunately, the two structures in are still limited to 32 bits, so this
won't fix any real problems but will still overflow in year 2106. Let's
at least document that properly, in case we get an updated format in the
future it can be fixed. We still have a long time before the overflow
and checking the tools at https://github.com/koverstreet/bcache-tools
reveals no access to any of them.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
drivers/md/bcache/super.c | 12 ++++++------
include/uapi/linux/bcache.h | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index fa4058e43202..74746d8ee05e 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -181,7 +181,7 @@ static const char *read_super(struct cache_sb *sb, struct block_device *bdev,
goto err;
}
- sb->last_mount = get_seconds();
+ sb->last_mount = (u32)ktime_get_real_seconds();
err = NULL;
get_page(bh->b_page);
@@ -701,7 +701,7 @@ static void bcache_device_detach(struct bcache_device *d)
SET_UUID_FLASH_ONLY(u, 0);
memcpy(u->uuid, invalid_uuid, 16);
- u->invalidated = cpu_to_le32(get_seconds());
+ u->invalidated = cpu_to_le32((u32)ktime_get_real_seconds());
bch_uuid_write(d->c);
}
@@ -1027,7 +1027,7 @@ void bch_cached_dev_detach(struct cached_dev *dc)
int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
uint8_t *set_uuid)
{
- uint32_t rtime = cpu_to_le32(get_seconds());
+ uint32_t rtime = cpu_to_le32((u32)ktime_get_real_seconds());
struct uuid_entry *u;
struct cached_dev *exist_dc, *t;
@@ -1070,7 +1070,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c,
(BDEV_STATE(&dc->sb) == BDEV_STATE_STALE ||
BDEV_STATE(&dc->sb) == BDEV_STATE_NONE)) {
memcpy(u->uuid, invalid_uuid, 16);
- u->invalidated = cpu_to_le32(get_seconds());
+ u->invalidated = cpu_to_le32((u32)ktime_get_real_seconds());
u = NULL;
}
@@ -1390,7 +1390,7 @@ int bch_flash_dev_create(struct cache_set *c, uint64_t size)
get_random_bytes(u->uuid, 16);
memset(u->label, 0, 32);
- u->first_reg = u->last_reg = cpu_to_le32(get_seconds());
+ u->first_reg = u->last_reg = cpu_to_le32((u32)ktime_get_real_seconds());
SET_UUID_FLASH_ONLY(u, 1);
u->sectors = size >> 9;
@@ -1894,7 +1894,7 @@ static void run_cache_set(struct cache_set *c)
goto err;
closure_sync(&cl);
- c->sb.last_mount = get_seconds();
+ c->sb.last_mount = (u32)ktime_get_real_seconds();
bcache_write_super(c);
list_for_each_entry_safe(dc, t, &uncached_devices, list)
diff --git a/include/uapi/linux/bcache.h b/include/uapi/linux/bcache.h
index 821f71a2e48f..8d19e02d752a 100644
--- a/include/uapi/linux/bcache.h
+++ b/include/uapi/linux/bcache.h
@@ -195,7 +195,7 @@ struct cache_sb {
};
};
- __u32 last_mount; /* time_t */
+ __u32 last_mount; /* time overflow in y2106 */
__u16 first_bucket;
union {
@@ -318,7 +318,7 @@ struct uuid_entry {
struct {
__u8 uuid[16];
__u8 label[32];
- __u32 first_reg;
+ __u32 first_reg; /* time overflow in y2106 */
__u32 last_reg;
__u32 invalidated;
--
2.9.0
get_seconds() is deprecated in favor of ktime_get_real_seconds(),
which returns a 64-bit timestamp.
In the SYSV file system, the superblock timestamp is only 32 bits
wide, and it is used to check whether a file system is clean, so
the best solution seems to be to force a wraparound and explicitly
convert it to an unsigned 32-bit value.
This is independent of the inode timestamps that are also 32-bit
wide on disk and that come from current_time().
Acked-by: Thomas Gleixner <tglx(a)linutronix.de>
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
Originally sent on Jun 19, got an Ack but no other reply.
Christoph apparently hasn't applied any sysvfs patches in many years,
so I'd like someone else to take this one.
Al or Andrew, could you take this patch for 4.19 as well?
---
fs/sysv/inode.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 47f66bbc4578..e8927ea70d12 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -35,7 +35,7 @@
static int sysv_sync_fs(struct super_block *sb, int wait)
{
struct sysv_sb_info *sbi = SYSV_SB(sb);
- unsigned long time = get_seconds(), old_time;
+ u32 time = (u32)ktime_get_real_seconds(), old_time;
mutex_lock(&sbi->s_lock);
@@ -46,8 +46,8 @@ static int sysv_sync_fs(struct super_block *sb, int wait)
*/
old_time = fs32_to_cpu(sbi, *sbi->s_sb_time);
if (sbi->s_type == FSTYPE_SYSV4) {
- if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38 - old_time))
- *sbi->s_sb_state = cpu_to_fs32(sbi, 0x7c269d38 - time);
+ if (*sbi->s_sb_state == cpu_to_fs32(sbi, 0x7c269d38u - old_time))
+ *sbi->s_sb_state = cpu_to_fs32(sbi, 0x7c269d38u - time);
*sbi->s_sb_time = cpu_to_fs32(sbi, time);
mark_buffer_dirty(sbi->s_bh2);
}
--
2.9.0
getnstimeofday64() is just a wrapper around the ktime accessor, so
we should use that directly.
I considered using ktime_get_boottime_ts64() (to avoid leap second
problems) or ktime_get_real_seconds() (to simplify the calculation,
but in the end concluded that the existing interface is probably
the most appropriate in this case.
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
Originally sent on Jun 18, but got no reply
Alexandre, could you pick this up into the rtc tree?
---
drivers/rtc/class.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index d37588f08055..7fa32c922617 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -68,7 +68,7 @@ static int rtc_suspend(struct device *dev)
return 0;
}
- getnstimeofday64(&old_system);
+ ktime_get_real_ts64(&old_system);
old_rtc.tv_sec = rtc_tm_to_time64(&tm);
@@ -110,7 +110,7 @@ static int rtc_resume(struct device *dev)
return 0;
/* snapshot the current rtc and system time at resume */
- getnstimeofday64(&new_system);
+ ktime_get_real_ts64(&new_system);
err = rtc_read_time(rtc, &tm);
if (err < 0) {
pr_debug("%s: fail to read rtc time\n", dev_name(&rtc->dev));
--
2.9.0
The series introduces struct __kernel_timex as a substitute for
the non y2038 safe struct timex.
The series is based on the original series posted by Arnd Bergmann
in [1].
The overview of the series is as below:
1. Prepare for the compat timex interfaces to be used unconditionally.
2. Introduce struct __kernel_timex.
3. Use struct __kernel_timex in place of struct timex.
4. Switch syscalls to use struct __kernel_timex.
[1] https://sourceware.org/ml/libc-alpha/2015-05/msg00070.html
Changes since v1:
* Fix riscv asm/compat.h to pick up generic compat types
Deepa Dinamani (7):
arm64: Make basic compat_* types always available
sparc: Make thread_info.h available directly
riscv: Include asm-generic/compat.h
timex: prepare compat helpers for y2038 changes
time: Add struct __kernel_timex
timex: use __kernel_timex internally
timex: change syscalls to use struct __kernel_timex
arch/alpha/kernel/osf_sys.c | 2 +-
arch/arm64/include/asm/compat.h | 22 ++++-----
arch/riscv/include/asm/compat.h | 3 ++
arch/sparc/include/asm/compat.h | 2 +
drivers/ptp/ptp_clock.c | 2 +-
include/asm-generic/compat.h | 8 +++-
include/linux/compat.h | 33 --------------
include/linux/compat_time.h | 34 ++++++++++++++
include/linux/posix-clock.h | 2 +-
include/linux/syscalls.h | 5 +--
include/linux/timex.h | 9 +++-
include/uapi/linux/timex.h | 41 +++++++++++++++++
kernel/compat.c | 63 --------------------------
kernel/time/ntp.c | 12 ++---
kernel/time/ntp_internal.h | 2 +-
kernel/time/posix-clock.c | 2 +-
kernel/time/posix-timers.c | 14 ++----
kernel/time/posix-timers.h | 2 +-
kernel/time/time.c | 80 ++++++++++++++++++++++++++++++---
kernel/time/timekeeping.c | 4 +-
20 files changed, 201 insertions(+), 141 deletions(-)
base-commit: e30b8745c892204095c0a8b69405868f63ddcce1
--
2.17.1
Cc: catalin.marinas(a)arm.com
Cc: davem(a)davemloft.net
Cc: linux-alpha(a)vger.kernel.org
Cc: linux-api(a)vger.kernel.org
Cc: linux-arch(a)vger.kernel.org
Cc: linux-riscv(a)lists.infradead.org
Cc: netdev(a)vger.kernel.org
Cc: palmer(a)sifive.com
get_monotonic_boottime() is deprecated, and may not be safe to call in
every context, as it has to read a hardware clocksource.
This changes xmon to print the time using ktime_get_coarse_boottime64()
instead, which avoids the old timespec type and the HW access.
Acked-by: Balbir Singh <bsingharora(a)gmail.com>
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
Originally sent Jun 18, but this hasn't appeared in linux-next yet.
Resending to make sure this is still on the radar. Please apply
to the powerpc git for 4.19
---
arch/powerpc/xmon/xmon.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 47166ad2a669..45e3d0ec1246 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -918,13 +918,13 @@ static void remove_cpu_bpts(void)
static void
show_uptime(void)
{
- struct timespec uptime;
+ struct timespec64 uptime;
if (setjmp(bus_error_jmp) == 0) {
catch_memory_errors = 1;
sync();
- get_monotonic_boottime(&uptime);
+ ktime_get_coarse_boottime_ts64(&uptime);
printf("Uptime: %lu.%.2lu seconds\n", (unsigned long)uptime.tv_sec,
((unsigned long)uptime.tv_nsec / (NSEC_PER_SEC/100)));
--
2.9.0