Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nilfs2: use time64_t internally

The superblock and segment timestamps are used only internally in nilfs2
and can be read out using sysfs.

Since we are using the old 'get_seconds()' interface and store the data
as timestamps, the behavior differs slightly between 64-bit and 32-bit
kernels, the latter will show incorrect timestamps after 2038 in sysfs,
and presumably fail completely in 2106 as comparisons go wrong.

This changes nilfs2 to use time64_t with ktime_get_real_seconds() to
handle timestamps, making the behavior consistent and correct on both
32-bit and 64-bit machines.

The on-disk format already uses 64-bit timestamps, so nothing changes
there.

Link: http://lkml.kernel.org/r/20180122211050.1286441-1-arnd@arndb.de
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Arnd Bergmann and committed by
Linus Torvalds
fb04b91b ca3a4569

+23 -24
+1 -1
fs/nilfs2/segbuf.c
··· 130 130 } 131 131 132 132 int nilfs_segbuf_reset(struct nilfs_segment_buffer *segbuf, unsigned int flags, 133 - time_t ctime, __u64 cno) 133 + time64_t ctime, __u64 cno) 134 134 { 135 135 int err; 136 136
+2 -2
fs/nilfs2/segbuf.h
··· 46 46 unsigned long nfileblk; 47 47 u64 seg_seq; 48 48 __u64 cno; 49 - time_t ctime; 49 + time64_t ctime; 50 50 sector_t next; 51 51 }; 52 52 ··· 120 120 struct nilfs_segment_buffer *prev); 121 121 void nilfs_segbuf_set_next_segnum(struct nilfs_segment_buffer *, __u64, 122 122 struct the_nilfs *); 123 - int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned int, time_t, 123 + int nilfs_segbuf_reset(struct nilfs_segment_buffer *, unsigned int, time64_t, 124 124 __u64); 125 125 int nilfs_segbuf_extend_segsum(struct nilfs_segment_buffer *); 126 126 int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *,
+1 -1
fs/nilfs2/segment.c
··· 2040 2040 goto out; 2041 2041 2042 2042 /* Update time stamp */ 2043 - sci->sc_seg_ctime = get_seconds(); 2043 + sci->sc_seg_ctime = ktime_get_real_seconds(); 2044 2044 2045 2045 err = nilfs_segctor_collect(sci, nilfs, mode); 2046 2046 if (unlikely(err))
+1 -1
fs/nilfs2/segment.h
··· 157 157 unsigned long sc_blk_cnt; 158 158 unsigned long sc_datablk_cnt; 159 159 unsigned long sc_nblk_this_inc; 160 - time_t sc_seg_ctime; 160 + time64_t sc_seg_ctime; 161 161 __u64 sc_cno; 162 162 unsigned long sc_flags; 163 163
+1 -1
fs/nilfs2/sufile.c
··· 526 526 * @modtime: modification time (option) 527 527 */ 528 528 int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, 529 - unsigned long nblocks, time_t modtime) 529 + unsigned long nblocks, time64_t modtime) 530 530 { 531 531 struct buffer_head *bh; 532 532 struct nilfs_segment_usage *su;
+1 -1
fs/nilfs2/sufile.h
··· 35 35 int nilfs_sufile_alloc(struct inode *, __u64 *); 36 36 int nilfs_sufile_mark_dirty(struct inode *sufile, __u64 segnum); 37 37 int nilfs_sufile_set_segment_usage(struct inode *sufile, __u64 segnum, 38 - unsigned long nblocks, time_t modtime); 38 + unsigned long nblocks, time64_t modtime); 39 39 int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *); 40 40 ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned int, 41 41 size_t);
+2 -2
fs/nilfs2/super.c
··· 283 283 { 284 284 struct the_nilfs *nilfs = sb->s_fs_info; 285 285 struct nilfs_super_block **sbp = nilfs->ns_sbp; 286 - time_t t; 286 + time64_t t; 287 287 288 288 /* nilfs->ns_sem must be locked by the caller. */ 289 - t = get_seconds(); 289 + t = ktime_get_real_seconds(); 290 290 nilfs->ns_sbwtime = t; 291 291 sbp[0]->s_wtime = cpu_to_le64(t); 292 292 sbp[0]->s_sum = 0;
+10 -11
fs/nilfs2/sysfs.c
··· 31 31 #define NILFS_SHOW_TIME(time_t_val, buf) ({ \ 32 32 struct tm res; \ 33 33 int count = 0; \ 34 - time_to_tm(time_t_val, 0, &res); \ 34 + time64_to_tm(time_t_val, 0, &res); \ 35 35 res.tm_year += 1900; \ 36 36 res.tm_mon += 1; \ 37 37 count = scnprintf(buf, PAGE_SIZE, \ ··· 579 579 struct the_nilfs *nilfs, 580 580 char *buf) 581 581 { 582 - time_t ctime; 582 + time64_t ctime; 583 583 584 584 down_read(&nilfs->ns_segctor_sem); 585 585 ctime = nilfs->ns_ctime; ··· 593 593 struct the_nilfs *nilfs, 594 594 char *buf) 595 595 { 596 - time_t ctime; 596 + time64_t ctime; 597 597 598 598 down_read(&nilfs->ns_segctor_sem); 599 599 ctime = nilfs->ns_ctime; 600 600 up_read(&nilfs->ns_segctor_sem); 601 601 602 - return snprintf(buf, PAGE_SIZE, "%llu\n", (unsigned long long)ctime); 602 + return snprintf(buf, PAGE_SIZE, "%llu\n", ctime); 603 603 } 604 604 605 605 static ssize_t ··· 607 607 struct the_nilfs *nilfs, 608 608 char *buf) 609 609 { 610 - time_t nongc_ctime; 610 + time64_t nongc_ctime; 611 611 612 612 down_read(&nilfs->ns_segctor_sem); 613 613 nongc_ctime = nilfs->ns_nongc_ctime; ··· 621 621 struct the_nilfs *nilfs, 622 622 char *buf) 623 623 { 624 - time_t nongc_ctime; 624 + time64_t nongc_ctime; 625 625 626 626 down_read(&nilfs->ns_segctor_sem); 627 627 nongc_ctime = nilfs->ns_nongc_ctime; 628 628 up_read(&nilfs->ns_segctor_sem); 629 629 630 - return snprintf(buf, PAGE_SIZE, "%llu\n", 631 - (unsigned long long)nongc_ctime); 630 + return snprintf(buf, PAGE_SIZE, "%llu\n", nongc_ctime); 632 631 } 633 632 634 633 static ssize_t ··· 727 728 struct the_nilfs *nilfs, 728 729 char *buf) 729 730 { 730 - time_t sbwtime; 731 + time64_t sbwtime; 731 732 732 733 down_read(&nilfs->ns_sem); 733 734 sbwtime = nilfs->ns_sbwtime; ··· 741 742 struct the_nilfs *nilfs, 742 743 char *buf) 743 744 { 744 - time_t sbwtime; 745 + time64_t sbwtime; 745 746 746 747 down_read(&nilfs->ns_sem); 747 748 sbwtime = nilfs->ns_sbwtime; 748 749 up_read(&nilfs->ns_sem); 749 750 750 - return snprintf(buf, PAGE_SIZE, "%llu\n", (unsigned long long)sbwtime); 751 + return snprintf(buf, PAGE_SIZE, "%llu\n", sbwtime); 751 752 } 752 753 753 754 static ssize_t
+4 -4
fs/nilfs2/the_nilfs.h
··· 116 116 */ 117 117 struct buffer_head *ns_sbh[2]; 118 118 struct nilfs_super_block *ns_sbp[2]; 119 - time_t ns_sbwtime; 119 + time64_t ns_sbwtime; 120 120 unsigned int ns_sbwcount; 121 121 unsigned int ns_sbsize; 122 122 unsigned int ns_mount_state; ··· 131 131 __u64 ns_nextnum; 132 132 unsigned long ns_pseg_offset; 133 133 __u64 ns_cno; 134 - time_t ns_ctime; 135 - time_t ns_nongc_ctime; 134 + time64_t ns_ctime; 135 + time64_t ns_nongc_ctime; 136 136 atomic_t ns_ndirtyblks; 137 137 138 138 /* ··· 267 267 268 268 static inline int nilfs_sb_need_update(struct the_nilfs *nilfs) 269 269 { 270 - u64 t = get_seconds(); 270 + u64 t = ktime_get_real_seconds(); 271 271 272 272 return t < nilfs->ns_sbwtime || 273 273 t > nilfs->ns_sbwtime + nilfs->ns_sb_update_freq;