History

Merge tag 'y2038-vfs' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground

Pull y2038 vfs updates from Arnd Bergmann: "Add inode timestamp clamping. This series from Deepa Dinamani adds a per-superblock minimum/maximum timestamp limit for a file system, and clamps timestamps as they are written, to avoid random behavior from integer overflow as well as having different time stamps on disk vs in memory. At mount time, a warning is now printed for any file system that can represent current timestamps but not future timestamps more than 30 years into the future, similar to the arbitrary 30 year limit that was added to settimeofday(). This was picked as a compromise to warn users to migrate to other file systems (e.g. ext4 instead of ext3) when they need the file system to survive beyond 2038 (or similar limits in other file systems), but not get in the way of normal usage" * tag 'y2038-vfs' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground: ext4: Reduce ext4 timestamp warnings isofs: Initialize filesystem timestamp ranges pstore: fs superblock limits fs: omfs: Initialize filesystem timestamp ranges fs: hpfs: Initialize filesystem timestamp ranges fs: ceph: Initialize filesystem timestamp ranges fs: sysv: Initialize filesystem timestamp ranges fs: affs: Initialize filesystem timestamp ranges fs: fat: Initialize filesystem timestamp ranges fs: cifs: Initialize filesystem timestamp ranges fs: nfs: Initialize filesystem timestamp ranges ext4: Initialize timestamps limits 9p: Fill min and max timestamps in sb fs: Fill in max and min timestamps in superblock utimes: Clamp the timestamps before update mount: Add mount warning for impending timestamp expiry timestamp_truncate: Replace users of timespec64_trunc vfs: Add timestamp_truncate() api vfs: Add file timestamp range support

Linus Torvalds committed 7 years ago

Commit cfb82e12 parents b41dae0 cba465b47 files · +294 −72Browse files

Unified · Split

47 files
  1. fs/9p/vfs_super.c +5 −1
  2. fs/affs/amigaffs.c +1 −1
  3. fs/affs/amigaffs.h +3 −0
  4. fs/affs/inode.c +2 −2
  5. fs/affs/super.c +4 −0
  6. fs/attr.c +12 −9
  7. fs/befs/linuxvfs.c +2 −0
  8. fs/bfs/inode.c +2 −0
  9. fs/ceph/super.c +2 −0
  10. fs/cifs/cifsfs.c +22 −0
  11. fs/cifs/netmisc.c +7 −7
  12. fs/coda/inode.c +3 −0
  13. fs/configfs/inode.c +6 −6
  14. fs/cramfs/inode.c +2 −0
  15. fs/efs/super.c +2 −0
  16. fs/ext2/super.c +2 −0
  17. fs/ext4/ext4.h +7 −1
  18. fs/ext4/super.c +15 −2
  19. fs/f2fs/file.c +12 −9
  20. fs/fat/inode.c +12 −0
  21. fs/freevxfs/vxfs_super.c +2 −0
  22. fs/hpfs/hpfs_fn.h +2 −4
  23. fs/hpfs/super.c +2 −0
  24. fs/inode.c +32 −1
  25. fs/isofs/inode.c +7 −0
  26. fs/jffs2/fs.c +3 −0
  27. fs/jfs/super.c +2 −0
  28. fs/kernfs/inode.c +3 −4
  29. fs/minix/inode.c +2 −0
  30. fs/namespace.c +32 −1
  31. fs/nfs/super.c +19 −1
  32. fs/ntfs/inode.c +12 −9
  33. fs/omfs/inode.c +4 −0
  34. fs/pstore/ram.c +2 −0
  35. fs/qnx4/inode.c +2 −0
  36. fs/qnx6/inode.c +2 −0
  37. fs/reiserfs/super.c +3 −0
  38. fs/romfs/super.c +2 −0
  39. fs/squashfs/super.c +2 −0
  40. fs/super.c +2 −0
  41. fs/sysv/super.c +4 −1
  42. fs/ubifs/file.c +12 −9
  43. fs/ufs/super.c +7 −0
  44. fs/utimes.c +2 −4
  45. fs/xfs/xfs_super.c +2 −0
  46. include/linux/fs.h +5 −0
  47. include/linux/time64.h +2 −0
