Commit f08957d0 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Linus Torvalds

fs/hpfs: extend gmt_to_local() conversion to 64-bit times

The VFS timestamps are all 64-bit now, the only missing piece for hpfs
is the internal conversion function.  One interesting bit about hpfs is
that it can already deal with moving the 136 year window of its
timestamps to support a much wider range than other file systems with
32-bit timestamps.  It also treats the timestamps as 'unsigned' on
64-bit architectures (but signed on 32-bit, because time_t always around
to negative numbers in 2038).

Changing the conversion to use time64_t makes 32-bit architectures
behave the same way as 64-bit.  For completeness, this also adds a
clamp_t call for each conversion, so we don't wrap the timestamps but
instead stay within the [0..U32_MAX] range of the on-disk timestamps.

Link: http://lkml.kernel.org/r/20180718115017.742609-3-arnd@arndb.deSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Cc: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent bcf451ec
...@@ -334,16 +334,23 @@ long hpfs_ioctl(struct file *file, unsigned cmd, unsigned long arg); ...@@ -334,16 +334,23 @@ long hpfs_ioctl(struct file *file, unsigned cmd, unsigned long arg);
* local time (HPFS) to GMT (Unix) * 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; extern struct timezone sys_tz;
return t + sys_tz.tz_minuteswest * 60 + hpfs_sb(s)->sb_timeshift; return 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; extern struct timezone sys_tz;
return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift; t = t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift;
return clamp_t(time64_t, t, 0, U32_MAX);
}
static inline time32_t local_get_seconds(struct super_block *s)
{
return gmt_to_local(s, ktime_get_real_seconds());
} }
/* /*
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
static void hpfs_update_directory_times(struct inode *dir) static void hpfs_update_directory_times(struct inode *dir)
{ {
time_t t = get_seconds(); time64_t t = local_to_gmt(dir->i_sb, local_get_seconds(dir->i_sb));
if (t == dir->i_mtime.tv_sec && if (t == dir->i_mtime.tv_sec &&
t == dir->i_ctime.tv_sec) t == dir->i_ctime.tv_sec)
return; return;
...@@ -50,7 +50,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ...@@ -50,7 +50,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
/*dee.archive = 0;*/ /*dee.archive = 0;*/
dee.hidden = name[0] == '.'; dee.hidden = name[0] == '.';
dee.fnode = cpu_to_le32(fno); 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(local_get_seconds(dir->i_sb));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result)
goto bail2; goto bail2;
...@@ -91,7 +91,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) ...@@ -91,7 +91,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
dnode->root_dnode = 1; dnode->root_dnode = 1;
dnode->up = cpu_to_le32(fno); dnode->up = cpu_to_le32(fno);
de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0); 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(local_get_seconds(dir->i_sb));
if (!(mode & 0222)) de->read_only = 1; if (!(mode & 0222)) de->read_only = 1;
de->first = de->directory = 1; de->first = de->directory = 1;
/*de->hidden = de->system = 0;*/ /*de->hidden = de->system = 0;*/
...@@ -151,7 +151,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, b ...@@ -151,7 +151,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, b
dee.archive = 1; dee.archive = 1;
dee.hidden = name[0] == '.'; dee.hidden = name[0] == '.';
dee.fnode = cpu_to_le32(fno); 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(local_get_seconds(dir->i_sb));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result)
...@@ -238,7 +238,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, de ...@@ -238,7 +238,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, de
dee.archive = 1; dee.archive = 1;
dee.hidden = name[0] == '.'; dee.hidden = name[0] == '.';
dee.fnode = cpu_to_le32(fno); 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(local_get_seconds(dir->i_sb));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result)
...@@ -314,7 +314,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy ...@@ -314,7 +314,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
dee.archive = 1; dee.archive = 1;
dee.hidden = name[0] == '.'; dee.hidden = name[0] == '.';
dee.fnode = cpu_to_le32(fno); 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(local_get_seconds(dir->i_sb));
result = new_inode(dir->i_sb); result = new_inode(dir->i_sb);
if (!result) if (!result)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment