"get_seconds()" and "time_t" will cause problems on 32-bit architectures in 2038 when time_t overflows. The hpfs code uses time32_t to represent time_t on disk, the range of time has been already lost, so that this patch just makes directly cast between time32_t and time_64t so as to remove time_t. Fortunately time32_t won't overflow until 2106.
Signed-off-by: DengChao chao.deng@linaro.org --- fs/hpfs/hpfs_fn.h | 26 ++++++++++++++++++++++---- fs/hpfs/namei.c | 19 ++++++++++++++----- 2 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index 975654a..0ef8f75 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h @@ -331,19 +331,37 @@ unsigned hpfs_get_free_dnodes(struct super_block *); long hpfs_ioctl(struct file *file, unsigned cmd, unsigned long arg);
/* + * Since time32_t is stored into media, the range has been already lost + * for time64_t anyway. Only thing we can do is directly cast between + * time32_t and time64_t. Forunately, time32_t won't overflow until 2106. + */ + +static inline time64_t cast_to_time64(time32_t t) +{ + return (time64_t)t; +} + +static inline time32_t cast_to_time32(time64_t t) +{ + return (time32_t)t; +} + +/* * local time (HPFS) to GMT (Unix) */
-static inline time_t local_to_gmt(struct super_block *s, time32_t t) +static inline time64_t local_to_gmt(struct super_block *s, time32_t t) { extern struct timezone sys_tz; - return t + sys_tz.tz_minuteswest * 60 + hpfs_sb(s)->sb_timeshift; + return cast_to_time64(t + sys_tz.tz_minuteswest * 60 + + hpfs_sb(s)->sb_timeshift); }
-static inline time32_t gmt_to_local(struct super_block *s, time_t t) +static inline time32_t gmt_to_local(struct super_block *s, time64_t t) { extern struct timezone sys_tz; - return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift; + return cast_to_time32(t - sys_tz.tz_minuteswest * 60 + - hpfs_sb(s)->sb_timeshift); }
/* diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 9fcb6f0..5fd608b 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c @@ -49,7 +49,9 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) /*dee.archive = 0;*/ dee.hidden = name[0] == '.'; dee.fnode = cpu_to_le32(fno); - dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); + dee.creation_date = dee.write_date = dee.read_date = + cpu_to_le32(gmt_to_local(dir->i_sb, + ktime_get_real_seconds())); result = new_inode(dir->i_sb); if (!result) goto bail2; @@ -90,7 +92,9 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) dnode->root_dnode = 1; dnode->up = cpu_to_le32(fno); de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0); - de->creation_date = de->write_date = de->read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); + de->creation_date = de->write_date = de->read_date + = cpu_to_le32(gmt_to_local(dir->i_sb, + ktime_get_real_seconds())); if (!(mode & 0222)) de->read_only = 1; de->first = de->directory = 1; /*de->hidden = de->system = 0;*/ @@ -150,7 +154,9 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, b dee.archive = 1; dee.hidden = name[0] == '.'; dee.fnode = cpu_to_le32(fno); - dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); + dee.creation_date = dee.write_date = dee.read_date + = cpu_to_le32(gmt_to_local(dir->i_sb, + ktime_get_real_seconds()));
result = new_inode(dir->i_sb); if (!result) @@ -239,7 +245,9 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, de dee.archive = 1; dee.hidden = name[0] == '.'; dee.fnode = cpu_to_le32(fno); - dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); + dee.creation_date = dee.write_date = dee.read_date + = cpu_to_le32(gmt_to_local(dir->i_sb, + ktime_get_real_seconds()));
result = new_inode(dir->i_sb); if (!result) @@ -315,7 +323,8 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy dee.archive = 1; dee.hidden = name[0] == '.'; dee.fnode = cpu_to_le32(fno); - dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); + dee.creation_date = dee.write_date = dee.read_date = + cpu_to_le32(gmt_to_local(dir->i_sb, ktime_get_real_seconds()));
result = new_inode(dir->i_sb); if (!result)