fs/9p/vfs_super.c+5−1
@@ -69,8 +69,12 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses, · 68 unmodified lines
6969 if (v9fs_proto_dotl(v9ses)) {
7070 sb->s_op = &v9fs_super_ops_dotl;
7171 sb->s_xattr = v9fs_xattr_handlers;
72− } else
72+ } else {
7373 sb->s_op = &v9fs_super_ops;
74+ sb->s_time_max = U32_MAX;
75+ }
76+
77+ sb->s_time_min = 0;
7478
7579 ret = super_setup_bdi(sb);
7680 if (ret)
fs/affs/amigaffs.c+1−1
@@ -375,7 +375,7 @@ affs_secs_to_datestamp(time64_t secs, struct affs_date *ds) · 374 unmodified lines
375375 u32 minute;
376376 s32 rem;
377377
378− secs -= sys_tz.tz_minuteswest * 60 + ((8 * 365 + 2) * 24 * 60 * 60);
378+ secs -= sys_tz.tz_minuteswest * 60 + AFFS_EPOCH_DELTA;
379379 if (secs < 0)
380380 secs = 0;
381381 days = div_s64_rem(secs, 86400, &rem);
fs/affs/amigaffs.h+3−0
@@ -32,6 +32,9 @@ · 31 unmodified lines
3232
3333 #define AFFS_ROOT_BMAPS 25
3434
35+/* Seconds since Amiga epoch of 1978/01/01 to UNIX */
36+#define AFFS_EPOCH_DELTA ((8 * 365 + 2) * 86400LL)
37+
3538 struct affs_date {
3639 __be32 days;
3740 __be32 mins;
fs/affs/inode.c+2−2
@@ -150,10 +150,10 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) · 149 unmodified lines
150150 }
151151
152152 inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec
153− = (be32_to_cpu(tail->change.days) * (24 * 60 * 60) +
153+ = (be32_to_cpu(tail->change.days) * 86400LL +
154154 be32_to_cpu(tail->change.mins) * 60 +
155155 be32_to_cpu(tail->change.ticks) / 50 +
156− ((8 * 365 + 2) * 24 * 60 * 60)) +
156+ AFFS_EPOCH_DELTA) +
157157 sys_tz.tz_minuteswest * 60;
158158 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0;
159159 affs_brelse(bh);
fs/affs/super.c+4−0
@@ -355,6 +355,10 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) · 354 unmodified lines
355355 sb->s_op = &affs_sops;
356356 sb->s_flags |= SB_NODIRATIME;
357357
358+ sb->s_time_gran = NSEC_PER_SEC;
359+ sb->s_time_min = sys_tz.tz_minuteswest * 60 + AFFS_EPOCH_DELTA;
360+ sb->s_time_max = 86400LL * U32_MAX + 86400 + sb->s_time_min;
361+
358362 sbi = kzalloc(sizeof(struct affs_sb_info), GFP_KERNEL);
359363 if (!sbi)
360364 return -ENOMEM;
fs/attr.c+12−9
@@ -183,15 +183,18 @@ void setattr_copy(struct inode *inode, const struct iattr *attr) · 182 unmodified lines
183183 inode->i_uid = attr->ia_uid;
184184 if (ia_valid & ATTR_GID)
185185 inode->i_gid = attr->ia_gid;
186− if (ia_valid & ATTR_ATIME)
187− inode->i_atime = timespec64_trunc(attr->ia_atime,
188− inode->i_sb->s_time_gran);
189− if (ia_valid & ATTR_MTIME)
190− inode->i_mtime = timespec64_trunc(attr->ia_mtime,
191− inode->i_sb->s_time_gran);
192− if (ia_valid & ATTR_CTIME)
193− inode->i_ctime = timespec64_trunc(attr->ia_ctime,
194− inode->i_sb->s_time_gran);
186+ if (ia_valid & ATTR_ATIME) {
187+ inode->i_atime = timestamp_truncate(attr->ia_atime,
188+ inode);
189+ }
190+ if (ia_valid & ATTR_MTIME) {
191+ inode->i_mtime = timestamp_truncate(attr->ia_mtime,
192+ inode);
193+ }
194+ if (ia_valid & ATTR_CTIME) {
195+ inode->i_ctime = timestamp_truncate(attr->ia_ctime,
196+ inode);
197+ }
195198 if (ia_valid & ATTR_MODE) {
196199 umode_t mode = attr->ia_mode;
197200
fs/befs/linuxvfs.c+2−0
@@ -893,6 +893,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent) · 892 unmodified lines
893893 sb_set_blocksize(sb, (ulong) befs_sb->block_size);
894894 sb->s_op = &befs_sops;
895895 sb->s_export_op = &befs_export_operations;
896+ sb->s_time_min = 0;
897+ sb->s_time_max = 0xffffffffffffll;
896898 root = befs_iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir)));
897899 if (IS_ERR(root)) {
898900 ret = PTR_ERR(root);
fs/bfs/inode.c+2−0
@@ -324,6 +324,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent) · 323 unmodified lines
324324 return -ENOMEM;
325325 mutex_init(&info->bfs_lock);
326326 s->s_fs_info = info;
327+ s->s_time_min = 0;
328+ s->s_time_max = U32_MAX;
327329
328330 sb_set_blocksize(s, BFS_BSIZE);
329331
fs/ceph/super.c+2−0
@@ -979,6 +979,8 @@ static int ceph_set_super(struct super_block *s, void *data) · 978 unmodified lines
979979 s->s_export_op = &ceph_export_ops;
980980
981981 s->s_time_gran = 1;
982+ s->s_time_min = 0;
983+ s->s_time_max = U32_MAX;
982984
983985 ret = set_anon_super(s, NULL); /* what is that second arg for? */
984986 if (ret != 0)
fs/cifs/cifsfs.c+22−0
@@ -56,6 +56,15 @@ · 55 unmodified lines
5656 #include "dfs_cache.h"
5757 #endif
5858
59+/*
60+ * DOS dates from 1980/1/1 through 2107/12/31
61+ * Protocol specifications indicate the range should be to 119, which
62+ * limits maximum year to 2099. But this range has not been checked.
63+ */
64+#define SMB_DATE_MAX (127<<9 | 12<<5 | 31)
65+#define SMB_DATE_MIN (0<<9 | 1<<5 | 1)
66+#define SMB_TIME_MAX (23<<11 | 59<<5 | 29)
67+
5968 int cifsFYI = 0;
6069 bool traceSMB;
6170 bool enable_oplocks = true;
@@ -142,6 +151,7 @@ cifs_read_super(struct super_block *sb) · 80 unmodified lines
142151 struct inode *inode;
143152 struct cifs_sb_info *cifs_sb;
144153 struct cifs_tcon *tcon;
154+ struct timespec64 ts;
145155 int rc = 0;
146156
147157 cifs_sb = CIFS_SB(sb);
@@ -161,6 +171,18 @@ cifs_read_super(struct super_block *sb) · 13 unmodified lines
161171 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
162172 sb->s_time_gran = 100;
163173
174+ if (tcon->unix_ext) {
175+ ts = cifs_NTtimeToUnix(0);
176+ sb->s_time_min = ts.tv_sec;
177+ ts = cifs_NTtimeToUnix(cpu_to_le64(S64_MAX));
178+ sb->s_time_max = ts.tv_sec;
179+ } else {
180+ ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MIN), 0, 0);
181+ sb->s_time_min = ts.tv_sec;
182+ ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MAX), cpu_to_le16(SMB_TIME_MAX), 0);
183+ sb->s_time_max = ts.tv_sec;
184+ }
185+
164186 sb->s_magic = CIFS_MAGIC_NUMBER;
165187 sb->s_op = &cifs_super_ops;
166188 sb->s_xattr = cifs_xattr_handlers;
fs/cifs/netmisc.c+7−7
@@ -949,8 +949,8 @@ static const int total_days_of_prev_months[] = { · 948 unmodified lines
949949 struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
950950 {
951951 struct timespec64 ts;
952− time64_t sec;
953− int min, days, month, year;
952+ time64_t sec, days;
953+ int min, day, month, year;
954954 u16 date = le16_to_cpu(le_date);
955955 u16 time = le16_to_cpu(le_time);
956956 SMB_TIME *st = (SMB_TIME *)&time;
@@ -966,15 +966,15 @@ struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) · 9 unmodified lines
966966 sec += 60 * 60 * st->Hours;
967967 if (st->Hours > 24)
968968 cifs_dbg(VFS, "illegal hours %d\n", st->Hours);
969− days = sd->Day;
969+ day = sd->Day;
970970 month = sd->Month;
971− if (days < 1 || days > 31 || month < 1 || month > 12) {
972− cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, days);
973− days = clamp(days, 1, 31);
971+ if (day < 1 || day > 31 || month < 1 || month > 12) {
972+ cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, day);
973+ day = clamp(day, 1, 31);
974974 month = clamp(month, 1, 12);
975975 }
976976 month -= 1;
977− days += total_days_of_prev_months[month];
977+ days = day + total_days_of_prev_months[month];
978978 days += 3652; /* account for difference in days between 1980 and 1970 */
979979 year = sd->Year;
980980 days += year * 365;
fs/coda/inode.c+3−0
@@ -188,6 +188,9 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) · 187 unmodified lines
188188 sb->s_magic = CODA_SUPER_MAGIC;
189189 sb->s_op = &coda_super_operations;
190190 sb->s_d_op = &coda_dentry_operations;
191+ sb->s_time_gran = 1;
192+ sb->s_time_min = S64_MIN;
193+ sb->s_time_max = S64_MAX;
191194
192195 error = super_setup_bdi(sb);
193196 if (error)
fs/configfs/inode.c+6−6
@@ -76,14 +76,14 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) · 75 unmodified lines
7676 if (ia_valid & ATTR_GID)
7777 sd_iattr->ia_gid = iattr->ia_gid;
7878 if (ia_valid & ATTR_ATIME)
79− sd_iattr->ia_atime = timespec64_trunc(iattr->ia_atime,
80− inode->i_sb->s_time_gran);
79+ sd_iattr->ia_atime = timestamp_truncate(iattr->ia_atime,
80+ inode);
8181 if (ia_valid & ATTR_MTIME)
82− sd_iattr->ia_mtime = timespec64_trunc(iattr->ia_mtime,
83− inode->i_sb->s_time_gran);
82+ sd_iattr->ia_mtime = timestamp_truncate(iattr->ia_mtime,
83+ inode);
8484 if (ia_valid & ATTR_CTIME)
85− sd_iattr->ia_ctime = timespec64_trunc(iattr->ia_ctime,
86− inode->i_sb->s_time_gran);
85+ sd_iattr->ia_ctime = timestamp_truncate(iattr->ia_ctime,
86+ inode);
8787 if (ia_valid & ATTR_MODE) {
8888 umode_t mode = iattr->ia_mode;
8989
fs/cramfs/inode.c+2−0
@@ -597,6 +597,8 @@ static int cramfs_finalize_super(struct super_block *sb, · 596 unmodified lines
597597
598598 /* Set it all up.. */
599599 sb->s_flags |= SB_RDONLY;
600+ sb->s_time_min = 0;
601+ sb->s_time_max = 0;
600602 sb->s_op = &cramfs_ops;
601603 root = get_cramfs_inode(sb, cramfs_root, 0);
602604 if (IS_ERR(root))
fs/efs/super.c+2−0
@@ -257,6 +257,8 @@ static int efs_fill_super(struct super_block *s, void *d, int silent) · 256 unmodified lines
257257 if (!sb)
258258 return -ENOMEM;
259259 s->s_fs_info = sb;
260+ s->s_time_min = 0;
261+ s->s_time_max = U32_MAX;
260262
261263 s->s_magic = EFS_SUPER_MAGIC;
262264 if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) {
fs/ext2/super.c+2−0
@@ -1002,6 +1002,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) · 1001 unmodified lines
10021002
10031003 sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits);
10041004 sb->s_max_links = EXT2_LINK_MAX;
1005+ sb->s_time_min = S32_MIN;
1006+ sb->s_time_max = S32_MAX;
10051007
10061008 if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) {
10071009 sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
fs/ext4/ext4.h+7−1
@@ -832,11 +832,13 @@ static inline void ext4_decode_extra_time(struct timespec64 *time, · 831 unmodified lines
832832
833833 #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \
834834 do { \
835− (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \
836835 if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) {\
836+ (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \
837837 (raw_inode)->xtime ## _extra = \
838838 ext4_encode_extra_time(&(inode)->xtime); \
839839 } \
840+ else \
841+ (raw_inode)->xtime = cpu_to_le32(clamp_t(int32_t, (inode)->xtime.tv_sec, S32_MIN, S32_MAX)); \
840842 } while (0)
841843
842844 #define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode) \
@@ -1643,6 +1645,10 @@ static inline bool ext4_verity_in_progress(struct inode *inode) · 800 unmodified lines
16431645
16441646 #define EXT4_GOOD_OLD_INODE_SIZE 128
16451647
1648+#define EXT4_EXTRA_TIMESTAMP_MAX (((s64)1 << 34) - 1 + S32_MIN)
1649+#define EXT4_NON_EXTRA_TIMESTAMP_MAX S32_MAX
1650+#define EXT4_TIMESTAMP_MIN S32_MIN
1651+
16461652 /*
16471653 * Feature set definitions
16481654 */
fs/ext4/super.c+15−2
@@ -4039,8 +4039,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) · 4038 unmodified lines
40394039 sbi->s_inode_size);
40404040 goto failed_mount;
40414041 }
4042− if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE)
4043− sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2);
4042+ /*
4043+ * i_atime_extra is the last extra field available for [acm]times in
4044+ * struct ext4_inode. Checking for that field should suffice to ensure
4045+ * we have extra space for all three.
4046+ */
4047+ if (sbi->s_inode_size >= offsetof(struct ext4_inode, i_atime_extra) +
4048+ sizeof(((struct ext4_inode *)0)->i_atime_extra)) {
4049+ sb->s_time_gran = 1;
4050+ sb->s_time_max = EXT4_EXTRA_TIMESTAMP_MAX;
4051+ } else {
4052+ sb->s_time_gran = NSEC_PER_SEC;
4053+ sb->s_time_max = EXT4_NON_EXTRA_TIMESTAMP_MAX;
4054+ }
4055+
4056+ sb->s_time_min = EXT4_TIMESTAMP_MIN;
40444057 }
40454058
40464059 sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
fs/f2fs/file.c+12−9
@@ -745,15 +745,18 @@ static void __setattr_copy(struct inode *inode, const struct iattr *attr) · 744 unmodified lines
745745 inode->i_uid = attr->ia_uid;
746746 if (ia_valid & ATTR_GID)
747747 inode->i_gid = attr->ia_gid;
748− if (ia_valid & ATTR_ATIME)
749− inode->i_atime = timespec64_trunc(attr->ia_atime,
750− inode->i_sb->s_time_gran);
751− if (ia_valid & ATTR_MTIME)
752− inode->i_mtime = timespec64_trunc(attr->ia_mtime,
753− inode->i_sb->s_time_gran);
754− if (ia_valid & ATTR_CTIME)
755− inode->i_ctime = timespec64_trunc(attr->ia_ctime,
756− inode->i_sb->s_time_gran);
748+ if (ia_valid & ATTR_ATIME) {
749+ inode->i_atime = timestamp_truncate(attr->ia_atime,
750+ inode);
751+ }
752+ if (ia_valid & ATTR_MTIME) {
753+ inode->i_mtime = timestamp_truncate(attr->ia_mtime,
754+ inode);
755+ }
756+ if (ia_valid & ATTR_CTIME) {
757+ inode->i_ctime = timestamp_truncate(attr->ia_ctime,
758+ inode);
759+ }
757760 if (ia_valid & ATTR_MODE) {
758761 umode_t mode = attr->ia_mode;
759762
fs/fat/inode.c+12−0
@@ -31,6 +31,11 @@ · 30 unmodified lines
3131
3232 #define KB_IN_SECTORS 2
3333
34+/* DOS dates from 1980/1/1 through 2107/12/31 */
35+#define FAT_DATE_MIN (0<<9 | 1<<5 | 1)
36+#define FAT_DATE_MAX (127<<9 | 12<<5 | 31)
37+#define FAT_TIME_MAX (23<<11 | 59<<5 | 29)
38+
3439 /*
3540 * A deserialized copy of the on-disk structure laid out in struct
3641 * fat_boot_sector.
@@ -1605,6 +1610,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, · 1568 unmodified lines
16051610 int debug;
16061611 long error;
16071612 char buf[50];
1613+ struct timespec64 ts;
16081614
16091615 /*
16101616 * GFP_KERNEL is ok here, because while we do hold the
@@ -1698,6 +1704,12 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, · 87 unmodified lines
16981704 sbi->free_clus_valid = 0;
16991705 sbi->prev_free = FAT_START_ENT;
17001706 sb->s_maxbytes = 0xffffffff;
1707+ fat_time_fat2unix(sbi, &ts, 0, cpu_to_le16(FAT_DATE_MIN), 0);
1708+ sb->s_time_min = ts.tv_sec;
1709+
1710+ fat_time_fat2unix(sbi, &ts, cpu_to_le16(FAT_TIME_MAX),
1711+ cpu_to_le16(FAT_DATE_MAX), 0);
1712+ sb->s_time_max = ts.tv_sec;
17011713
17021714 if (!sbi->fat_length && bpb.fat32_length) {
17031715 struct fat_boot_fsinfo *fsinfo;
fs/freevxfs/vxfs_super.c+2−0
@@ -229,6 +229,8 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) · 228 unmodified lines
229229
230230 sbp->s_op = &vxfs_super_ops;
231231 sbp->s_fs_info = infp;
232+ sbp->s_time_min = 0;
233+ sbp->s_time_max = U32_MAX;
232234
233235 if (!vxfs_try_sb_magic(sbp, silent, 1,
234236 (__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) {
fs/hpfs/hpfs_fn.h+2−4
@@ -334,7 +334,7 @@ long hpfs_ioctl(struct file *file, unsigned cmd, unsigned long arg); · 333 unmodified lines
334334 * local time (HPFS) to GMT (Unix)
335335 */
336336
337−static inline time64_t local_to_gmt(struct super_block *s, time32_t t)
337+static inline time64_t local_to_gmt(struct super_block *s, time64_t t)
338338 {
339339 extern struct timezone sys_tz;
340340 return t + sys_tz.tz_minuteswest * 60 + hpfs_sb(s)->sb_timeshift;
@@ -343,9 +343,7 @@ static inline time64_t local_to_gmt(struct super_block *s, time32_t t) · 2 unmodified lines
343343 static inline time32_t gmt_to_local(struct super_block *s, time64_t t)
344344 {
345345 extern struct timezone sys_tz;
346− t = t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift;
347−
348− return clamp_t(time64_t, t, 0, U32_MAX);
346+ return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift;
349347 }
350348
351349 static inline time32_t local_get_seconds(struct super_block *s)
fs/hpfs/super.c+2−0
@@ -614,6 +614,8 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) · 613 unmodified lines
614614 s->s_magic = HPFS_SUPER_MAGIC;
615615 s->s_op = &hpfs_sops;
616616 s->s_d_op = &hpfs_dentry_operations;
617+ s->s_time_min = local_to_gmt(s, 0);
618+ s->s_time_max = local_to_gmt(s, U32_MAX);
617619
618620 sbi->sb_root = le32_to_cpu(superblock->root);
619621 sbi->sb_fs_size = le32_to_cpu(superblock->n_sectors);
fs/inode.c+32−1
@@ -2166,6 +2166,37 @@ struct timespec64 timespec64_trunc(struct timespec64 t, unsigned gran) · 2165 unmodified lines
21662166 }
21672167 EXPORT_SYMBOL(timespec64_trunc);
21682168
2169+/**
2170+ * timestamp_truncate - Truncate timespec to a granularity
2171+ * @t: Timespec
2172+ * @inode: inode being updated
2173+ *
2174+ * Truncate a timespec to the granularity supported by the fs
2175+ * containing the inode. Always rounds down. gran must
2176+ * not be 0 nor greater than a second (NSEC_PER_SEC, or 10^9 ns).
2177+ */
2178+struct timespec64 timestamp_truncate(struct timespec64 t, struct inode *inode)
2179+{
2180+ struct super_block *sb = inode->i_sb;
2181+ unsigned int gran = sb->s_time_gran;
2182+
2183+ t.tv_sec = clamp(t.tv_sec, sb->s_time_min, sb->s_time_max);
2184+ if (unlikely(t.tv_sec == sb->s_time_max || t.tv_sec == sb->s_time_min))
2185+ t.tv_nsec = 0;
2186+
2187+ /* Avoid division in the common cases 1 ns and 1 s. */
2188+ if (gran == 1)
2189+ ; /* nothing */
2190+ else if (gran == NSEC_PER_SEC)
2191+ t.tv_nsec = 0;
2192+ else if (gran > 1 && gran < NSEC_PER_SEC)
2193+ t.tv_nsec -= t.tv_nsec % gran;
2194+ else
2195+ WARN(1, "invalid file time granularity: %u", gran);
2196+ return t;
2197+}
2198+EXPORT_SYMBOL(timestamp_truncate);
2199+
21692200 /**
21702201 * current_time - Return FS time
21712202 * @inode: inode.
@@ -2187,7 +2218,7 @@ struct timespec64 current_time(struct inode *inode) · 15 unmodified lines
21872218 return now;
21882219 }
21892220
2190− return timespec64_trunc(now, inode->i_sb->s_time_gran);
2221+ return timestamp_truncate(now, inode);
21912222 }
21922223 EXPORT_SYMBOL(current_time);
21932224
fs/isofs/inode.c+7−0
@@ -30,6 +30,9 @@ · 29 unmodified lines
3030 #include "isofs.h"
3131 #include "zisofs.h"
3232
33+/* max tz offset is 13 hours */
34+#define MAX_TZ_OFFSET (52*15*60)
35+
3336 #define BEQUIET
3437
3538 static int isofs_hashi(const struct dentry *parent, struct qstr *qstr);
@@ -801,6 +804,10 @@ root_found: · 765 unmodified lines
801804 */
802805 s->s_maxbytes = 0x80000000000LL;
803806
807+ /* ECMA-119 timestamp from 1900/1/1 with tz offset */
808+ s->s_time_min = mktime64(1900, 1, 1, 0, 0, 0) - MAX_TZ_OFFSET;
809+ s->s_time_max = mktime64(U8_MAX+1900, 12, 31, 23, 59, 59) + MAX_TZ_OFFSET;
810+
804811 /* Set this for reference. Its not currently used except on write
805812 which we don't have .. */
806813
fs/jffs2/fs.c+3−0
@@ -590,6 +590,9 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) · 589 unmodified lines
590590 sb->s_blocksize = PAGE_SIZE;
591591 sb->s_blocksize_bits = PAGE_SHIFT;
592592 sb->s_magic = JFFS2_SUPER_MAGIC;
593+ sb->s_time_min = 0;
594+ sb->s_time_max = U32_MAX;
595+
593596 if (!sb_rdonly(sb))
594597 jffs2_start_garbage_collect_thread(c);
595598 return 0;
fs/jfs/super.c+2−0
@@ -503,6 +503,8 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) · 502 unmodified lines
503503
504504 sb->s_fs_info = sbi;
505505 sb->s_max_links = JFS_LINK_MAX;
506+ sb->s_time_min = 0;
507+ sb->s_time_max = U32_MAX;
506508 sbi->sb = sb;
507509 sbi->uid = INVALID_UID;
508510 sbi->gid = INVALID_GID;
fs/kernfs/inode.c+3−4
@@ -158,12 +158,11 @@ static inline void set_default_inode_attr(struct inode *inode, umode_t mode) · 157 unmodified lines
158158 static inline void set_inode_attr(struct inode *inode,
159159 struct kernfs_iattrs *attrs)
160160 {
161− struct super_block *sb = inode->i_sb;
162161 inode->i_uid = attrs->ia_uid;
163162 inode->i_gid = attrs->ia_gid;
164− inode->i_atime = timespec64_trunc(attrs->ia_atime, sb->s_time_gran);
165− inode->i_mtime = timespec64_trunc(attrs->ia_mtime, sb->s_time_gran);
166− inode->i_ctime = timespec64_trunc(attrs->ia_ctime, sb->s_time_gran);
163+ inode->i_atime = timestamp_truncate(attrs->ia_atime, inode);
164+ inode->i_mtime = timestamp_truncate(attrs->ia_mtime, inode);
165+ inode->i_ctime = timestamp_truncate(attrs->ia_ctime, inode);
167166 }
168167
169168 static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
fs/minix/inode.c+2−0
@@ -277,6 +277,8 @@ static int minix_fill_super(struct super_block *s, void *data, int silent) · 276 unmodified lines
277277
278278 /* set up enough so that it can read an inode */
279279 s->s_op = &minix_sops;
280+ s->s_time_min = 0;
281+ s->s_time_max = U32_MAX;
280282 root_inode = minix_iget(s, MINIX_ROOT_INO);
281283 if (IS_ERR(root_inode)) {
282284 ret = PTR_ERR(root_inode);
fs/namespace.c+32−1
@@ -2466,6 +2466,26 @@ static void set_mount_attributes(struct mount *mnt, unsigned int mnt_flags) · 2465 unmodified lines
24662466 unlock_mount_hash();
24672467 }
24682468
2469+static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *mnt)
2470+{
2471+ struct super_block *sb = mnt->mnt_sb;
2472+
2473+ if (!__mnt_is_readonly(mnt) &&
2474+ (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) {
2475+ char *buf = (char *)__get_free_page(GFP_KERNEL);
2476+ char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM);
2477+ struct tm tm;
2478+
2479+ time64_to_tm(sb->s_time_max, 0, &tm);
2480+
2481+ pr_warn("Mounted %s file system at %s supports timestamps until %04ld (0x%llx)\n",
2482+ sb->s_type->name, mntpath,
2483+ tm.tm_year+1900, (unsigned long long)sb->s_time_max);
2484+
2485+ free_page((unsigned long)buf);
2486+ }
2487+}
2488+
24692489 /*
24702490 * Handle reconfiguration of the mountpoint only without alteration of the
24712491 * superblock it refers to. This is triggered by specifying MS_REMOUNT|MS_BIND
@@ -2491,6 +2511,9 @@ static int do_reconfigure_mnt(struct path *path, unsigned int mnt_flags) · 19 unmodified lines
24912511 if (ret == 0)
24922512 set_mount_attributes(mnt, mnt_flags);
24932513 up_write(&sb->s_umount);
2514+
2515+ mnt_warn_timestamp_expiry(path, &mnt->mnt);
2516+
24942517 return ret;
24952518 }
24962519
@@ -2531,6 +2554,9 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags, · 34 unmodified lines
25312554 }
25322555 up_write(&sb->s_umount);
25332556 }
2557+
2558+ mnt_warn_timestamp_expiry(path, &mnt->mnt);
2559+
25342560 put_fs_context(fc);
25352561 return err;
25362562 }
@@ -2739,8 +2765,13 @@ static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint, · 202 unmodified lines
27392765 return PTR_ERR(mnt);
27402766
27412767 error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags);
2742− if (error < 0)
2768+ if (error < 0) {
27432769 mntput(mnt);
2770+ return error;
2771+ }
2772+
2773+ mnt_warn_timestamp_expiry(mountpoint, mnt);
2774+
27442775 return error;
27452776 }
27462777
fs/nfs/super.c+19−1
@@ -2382,6 +2382,15 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) · 2381 unmodified lines
23822382 sb->s_flags |= SB_POSIXACL;
23832383 sb->s_time_gran = 1;
23842384 sb->s_export_op = &nfs_export_ops;
2385+ } else
2386+ sb->s_time_gran = 1000;
2387+
2388+ if (server->nfs_client->rpc_ops->version != 4) {
2389+ sb->s_time_min = 0;
2390+ sb->s_time_max = U32_MAX;
2391+ } else {
2392+ sb->s_time_min = S64_MIN;
2393+ sb->s_time_max = S64_MAX;
23852394 }
23862395
23872396 nfs_initialise_sb(sb);
@@ -2402,7 +2411,6 @@ static void nfs_clone_super(struct super_block *sb, · 14 unmodified lines
24022411 sb->s_maxbytes = old_sb->s_maxbytes;
24032412 sb->s_xattr = old_sb->s_xattr;
24042413 sb->s_op = old_sb->s_op;
2405− sb->s_time_gran = 1;
24062414 sb->s_export_op = old_sb->s_export_op;
24072415
24082416 if (server->nfs_client->rpc_ops->version != 2) {
@@ -2410,6 +2418,16 @@ static void nfs_clone_super(struct super_block *sb, · 1 unmodified line
24102418 * so ourselves when necessary.
24112419 */
24122420 sb->s_flags |= SB_POSIXACL;
2421+ sb->s_time_gran = 1;
2422+ } else
2423+ sb->s_time_gran = 1000;
2424+
2425+ if (server->nfs_client->rpc_ops->version != 4) {
2426+ sb->s_time_min = 0;
2427+ sb->s_time_max = U32_MAX;
2428+ } else {
2429+ sb->s_time_min = S64_MIN;
2430+ sb->s_time_max = S64_MAX;
24132431 }
24142432
24152433 nfs_initialise_sb(sb);
fs/ntfs/inode.c+12−9
@@ -2899,15 +2899,18 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr) · 2898 unmodified lines
28992899 ia_valid |= ATTR_MTIME | ATTR_CTIME;
29002900 }
29012901 }
2902− if (ia_valid & ATTR_ATIME)
2903− vi->i_atime = timespec64_trunc(attr->ia_atime,
2904− vi->i_sb->s_time_gran);
2905− if (ia_valid & ATTR_MTIME)
2906− vi->i_mtime = timespec64_trunc(attr->ia_mtime,
2907− vi->i_sb->s_time_gran);
2908− if (ia_valid & ATTR_CTIME)
2909− vi->i_ctime = timespec64_trunc(attr->ia_ctime,
2910− vi->i_sb->s_time_gran);
2902+ if (ia_valid & ATTR_ATIME) {
2903+ vi->i_atime = timestamp_truncate(attr->ia_atime,
2904+ vi);
2905+ }
2906+ if (ia_valid & ATTR_MTIME) {
2907+ vi->i_mtime = timestamp_truncate(attr->ia_mtime,
2908+ vi);
2909+ }
2910+ if (ia_valid & ATTR_CTIME) {
2911+ vi->i_ctime = timestamp_truncate(attr->ia_ctime,
2912+ vi);
2913+ }
29112914 mark_inode_dirty(vi);
29122915 out:
29132916 return err;
fs/omfs/inode.c+4−0
@@ -478,6 +478,10 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent) · 477 unmodified lines
478478
479479 sb->s_maxbytes = 0xffffffff;
480480
481+ sb->s_time_gran = NSEC_PER_MSEC;
482+ sb->s_time_min = 0;
483+ sb->s_time_max = U64_MAX / MSEC_PER_SEC;
484+
481485 sb_set_blocksize(sb, 0x200);
482486
483487 bh = sb_bread(sb, 0);
fs/pstore/ram.c+2−0
@@ -144,6 +144,7 @@ static int ramoops_read_kmsg_hdr(char *buffer, struct timespec64 *time, · 143 unmodified lines
144144 if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lld.%lu-%c\n%n",
145145 (time64_t *)&time->tv_sec, &time->tv_nsec, &data_type,
146146 &header_length) == 3) {
147+ time->tv_nsec *= 1000;
147148 if (data_type == 'C')
148149 *compressed = true;
149150 else
@@ -151,6 +152,7 @@ static int ramoops_read_kmsg_hdr(char *buffer, struct timespec64 *time, · 1 unmodified line
151152 } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lld.%lu\n%n",
152153 (time64_t *)&time->tv_sec, &time->tv_nsec,
153154 &header_length) == 2) {
155+ time->tv_nsec *= 1000;
154156 *compressed = false;
155157 } else {
156158 time->tv_sec = 0;
fs/qnx4/inode.c+2−0
@@ -201,6 +201,8 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent) · 200 unmodified lines
201201 s->s_op = &qnx4_sops;
202202 s->s_magic = QNX4_SUPER_MAGIC;
203203 s->s_flags |= SB_RDONLY; /* Yup, read-only yet */
204+ s->s_time_min = 0;
205+ s->s_time_max = U32_MAX;
204206
205207 /* Check the superblock signature. Since the qnx4 code is
206208 dangerous, we should leave as quickly as possible
fs/qnx6/inode.c+2−0
@@ -429,6 +429,8 @@ mmi_success: · 428 unmodified lines
429429 s->s_op = &qnx6_sops;
430430 s->s_magic = QNX6_SUPER_MAGIC;
431431 s->s_flags |= SB_RDONLY; /* Yup, read-only yet */
432+ s->s_time_min = 0;
433+ s->s_time_max = U32_MAX;
432434
433435 /* ease the later tree level calculations */
434436 sbi = QNX6_SB(s);
fs/reiserfs/super.c+3−0
@@ -1976,6 +1976,9 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) · 1975 unmodified lines
19761976 goto error_unlocked;
19771977 }
19781978
1979+ s->s_time_min = 0;
1980+ s->s_time_max = U32_MAX;
1981+
19791982 rs = SB_DISK_SUPER_BLOCK(s);
19801983 /*
19811984 * Let's do basic sanity check to verify that underlying device is not
fs/romfs/super.c+2−0
@@ -478,6 +478,8 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent) · 477 unmodified lines
478478 sb->s_maxbytes = 0xFFFFFFFF;
479479 sb->s_magic = ROMFS_MAGIC;
480480 sb->s_flags |= SB_RDONLY | SB_NOATIME;
481+ sb->s_time_min = 0;
482+ sb->s_time_max = 0;
481483 sb->s_op = &romfs_super_ops;
482484
483485 #ifdef CONFIG_ROMFS_ON_MTD
fs/squashfs/super.c+2−0
@@ -183,6 +183,8 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent) · 182 unmodified lines
183183 (u64) le64_to_cpu(sblk->id_table_start));
184184
185185 sb->s_maxbytes = MAX_LFS_FILESIZE;
186+ sb->s_time_min = 0;
187+ sb->s_time_max = U32_MAX;
186188 sb->s_flags |= SB_RDONLY;
187189 sb->s_op = &squashfs_super_ops;
188190
fs/super.c+2−0
@@ -258,6 +258,8 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags, · 257 unmodified lines
258258 s->s_maxbytes = MAX_NON_LFS;
259259 s->s_op = &default_op;
260260 s->s_time_gran = 1000000000;
261+ s->s_time_min = TIME64_MIN;
262+ s->s_time_max = TIME64_MAX;
261263 s->cleancache_poolid = CLEANCACHE_NO_POOL;
262264
263265 s->s_shrink.seeks = DEFAULT_SEEKS;
fs/sysv/super.c+4−1
@@ -368,7 +368,8 @@ static int sysv_fill_super(struct super_block *sb, void *data, int silent) · 367 unmodified lines
368368 sbi->s_block_base = 0;
369369 mutex_init(&sbi->s_lock);
370370 sb->s_fs_info = sbi;
371−
371+ sb->s_time_min = 0;
372+ sb->s_time_max = U32_MAX;
372373 sb_set_blocksize(sb, BLOCK_SIZE);
373374
374375 for (i = 0; i < ARRAY_SIZE(flavours) && !size; i++) {
@@ -487,6 +488,8 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent) · 112 unmodified lines
487488 sbi->s_type = FSTYPE_V7;
488489 mutex_init(&sbi->s_lock);
489490 sb->s_fs_info = sbi;
491+ sb->s_time_min = 0;
492+ sb->s_time_max = U32_MAX;
490493
491494 sb_set_blocksize(sb, 512);
492495
fs/ubifs/file.c+12−9
@@ -1078,15 +1078,18 @@ static void do_attr_changes(struct inode *inode, const struct iattr *attr) · 1077 unmodified lines
10781078 inode->i_uid = attr->ia_uid;
10791079 if (attr->ia_valid & ATTR_GID)
10801080 inode->i_gid = attr->ia_gid;
1081− if (attr->ia_valid & ATTR_ATIME)
1082− inode->i_atime = timespec64_trunc(attr->ia_atime,
1083− inode->i_sb->s_time_gran);
1084− if (attr->ia_valid & ATTR_MTIME)
1085− inode->i_mtime = timespec64_trunc(attr->ia_mtime,
1086− inode->i_sb->s_time_gran);
1087− if (attr->ia_valid & ATTR_CTIME)
1088− inode->i_ctime = timespec64_trunc(attr->ia_ctime,
1089− inode->i_sb->s_time_gran);
1081+ if (attr->ia_valid & ATTR_ATIME) {
1082+ inode->i_atime = timestamp_truncate(attr->ia_atime,
1083+ inode);
1084+ }
1085+ if (attr->ia_valid & ATTR_MTIME) {
1086+ inode->i_mtime = timestamp_truncate(attr->ia_mtime,
1087+ inode);
1088+ }
1089+ if (attr->ia_valid & ATTR_CTIME) {
1090+ inode->i_ctime = timestamp_truncate(attr->ia_ctime,
1091+ inode);
1092+ }
10901093 if (attr->ia_valid & ATTR_MODE) {
10911094 umode_t mode = attr->ia_mode;
10921095
fs/ufs/super.c+7−0
@@ -843,6 +843,10 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) · 842 unmodified lines
843843
844844 sb->s_maxbytes = MAX_LFS_FILESIZE;
845845
846+ sb->s_time_gran = NSEC_PER_SEC;
847+ sb->s_time_min = S32_MIN;
848+ sb->s_time_max = S32_MAX;
849+
846850 switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) {
847851 case UFS_MOUNT_UFSTYPE_44BSD:
848852 UFSD("ufstype=44bsd\n");
@@ -861,6 +865,9 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) · 12 unmodified lines
861865 uspi->s_fshift = 9;
862866 uspi->s_sbsize = super_block_size = 1536;
863867 uspi->s_sbbase = 0;
868+ sb->s_time_gran = 1;
869+ sb->s_time_min = S64_MIN;
870+ sb->s_time_max = S64_MAX;
864871 flags |= UFS_TYPE_UFS2 | UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
865872 break;
866873
fs/utimes.c+2−4
@@ -36,16 +36,14 @@ static int utimes_common(const struct path *path, struct timespec64 *times) · 35 unmodified lines
3636 if (times[0].tv_nsec == UTIME_OMIT)
3737 newattrs.ia_valid &= ~ATTR_ATIME;
3838 else if (times[0].tv_nsec != UTIME_NOW) {
39− newattrs.ia_atime.tv_sec = times[0].tv_sec;
40− newattrs.ia_atime.tv_nsec = times[0].tv_nsec;
39+ newattrs.ia_atime = timestamp_truncate(times[0], inode);
4140 newattrs.ia_valid |= ATTR_ATIME_SET;
4241 }
4342
4443 if (times[1].tv_nsec == UTIME_OMIT)
4544 newattrs.ia_valid &= ~ATTR_MTIME;
4645 else if (times[1].tv_nsec != UTIME_NOW) {
47− newattrs.ia_mtime.tv_sec = times[1].tv_sec;
48− newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
46+ newattrs.ia_mtime = timestamp_truncate(times[1], inode);
4947 newattrs.ia_valid |= ATTR_MTIME_SET;
5048 }
5149 /*
fs/xfs/xfs_super.c+2−0
@@ -1664,6 +1664,8 @@ xfs_fs_fill_super( · 1663 unmodified lines
16641664 sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
16651665 sb->s_max_links = XFS_MAXLINK;
16661666 sb->s_time_gran = 1;
1667+ sb->s_time_min = S32_MIN;
1668+ sb->s_time_max = S32_MAX;
16671669 sb->s_iflags |= SB_I_CGROUPWB;
16681670
16691671 set_posix_acl_flag(sb);
include/linux/fs.h+5−0
@@ -732,6 +732,8 @@ struct inode { · 731 unmodified lines
732732 void *i_private; /* fs or device private pointer */
733733 } __randomize_layout;
734734
735+struct timespec64 timestamp_truncate(struct timespec64 t, struct inode *inode);
736+
735737 static inline unsigned int i_blocksize(const struct inode *node)
736738 {
737739 return (1 << node->i_blkbits);
@@ -1458,6 +1460,9 @@ struct super_block { · 720 unmodified lines
14581460
14591461 /* Granularity of c/m/atime in ns (cannot be worse than a second) */
14601462 u32 s_time_gran;
1463+ /* Time limits for c/m/atime in seconds */
1464+ time64_t s_time_min;
1465+ time64_t s_time_max;
14611466 #ifdef CONFIG_FSNOTIFY
14621467 __u32 s_fsnotify_mask;
14631468 struct fsnotify_mark_connector __rcu *s_fsnotify_marks;
include/linux/time64.h+2−0
@@ -30,6 +30,8 @@ struct itimerspec64 { · 29 unmodified lines
3030
3131 /* Located here for timespec[64]_valid_strict */
3232 #define TIME64_MAX ((s64)~((u64)1 << 63))
33+#define TIME64_MIN (-TIME64_MAX - 1)
34+
3335 #define KTIME_MAX ((s64)~((u64)1 << 63))
3436 #define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
3537

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t