The affs code uses "time_t" and "get_seconds()". This will cause problems on 32-bit architectures in 2038 when time_t overflows. This patch replaces them with "time64_t" and "ktime_get_real_seconds()". This patch introduces expensive 64-bit divsion in "secs_to_datestamp()", considering this function is not called so often, the cost should be acceptable.
Signed-off-by: DengChao chao.deng@linaro.org --- fs/affs/affs.h | 2 +- fs/affs/amigaffs.c | 13 +++++++------ fs/affs/super.c | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/fs/affs/affs.h b/fs/affs/affs.h index c69a87e..cc2b2ef 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h @@ -138,7 +138,7 @@ extern int affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh); extern int affs_remove_header(struct dentry *dentry); extern u32 affs_checksum_block(struct super_block *sb, struct buffer_head *bh); extern void affs_fix_checksum(struct super_block *sb, struct buffer_head *bh); -extern void secs_to_datestamp(time_t secs, struct affs_date *ds); +extern void secs_to_datestamp(time64_t secs, struct affs_date *ds); extern umode_t prot_to_mode(u32 prot); extern void mode_to_prot(struct inode *inode); __printf(3, 4) diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index 5fa92bc..d6c7a51 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c @@ -8,6 +8,7 @@ * Please send bug reports to: hjw@zvw.de */
+#include <linux/math64.h> #include "affs.h"
/* @@ -366,22 +367,22 @@ affs_fix_checksum(struct super_block *sb, struct buffer_head *bh) }
void -secs_to_datestamp(time_t secs, struct affs_date *ds) +secs_to_datestamp(time64_t secs, struct affs_date *ds) { u32 days; u32 minute; + s32 rem;
secs -= sys_tz.tz_minuteswest * 60 + ((8 * 365 + 2) * 24 * 60 * 60); if (secs < 0) secs = 0; - days = secs / 86400; - secs -= days * 86400; - minute = secs / 60; - secs -= minute * 60; + days = div_s64_rem(secs, 86400, &rem); + minute = rem / 60; + rem -= minute * 60;
ds->days = cpu_to_be32(days); ds->mins = cpu_to_be32(minute); - ds->ticks = cpu_to_be32(secs * 50); + ds->ticks = cpu_to_be32(rem * 50); }
umode_t diff --git a/fs/affs/super.c b/fs/affs/super.c index 5b50c4c..8836df5 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -32,7 +32,7 @@ affs_commit_super(struct super_block *sb, int wait) struct affs_root_tail *tail = AFFS_ROOT_TAIL(sb, bh);
lock_buffer(bh); - secs_to_datestamp(get_seconds(), &tail->disk_change); + secs_to_datestamp(ktime_get_real_seconds(), &tail->disk_change); affs_fix_checksum(sb, bh); unlock_buffer(bh);
On Tuesday 10 November 2015 22:25:42 DengChao wrote:
The affs code uses "time_t" and "get_seconds()". This will cause problems on 32-bit architectures in 2038 when time_t overflows. This patch replaces them with "time64_t" and "ktime_get_real_seconds()". This patch introduces expensive 64-bit divsion in "secs_to_datestamp()", considering this function is not called so often, the cost should be acceptable.
Signed-off-by: DengChao chao.deng@linaro.org
Patch looks great,
Reviewed-by: Arnd Bergmann arnd@arndb.de
Maybe post it again to the linux-fsdevel list. Unfortunately there is no maintainer for this, so one of us will have to pick up the patch directly, but maybe someone else can comment.
Arnd
On Tuesday 10 November 2015 17:49:21 Arnd Bergmann wrote:
On Tuesday 10 November 2015 22:25:42 DengChao wrote:
The affs code uses "time_t" and "get_seconds()". This will cause problems on 32-bit architectures in 2038 when time_t overflows. This patch replaces them with "time64_t" and "ktime_get_real_seconds()". This patch introduces expensive 64-bit divsion in "secs_to_datestamp()", considering this function is not called so often, the cost should be acceptable.
Signed-off-by: DengChao chao.deng@linaro.org
Patch looks great,
Reviewed-by: Arnd Bergmann arnd@arndb.de
Maybe post it again to the linux-fsdevel list. Unfortunately there is no maintainer for this, so one of us will have to pick up the patch directly, but maybe someone else can comment.
Actually linux-fsdevel + linux-kernel.