summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2018-08-17 18:43:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-08-17 19:20:27 -0400
commitf08957d0ffe91f346c47cef95139c54aa7275cfe (patch)
tree16d260a7e3354f56e00d1227be8aabac84f97ef0
parentbcf451ecfc8d45618d13c9e4abcbbd770af20cc9 (diff)
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.de Signed-off-by: Arnd 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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/hpfs/hpfs_fn.h13
-rw-r--r--fs/hpfs/namei.c12
2 files changed, 16 insertions, 9 deletions
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index 2a153aed4c19..ab2e7cc2ff33 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -334,16 +334,23 @@ long hpfs_ioctl(struct file *file, unsigned cmd, unsigned long arg);
334 * local time (HPFS) to GMT (Unix) 334 * local time (HPFS) to GMT (Unix)
335 */ 335 */
336 336
337static inline time_t local_to_gmt(struct super_block *s, time32_t t) 337static inline time64_t local_to_gmt(struct super_block *s, time32_t t)
338{ 338{
339 extern struct timezone sys_tz; 339 extern struct timezone sys_tz;
340 return t + sys_tz.tz_minuteswest * 60 + hpfs_sb(s)->sb_timeshift; 340 return t + sys_tz.tz_minuteswest * 60 + hpfs_sb(s)->sb_timeshift;
341} 341}
342 342
343static inline time32_t gmt_to_local(struct super_block *s, time_t t) 343static inline time32_t gmt_to_local(struct super_block *s, time64_t t)
344{ 344{
345 extern struct timezone sys_tz; 345 extern struct timezone sys_tz;
346 return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift; 346 t = t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift;
347
348 return clamp_t(time64_t, t, 0, U32_MAX);
349}
350
351static inline time32_t local_get_seconds(struct super_block *s)
352{
353 return gmt_to_local(s, ktime_get_real_seconds());
347} 354}
348 355
349/* 356/*
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index a3615e4c730d..082b7c76dd0c 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -11,7 +11,7 @@
11 11
12static void hpfs_update_directory_times(struct inode *dir) 12static void hpfs_update_directory_times(struct inode *dir)
13{ 13{
14 time_t t = get_seconds(); 14 time64_t t = local_to_gmt(dir->i_sb, local_get_seconds(dir->i_sb));
15 if (t == dir->i_mtime.tv_sec && 15 if (t == dir->i_mtime.tv_sec &&
16 t == dir->i_ctime.tv_sec) 16 t == dir->i_ctime.tv_sec)
17 return; 17 return;
@@ -50,7 +50,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
50 /*dee.archive = 0;*/ 50 /*dee.archive = 0;*/
51 dee.hidden = name[0] == '.'; 51 dee.hidden = name[0] == '.';
52 dee.fnode = cpu_to_le32(fno); 52 dee.fnode = cpu_to_le32(fno);
53 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); 53 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
54 result = new_inode(dir->i_sb); 54 result = new_inode(dir->i_sb);
55 if (!result) 55 if (!result)
56 goto bail2; 56 goto bail2;
@@ -91,7 +91,7 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
91 dnode->root_dnode = 1; 91 dnode->root_dnode = 1;
92 dnode->up = cpu_to_le32(fno); 92 dnode->up = cpu_to_le32(fno);
93 de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0); 93 de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
94 de->creation_date = de->write_date = de->read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); 94 de->creation_date = de->write_date = de->read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
95 if (!(mode & 0222)) de->read_only = 1; 95 if (!(mode & 0222)) de->read_only = 1;
96 de->first = de->directory = 1; 96 de->first = de->directory = 1;
97 /*de->hidden = de->system = 0;*/ 97 /*de->hidden = de->system = 0;*/
@@ -151,7 +151,7 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, b
151 dee.archive = 1; 151 dee.archive = 1;
152 dee.hidden = name[0] == '.'; 152 dee.hidden = name[0] == '.';
153 dee.fnode = cpu_to_le32(fno); 153 dee.fnode = cpu_to_le32(fno);
154 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); 154 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
155 155
156 result = new_inode(dir->i_sb); 156 result = new_inode(dir->i_sb);
157 if (!result) 157 if (!result)
@@ -238,7 +238,7 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, de
238 dee.archive = 1; 238 dee.archive = 1;
239 dee.hidden = name[0] == '.'; 239 dee.hidden = name[0] == '.';
240 dee.fnode = cpu_to_le32(fno); 240 dee.fnode = cpu_to_le32(fno);
241 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); 241 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
242 242
243 result = new_inode(dir->i_sb); 243 result = new_inode(dir->i_sb);
244 if (!result) 244 if (!result)
@@ -314,7 +314,7 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
314 dee.archive = 1; 314 dee.archive = 1;
315 dee.hidden = name[0] == '.'; 315 dee.hidden = name[0] == '.';
316 dee.fnode = cpu_to_le32(fno); 316 dee.fnode = cpu_to_le32(fno);
317 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(gmt_to_local(dir->i_sb, get_seconds())); 317 dee.creation_date = dee.write_date = dee.read_date = cpu_to_le32(local_get_seconds(dir->i_sb));
318 318
319 result = new_inode(dir->i_sb); 319 result = new_inode(dir->i_sb);
320 if (!result) 320 if (!result)