summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-19 12:42:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-19 12:42:37 -0400
commitcfb82e1df8b7c76991ea12958855897c2fb4debc (patch)
tree7419ef2cef9ec1ea43b78619af6ddd3471152a44
parentb41dae061bbd722b9d7fa828f35d22035b218e18 (diff)
parentcba465b4f9820b0d929822a70341dde14909fc18 (diff)
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
-rw-r--r--fs/9p/vfs_super.c6
-rw-r--r--fs/affs/amigaffs.c2
-rw-r--r--fs/affs/amigaffs.h3
-rw-r--r--fs/affs/inode.c4
-rw-r--r--fs/affs/super.c4
-rw-r--r--fs/attr.c21
-rw-r--r--fs/befs/linuxvfs.c2
-rw-r--r--fs/bfs/inode.c2
-rw-r--r--fs/ceph/super.c2
-rw-r--r--fs/cifs/cifsfs.c22
-rw-r--r--fs/cifs/netmisc.c14
-rw-r--r--fs/coda/inode.c3
-rw-r--r--fs/configfs/inode.c12
-rw-r--r--fs/cramfs/inode.c2
-rw-r--r--fs/efs/super.c2
-rw-r--r--fs/ext2/super.c2
-rw-r--r--fs/ext4/ext4.h8
-rw-r--r--fs/ext4/super.c17
-rw-r--r--fs/f2fs/file.c21
-rw-r--r--fs/fat/inode.c12
-rw-r--r--fs/freevxfs/vxfs_super.c2
-rw-r--r--fs/hpfs/hpfs_fn.h6
-rw-r--r--fs/hpfs/super.c2
-rw-r--r--fs/inode.c33
-rw-r--r--fs/isofs/inode.c7
-rw-r--r--fs/jffs2/fs.c3
-rw-r--r--fs/jfs/super.c2
-rw-r--r--fs/kernfs/inode.c7
-rw-r--r--fs/minix/inode.c2
-rw-r--r--fs/namespace.c33
-rw-r--r--fs/nfs/super.c20
-rw-r--r--fs/ntfs/inode.c21
-rw-r--r--fs/omfs/inode.c4
-rw-r--r--fs/pstore/ram.c2
-rw-r--r--fs/qnx4/inode.c2
-rw-r--r--fs/qnx6/inode.c2
-rw-r--r--fs/reiserfs/super.c3
-rw-r--r--fs/romfs/super.c2
-rw-r--r--fs/squashfs/super.c2
-rw-r--r--fs/super.c2
-rw-r--r--fs/sysv/super.c5
-rw-r--r--fs/ubifs/file.c21
-rw-r--r--fs/ufs/super.c7
-rw-r--r--fs/utimes.c6
-rw-r--r--fs/xfs/xfs_super.c2
-rw-r--r--include/linux/fs.h5
-rw-r--r--include/linux/time64.h2
47 files changed, 294 insertions, 72 deletions
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 08112fbcaece..ca243e658d71 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -69,8 +69,12 @@ v9fs_fill_super(struct super_block *sb, struct v9fs_session_info *v9ses,
69 if (v9fs_proto_dotl(v9ses)) { 69 if (v9fs_proto_dotl(v9ses)) {
70 sb->s_op = &v9fs_super_ops_dotl; 70 sb->s_op = &v9fs_super_ops_dotl;
71 sb->s_xattr = v9fs_xattr_handlers; 71 sb->s_xattr = v9fs_xattr_handlers;
72 } else 72 } else {
73 sb->s_op = &v9fs_super_ops; 73 sb->s_op = &v9fs_super_ops;
74 sb->s_time_max = U32_MAX;
75 }
76
77 sb->s_time_min = 0;
74 78
75 ret = super_setup_bdi(sb); 79 ret = super_setup_bdi(sb);
76 if (ret) 80 if (ret)
diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c
index 14a6c1b90c9f..f708c45d5f66 100644
--- a/fs/affs/amigaffs.c
+++ b/fs/affs/amigaffs.c
@@ -375,7 +375,7 @@ affs_secs_to_datestamp(time64_t secs, struct affs_date *ds)
375 u32 minute; 375 u32 minute;
376 s32 rem; 376 s32 rem;
377 377
378 secs -= sys_tz.tz_minuteswest * 60 + ((8 * 365 + 2) * 24 * 60 * 60); 378 secs -= sys_tz.tz_minuteswest * 60 + AFFS_EPOCH_DELTA;
379 if (secs < 0) 379 if (secs < 0)
380 secs = 0; 380 secs = 0;
381 days = div_s64_rem(secs, 86400, &rem); 381 days = div_s64_rem(secs, 86400, &rem);
diff --git a/fs/affs/amigaffs.h b/fs/affs/amigaffs.h
index f9bef9056659..81fb396d4dfa 100644
--- a/fs/affs/amigaffs.h
+++ b/fs/affs/amigaffs.h
@@ -32,6 +32,9 @@
32 32
33#define AFFS_ROOT_BMAPS 25 33#define AFFS_ROOT_BMAPS 25
34 34
35/* Seconds since Amiga epoch of 1978/01/01 to UNIX */
36#define AFFS_EPOCH_DELTA ((8 * 365 + 2) * 86400LL)
37
35struct affs_date { 38struct affs_date {
36 __be32 days; 39 __be32 days;
37 __be32 mins; 40 __be32 mins;
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index 73598bff8506..a346cf7659f1 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -150,10 +150,10 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino)
150 } 150 }
151 151
152 inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec 152 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 +
154 be32_to_cpu(tail->change.mins) * 60 + 154 be32_to_cpu(tail->change.mins) * 60 +
155 be32_to_cpu(tail->change.ticks) / 50 + 155 be32_to_cpu(tail->change.ticks) / 50 +
156 ((8 * 365 + 2) * 24 * 60 * 60)) + 156 AFFS_EPOCH_DELTA) +
157 sys_tz.tz_minuteswest * 60; 157 sys_tz.tz_minuteswest * 60;
158 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0; 158 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0;
159 affs_brelse(bh); 159 affs_brelse(bh);
diff --git a/fs/affs/super.c b/fs/affs/super.c
index e7d036efbaa1..cc463ae47c12 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -355,6 +355,10 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent)
355 sb->s_op = &affs_sops; 355 sb->s_op = &affs_sops;
356 sb->s_flags |= SB_NODIRATIME; 356 sb->s_flags |= SB_NODIRATIME;
357 357
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
358 sbi = kzalloc(sizeof(struct affs_sb_info), GFP_KERNEL); 362 sbi = kzalloc(sizeof(struct affs_sb_info), GFP_KERNEL);
359 if (!sbi) 363 if (!sbi)
360 return -ENOMEM; 364 return -ENOMEM;
diff --git a/fs/attr.c b/fs/attr.c
index d22e8187477f..df28035aa23e 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -183,15 +183,18 @@ void setattr_copy(struct inode *inode, const struct iattr *attr)
183 inode->i_uid = attr->ia_uid; 183 inode->i_uid = attr->ia_uid;
184 if (ia_valid & ATTR_GID) 184 if (ia_valid & ATTR_GID)
185 inode->i_gid = attr->ia_gid; 185 inode->i_gid = attr->ia_gid;
186 if (ia_valid & ATTR_ATIME) 186 if (ia_valid & ATTR_ATIME) {
187 inode->i_atime = timespec64_trunc(attr->ia_atime, 187 inode->i_atime = timestamp_truncate(attr->ia_atime,
188 inode->i_sb->s_time_gran); 188 inode);
189 if (ia_valid & ATTR_MTIME) 189 }
190 inode->i_mtime = timespec64_trunc(attr->ia_mtime, 190 if (ia_valid & ATTR_MTIME) {
191 inode->i_sb->s_time_gran); 191 inode->i_mtime = timestamp_truncate(attr->ia_mtime,
192 if (ia_valid & ATTR_CTIME) 192 inode);
193 inode->i_ctime = timespec64_trunc(attr->ia_ctime, 193 }
194 inode->i_sb->s_time_gran); 194 if (ia_valid & ATTR_CTIME) {
195 inode->i_ctime = timestamp_truncate(attr->ia_ctime,
196 inode);
197 }
195 if (ia_valid & ATTR_MODE) { 198 if (ia_valid & ATTR_MODE) {
196 umode_t mode = attr->ia_mode; 199 umode_t mode = attr->ia_mode;
197 200
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 462d096ff3e9..64cdf4d8e424 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -893,6 +893,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
893 sb_set_blocksize(sb, (ulong) befs_sb->block_size); 893 sb_set_blocksize(sb, (ulong) befs_sb->block_size);
894 sb->s_op = &befs_sops; 894 sb->s_op = &befs_sops;
895 sb->s_export_op = &befs_export_operations; 895 sb->s_export_op = &befs_export_operations;
896 sb->s_time_min = 0;
897 sb->s_time_max = 0xffffffffffffll;
896 root = befs_iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir))); 898 root = befs_iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir)));
897 if (IS_ERR(root)) { 899 if (IS_ERR(root)) {
898 ret = PTR_ERR(root); 900 ret = PTR_ERR(root);
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index 5e97bed073d7..f8ce1368218b 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -324,6 +324,8 @@ static int bfs_fill_super(struct super_block *s, void *data, int silent)
324 return -ENOMEM; 324 return -ENOMEM;
325 mutex_init(&info->bfs_lock); 325 mutex_init(&info->bfs_lock);
326 s->s_fs_info = info; 326 s->s_fs_info = info;
327 s->s_time_min = 0;
328 s->s_time_max = U32_MAX;
327 329
328 sb_set_blocksize(s, BFS_BSIZE); 330 sb_set_blocksize(s, BFS_BSIZE);
329 331
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index ab4868c7308e..377fafc76f20 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -979,6 +979,8 @@ static int ceph_set_super(struct super_block *s, void *data)
979 s->s_export_op = &ceph_export_ops; 979 s->s_export_op = &ceph_export_ops;
980 980
981 s->s_time_gran = 1; 981 s->s_time_gran = 1;
982 s->s_time_min = 0;
983 s->s_time_max = U32_MAX;
982 984
983 ret = set_anon_super(s, NULL); /* what is that second arg for? */ 985 ret = set_anon_super(s, NULL); /* what is that second arg for? */
984 if (ret != 0) 986 if (ret != 0)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 4e2f74894e9b..e8afff702bb8 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -56,6 +56,15 @@
56#include "dfs_cache.h" 56#include "dfs_cache.h"
57#endif 57#endif
58 58
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
59int cifsFYI = 0; 68int cifsFYI = 0;
60bool traceSMB; 69bool traceSMB;
61bool enable_oplocks = true; 70bool enable_oplocks = true;
@@ -142,6 +151,7 @@ cifs_read_super(struct super_block *sb)
142 struct inode *inode; 151 struct inode *inode;
143 struct cifs_sb_info *cifs_sb; 152 struct cifs_sb_info *cifs_sb;
144 struct cifs_tcon *tcon; 153 struct cifs_tcon *tcon;
154 struct timespec64 ts;
145 int rc = 0; 155 int rc = 0;
146 156
147 cifs_sb = CIFS_SB(sb); 157 cifs_sb = CIFS_SB(sb);
@@ -161,6 +171,18 @@ cifs_read_super(struct super_block *sb)
161 /* BB FIXME fix time_gran to be larger for LANMAN sessions */ 171 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
162 sb->s_time_gran = 100; 172 sb->s_time_gran = 100;
163 173
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
164 sb->s_magic = CIFS_MAGIC_NUMBER; 186 sb->s_magic = CIFS_MAGIC_NUMBER;
165 sb->s_op = &cifs_super_ops; 187 sb->s_op = &cifs_super_ops;
166 sb->s_xattr = cifs_xattr_handlers; 188 sb->s_xattr = cifs_xattr_handlers;
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index ed92958e842d..49c17ee18254 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -949,8 +949,8 @@ static const int total_days_of_prev_months[] = {
949struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) 949struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
950{ 950{
951 struct timespec64 ts; 951 struct timespec64 ts;
952 time64_t sec; 952 time64_t sec, days;
953 int min, days, month, year; 953 int min, day, month, year;
954 u16 date = le16_to_cpu(le_date); 954 u16 date = le16_to_cpu(le_date);
955 u16 time = le16_to_cpu(le_time); 955 u16 time = le16_to_cpu(le_time);
956 SMB_TIME *st = (SMB_TIME *)&time; 956 SMB_TIME *st = (SMB_TIME *)&time;
@@ -966,15 +966,15 @@ struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
966 sec += 60 * 60 * st->Hours; 966 sec += 60 * 60 * st->Hours;
967 if (st->Hours > 24) 967 if (st->Hours > 24)
968 cifs_dbg(VFS, "illegal hours %d\n", st->Hours); 968 cifs_dbg(VFS, "illegal hours %d\n", st->Hours);
969 days = sd->Day; 969 day = sd->Day;
970 month = sd->Month; 970 month = sd->Month;
971 if (days < 1 || days > 31 || month < 1 || month > 12) { 971 if (day < 1 || day > 31 || month < 1 || month > 12) {
972 cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, days); 972 cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, day);
973 days = clamp(days, 1, 31); 973 day = clamp(day, 1, 31);
974 month = clamp(month, 1, 12); 974 month = clamp(month, 1, 12);
975 } 975 }
976 month -= 1; 976 month -= 1;
977 days += total_days_of_prev_months[month]; 977 days = day + total_days_of_prev_months[month];
978 days += 3652; /* account for difference in days between 1980 and 1970 */ 978 days += 3652; /* account for difference in days between 1980 and 1970 */
979 year = sd->Year; 979 year = sd->Year;
980 days += year * 365; 980 days += year * 365;
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index 321f56e487cb..b1c70e2b9b1e 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -188,6 +188,9 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
188 sb->s_magic = CODA_SUPER_MAGIC; 188 sb->s_magic = CODA_SUPER_MAGIC;
189 sb->s_op = &coda_super_operations; 189 sb->s_op = &coda_super_operations;
190 sb->s_d_op = &coda_dentry_operations; 190 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;
191 194
192 error = super_setup_bdi(sb); 195 error = super_setup_bdi(sb);
193 if (error) 196 if (error)
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index ab0284321912..884dcf06cfbe 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -76,14 +76,14 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
76 if (ia_valid & ATTR_GID) 76 if (ia_valid & ATTR_GID)
77 sd_iattr->ia_gid = iattr->ia_gid; 77 sd_iattr->ia_gid = iattr->ia_gid;
78 if (ia_valid & ATTR_ATIME) 78 if (ia_valid & ATTR_ATIME)
79 sd_iattr->ia_atime = timespec64_trunc(iattr->ia_atime, 79 sd_iattr->ia_atime = timestamp_truncate(iattr->ia_atime,
80 inode->i_sb->s_time_gran); 80 inode);
81 if (ia_valid & ATTR_MTIME) 81 if (ia_valid & ATTR_MTIME)
82 sd_iattr->ia_mtime = timespec64_trunc(iattr->ia_mtime, 82 sd_iattr->ia_mtime = timestamp_truncate(iattr->ia_mtime,
83 inode->i_sb->s_time_gran); 83 inode);
84 if (ia_valid & ATTR_CTIME) 84 if (ia_valid & ATTR_CTIME)
85 sd_iattr->ia_ctime = timespec64_trunc(iattr->ia_ctime, 85 sd_iattr->ia_ctime = timestamp_truncate(iattr->ia_ctime,
86 inode->i_sb->s_time_gran); 86 inode);
87 if (ia_valid & ATTR_MODE) { 87 if (ia_valid & ATTR_MODE) {
88 umode_t mode = iattr->ia_mode; 88 umode_t mode = iattr->ia_mode;
89 89
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index 9352487bd0fc..4d1d8b7761ed 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -597,6 +597,8 @@ static int cramfs_finalize_super(struct super_block *sb,
597 597
598 /* Set it all up.. */ 598 /* Set it all up.. */
599 sb->s_flags |= SB_RDONLY; 599 sb->s_flags |= SB_RDONLY;
600 sb->s_time_min = 0;
601 sb->s_time_max = 0;
600 sb->s_op = &cramfs_ops; 602 sb->s_op = &cramfs_ops;
601 root = get_cramfs_inode(sb, cramfs_root, 0); 603 root = get_cramfs_inode(sb, cramfs_root, 0);
602 if (IS_ERR(root)) 604 if (IS_ERR(root))
diff --git a/fs/efs/super.c b/fs/efs/super.c
index 867fc24dee20..4a6ebff2af76 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -257,6 +257,8 @@ static int efs_fill_super(struct super_block *s, void *d, int silent)
257 if (!sb) 257 if (!sb)
258 return -ENOMEM; 258 return -ENOMEM;
259 s->s_fs_info = sb; 259 s->s_fs_info = sb;
260 s->s_time_min = 0;
261 s->s_time_max = U32_MAX;
260 262
261 s->s_magic = EFS_SUPER_MAGIC; 263 s->s_magic = EFS_SUPER_MAGIC;
262 if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) { 264 if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) {
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 44eb6e7eb492..baa36c6fb71e 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -1002,6 +1002,8 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
1002 1002
1003 sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits); 1003 sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits);
1004 sb->s_max_links = EXT2_LINK_MAX; 1004 sb->s_max_links = EXT2_LINK_MAX;
1005 sb->s_time_min = S32_MIN;
1006 sb->s_time_max = S32_MAX;
1005 1007
1006 if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) { 1008 if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) {
1007 sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE; 1009 sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 9c7f4036021b..42c6e4a5e673 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -832,11 +832,13 @@ static inline void ext4_decode_extra_time(struct timespec64 *time,
832 832
833#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ 833#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \
834do { \ 834do { \
835 (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \
836 if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) {\ 835 if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) {\
836 (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \
837 (raw_inode)->xtime ## _extra = \ 837 (raw_inode)->xtime ## _extra = \
838 ext4_encode_extra_time(&(inode)->xtime); \ 838 ext4_encode_extra_time(&(inode)->xtime); \
839 } \ 839 } \
840 else \
841 (raw_inode)->xtime = cpu_to_le32(clamp_t(int32_t, (inode)->xtime.tv_sec, S32_MIN, S32_MAX)); \
840} while (0) 842} while (0)
841 843
842#define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode) \ 844#define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode) \
@@ -1643,6 +1645,10 @@ static inline bool ext4_verity_in_progress(struct inode *inode)
1643 1645
1644#define EXT4_GOOD_OLD_INODE_SIZE 128 1646#define EXT4_GOOD_OLD_INODE_SIZE 128
1645 1647
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
1646/* 1652/*
1647 * Feature set definitions 1653 * Feature set definitions
1648 */ 1654 */
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 27cd622676e7..3db5f17228b7 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -4039,8 +4039,21 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
4039 sbi->s_inode_size); 4039 sbi->s_inode_size);
4040 goto failed_mount; 4040 goto failed_mount;
4041 } 4041 }
4042 if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) 4042 /*
4043 sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); 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;
4044 } 4057 }
4045 4058
4046 sbi->s_desc_size = le16_to_cpu(es->s_desc_size); 4059 sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 39fffc19e00c..56efde9d3659 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -745,15 +745,18 @@ static void __setattr_copy(struct inode *inode, const struct iattr *attr)
745 inode->i_uid = attr->ia_uid; 745 inode->i_uid = attr->ia_uid;
746 if (ia_valid & ATTR_GID) 746 if (ia_valid & ATTR_GID)
747 inode->i_gid = attr->ia_gid; 747 inode->i_gid = attr->ia_gid;
748 if (ia_valid & ATTR_ATIME) 748 if (ia_valid & ATTR_ATIME) {
749 inode->i_atime = timespec64_trunc(attr->ia_atime, 749 inode->i_atime = timestamp_truncate(attr->ia_atime,
750 inode->i_sb->s_time_gran); 750 inode);
751 if (ia_valid & ATTR_MTIME) 751 }
752 inode->i_mtime = timespec64_trunc(attr->ia_mtime, 752 if (ia_valid & ATTR_MTIME) {
753 inode->i_sb->s_time_gran); 753 inode->i_mtime = timestamp_truncate(attr->ia_mtime,
754 if (ia_valid & ATTR_CTIME) 754 inode);
755 inode->i_ctime = timespec64_trunc(attr->ia_ctime, 755 }
756 inode->i_sb->s_time_gran); 756 if (ia_valid & ATTR_CTIME) {
757 inode->i_ctime = timestamp_truncate(attr->ia_ctime,
758 inode);
759 }
757 if (ia_valid & ATTR_MODE) { 760 if (ia_valid & ATTR_MODE) {
758 umode_t mode = attr->ia_mode; 761 umode_t mode = attr->ia_mode;
759 762
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 05689198f5af..5f04c5c810fb 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -31,6 +31,11 @@
31 31
32#define KB_IN_SECTORS 2 32#define KB_IN_SECTORS 2
33 33
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
34/* 39/*
35 * A deserialized copy of the on-disk structure laid out in struct 40 * A deserialized copy of the on-disk structure laid out in struct
36 * fat_boot_sector. 41 * fat_boot_sector.
@@ -1605,6 +1610,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat,
1605 int debug; 1610 int debug;
1606 long error; 1611 long error;
1607 char buf[50]; 1612 char buf[50];
1613 struct timespec64 ts;
1608 1614
1609 /* 1615 /*
1610 * GFP_KERNEL is ok here, because while we do hold the 1616 * 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,
1698 sbi->free_clus_valid = 0; 1704 sbi->free_clus_valid = 0;
1699 sbi->prev_free = FAT_START_ENT; 1705 sbi->prev_free = FAT_START_ENT;
1700 sb->s_maxbytes = 0xffffffff; 1706 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;
1701 1713
1702 if (!sbi->fat_length && bpb.fat32_length) { 1714 if (!sbi->fat_length && bpb.fat32_length) {
1703 struct fat_boot_fsinfo *fsinfo; 1715 struct fat_boot_fsinfo *fsinfo;
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index a89f68c3cbed..578a5062706e 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -229,6 +229,8 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent)
229 229
230 sbp->s_op = &vxfs_super_ops; 230 sbp->s_op = &vxfs_super_ops;
231 sbp->s_fs_info = infp; 231 sbp->s_fs_info = infp;
232 sbp->s_time_min = 0;
233 sbp->s_time_max = U32_MAX;
232 234
233 if (!vxfs_try_sb_magic(sbp, silent, 1, 235 if (!vxfs_try_sb_magic(sbp, silent, 1,
234 (__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) { 236 (__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) {
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index ab2e7cc2ff33..1cca83218fb5 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -334,7 +334,7 @@ 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 time64_t local_to_gmt(struct super_block *s, time32_t t) 337static inline time64_t local_to_gmt(struct super_block *s, time64_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;
@@ -343,9 +343,7 @@ static inline time64_t local_to_gmt(struct super_block *s, time32_t t)
343static inline time32_t gmt_to_local(struct super_block *s, time64_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 t = t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift; 346 return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift;
347
348 return clamp_t(time64_t, t, 0, U32_MAX);
349} 347}
350 348
351static inline time32_t local_get_seconds(struct super_block *s) 349static inline time32_t local_get_seconds(struct super_block *s)
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index 9db6d84f0d62..0a677a9aaf34 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -614,6 +614,8 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
614 s->s_magic = HPFS_SUPER_MAGIC; 614 s->s_magic = HPFS_SUPER_MAGIC;
615 s->s_op = &hpfs_sops; 615 s->s_op = &hpfs_sops;
616 s->s_d_op = &hpfs_dentry_operations; 616 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);
617 619
618 sbi->sb_root = le32_to_cpu(superblock->root); 620 sbi->sb_root = le32_to_cpu(superblock->root);
619 sbi->sb_fs_size = le32_to_cpu(superblock->n_sectors); 621 sbi->sb_fs_size = le32_to_cpu(superblock->n_sectors);
diff --git a/fs/inode.c b/fs/inode.c
index 0f1e3b563c47..64bf28cf05cd 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -2167,6 +2167,37 @@ struct timespec64 timespec64_trunc(struct timespec64 t, unsigned gran)
2167EXPORT_SYMBOL(timespec64_trunc); 2167EXPORT_SYMBOL(timespec64_trunc);
2168 2168
2169/** 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 */
2178struct 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}
2198EXPORT_SYMBOL(timestamp_truncate);
2199
2200/**
2170 * current_time - Return FS time 2201 * current_time - Return FS time
2171 * @inode: inode. 2202 * @inode: inode.
2172 * 2203 *
@@ -2187,7 +2218,7 @@ struct timespec64 current_time(struct inode *inode)
2187 return now; 2218 return now;
2188 } 2219 }
2189 2220
2190 return timespec64_trunc(now, inode->i_sb->s_time_gran); 2221 return timestamp_truncate(now, inode);
2191} 2222}
2192EXPORT_SYMBOL(current_time); 2223EXPORT_SYMBOL(current_time);
2193 2224
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 9e30d8703735..62c0462dc89f 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -30,6 +30,9 @@
30#include "isofs.h" 30#include "isofs.h"
31#include "zisofs.h" 31#include "zisofs.h"
32 32
33/* max tz offset is 13 hours */
34#define MAX_TZ_OFFSET (52*15*60)
35
33#define BEQUIET 36#define BEQUIET
34 37
35static int isofs_hashi(const struct dentry *parent, struct qstr *qstr); 38static int isofs_hashi(const struct dentry *parent, struct qstr *qstr);
@@ -801,6 +804,10 @@ root_found:
801 */ 804 */
802 s->s_maxbytes = 0x80000000000LL; 805 s->s_maxbytes = 0x80000000000LL;
803 806
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
804 /* Set this for reference. Its not currently used except on write 811 /* Set this for reference. Its not currently used except on write
805 which we don't have .. */ 812 which we don't have .. */
806 813
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 8a20ddd25f2d..d0b59d03a7a9 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -590,6 +590,9 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
590 sb->s_blocksize = PAGE_SIZE; 590 sb->s_blocksize = PAGE_SIZE;
591 sb->s_blocksize_bits = PAGE_SHIFT; 591 sb->s_blocksize_bits = PAGE_SHIFT;
592 sb->s_magic = JFFS2_SUPER_MAGIC; 592 sb->s_magic = JFFS2_SUPER_MAGIC;
593 sb->s_time_min = 0;
594 sb->s_time_max = U32_MAX;
595
593 if (!sb_rdonly(sb)) 596 if (!sb_rdonly(sb))
594 jffs2_start_garbage_collect_thread(c); 597 jffs2_start_garbage_collect_thread(c);
595 return 0; 598 return 0;
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index f4e10cb9f734..b2dc4d1f9dcc 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -503,6 +503,8 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
503 503
504 sb->s_fs_info = sbi; 504 sb->s_fs_info = sbi;
505 sb->s_max_links = JFS_LINK_MAX; 505 sb->s_max_links = JFS_LINK_MAX;
506 sb->s_time_min = 0;
507 sb->s_time_max = U32_MAX;
506 sbi->sb = sb; 508 sbi->sb = sb;
507 sbi->uid = INVALID_UID; 509 sbi->uid = INVALID_UID;
508 sbi->gid = INVALID_GID; 510 sbi->gid = INVALID_GID;
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index f3f3984cce80..f3eaa8869f42 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -158,12 +158,11 @@ static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
158static inline void set_inode_attr(struct inode *inode, 158static inline void set_inode_attr(struct inode *inode,
159 struct kernfs_iattrs *attrs) 159 struct kernfs_iattrs *attrs)
160{ 160{
161 struct super_block *sb = inode->i_sb;
162 inode->i_uid = attrs->ia_uid; 161 inode->i_uid = attrs->ia_uid;
163 inode->i_gid = attrs->ia_gid; 162 inode->i_gid = attrs->ia_gid;
164 inode->i_atime = timespec64_trunc(attrs->ia_atime, sb->s_time_gran); 163 inode->i_atime = timestamp_truncate(attrs->ia_atime, inode);
165 inode->i_mtime = timespec64_trunc(attrs->ia_mtime, sb->s_time_gran); 164 inode->i_mtime = timestamp_truncate(attrs->ia_mtime, inode);
166 inode->i_ctime = timespec64_trunc(attrs->ia_ctime, sb->s_time_gran); 165 inode->i_ctime = timestamp_truncate(attrs->ia_ctime, inode);
167} 166}
168 167
169static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) 168static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index f96073f25432..7cb5fd38eb14 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -277,6 +277,8 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
277 277
278 /* set up enough so that it can read an inode */ 278 /* set up enough so that it can read an inode */
279 s->s_op = &minix_sops; 279 s->s_op = &minix_sops;
280 s->s_time_min = 0;
281 s->s_time_max = U32_MAX;
280 root_inode = minix_iget(s, MINIX_ROOT_INO); 282 root_inode = minix_iget(s, MINIX_ROOT_INO);
281 if (IS_ERR(root_inode)) { 283 if (IS_ERR(root_inode)) {
282 ret = PTR_ERR(root_inode); 284 ret = PTR_ERR(root_inode);
diff --git a/fs/namespace.c b/fs/namespace.c
index 227f7b343034..93c043245c46 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2466,6 +2466,26 @@ static void set_mount_attributes(struct mount *mnt, unsigned int mnt_flags)
2466 unlock_mount_hash(); 2466 unlock_mount_hash();
2467} 2467}
2468 2468
2469static 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
2469/* 2489/*
2470 * Handle reconfiguration of the mountpoint only without alteration of the 2490 * Handle reconfiguration of the mountpoint only without alteration of the
2471 * superblock it refers to. This is triggered by specifying MS_REMOUNT|MS_BIND 2491 * 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)
2491 if (ret == 0) 2511 if (ret == 0)
2492 set_mount_attributes(mnt, mnt_flags); 2512 set_mount_attributes(mnt, mnt_flags);
2493 up_write(&sb->s_umount); 2513 up_write(&sb->s_umount);
2514
2515 mnt_warn_timestamp_expiry(path, &mnt->mnt);
2516
2494 return ret; 2517 return ret;
2495} 2518}
2496 2519
@@ -2531,6 +2554,9 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags,
2531 } 2554 }
2532 up_write(&sb->s_umount); 2555 up_write(&sb->s_umount);
2533 } 2556 }
2557
2558 mnt_warn_timestamp_expiry(path, &mnt->mnt);
2559
2534 put_fs_context(fc); 2560 put_fs_context(fc);
2535 return err; 2561 return err;
2536} 2562}
@@ -2739,8 +2765,13 @@ static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint,
2739 return PTR_ERR(mnt); 2765 return PTR_ERR(mnt);
2740 2766
2741 error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags); 2767 error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags);
2742 if (error < 0) 2768 if (error < 0) {
2743 mntput(mnt); 2769 mntput(mnt);
2770 return error;
2771 }
2772
2773 mnt_warn_timestamp_expiry(mountpoint, mnt);
2774
2744 return error; 2775 return error;
2745} 2776}
2746 2777
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 703f595dce90..19a76cfa8b1f 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2382,6 +2382,15 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
2382 sb->s_flags |= SB_POSIXACL; 2382 sb->s_flags |= SB_POSIXACL;
2383 sb->s_time_gran = 1; 2383 sb->s_time_gran = 1;
2384 sb->s_export_op = &nfs_export_ops; 2384 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;
2385 } 2394 }
2386 2395
2387 nfs_initialise_sb(sb); 2396 nfs_initialise_sb(sb);
@@ -2402,7 +2411,6 @@ static void nfs_clone_super(struct super_block *sb,
2402 sb->s_maxbytes = old_sb->s_maxbytes; 2411 sb->s_maxbytes = old_sb->s_maxbytes;
2403 sb->s_xattr = old_sb->s_xattr; 2412 sb->s_xattr = old_sb->s_xattr;
2404 sb->s_op = old_sb->s_op; 2413 sb->s_op = old_sb->s_op;
2405 sb->s_time_gran = 1;
2406 sb->s_export_op = old_sb->s_export_op; 2414 sb->s_export_op = old_sb->s_export_op;
2407 2415
2408 if (server->nfs_client->rpc_ops->version != 2) { 2416 if (server->nfs_client->rpc_ops->version != 2) {
@@ -2410,6 +2418,16 @@ static void nfs_clone_super(struct super_block *sb,
2410 * so ourselves when necessary. 2418 * so ourselves when necessary.
2411 */ 2419 */
2412 sb->s_flags |= SB_POSIXACL; 2420 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;
2413 } 2431 }
2414 2432
2415 nfs_initialise_sb(sb); 2433 nfs_initialise_sb(sb);
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 8baa34baf548..6c7388430ad3 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -2899,15 +2899,18 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
2899 ia_valid |= ATTR_MTIME | ATTR_CTIME; 2899 ia_valid |= ATTR_MTIME | ATTR_CTIME;
2900 } 2900 }
2901 } 2901 }
2902 if (ia_valid & ATTR_ATIME) 2902 if (ia_valid & ATTR_ATIME) {
2903 vi->i_atime = timespec64_trunc(attr->ia_atime, 2903 vi->i_atime = timestamp_truncate(attr->ia_atime,
2904 vi->i_sb->s_time_gran); 2904 vi);
2905 if (ia_valid & ATTR_MTIME) 2905 }
2906 vi->i_mtime = timespec64_trunc(attr->ia_mtime, 2906 if (ia_valid & ATTR_MTIME) {
2907 vi->i_sb->s_time_gran); 2907 vi->i_mtime = timestamp_truncate(attr->ia_mtime,
2908 if (ia_valid & ATTR_CTIME) 2908 vi);
2909 vi->i_ctime = timespec64_trunc(attr->ia_ctime, 2909 }
2910 vi->i_sb->s_time_gran); 2910 if (ia_valid & ATTR_CTIME) {
2911 vi->i_ctime = timestamp_truncate(attr->ia_ctime,
2912 vi);
2913 }
2911 mark_inode_dirty(vi); 2914 mark_inode_dirty(vi);
2912out: 2915out:
2913 return err; 2916 return err;
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c
index 08226a835ec3..b76ec6b88ded 100644
--- a/fs/omfs/inode.c
+++ b/fs/omfs/inode.c
@@ -478,6 +478,10 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
478 478
479 sb->s_maxbytes = 0xffffffff; 479 sb->s_maxbytes = 0xffffffff;
480 480
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
481 sb_set_blocksize(sb, 0x200); 485 sb_set_blocksize(sb, 0x200);
482 486
483 bh = sb_bread(sb, 0); 487 bh = sb_bread(sb, 0);
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 2bb3468fc93a..8caff834f002 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -144,6 +144,7 @@ static int ramoops_read_kmsg_hdr(char *buffer, struct timespec64 *time,
144 if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lld.%lu-%c\n%n", 144 if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lld.%lu-%c\n%n",
145 (time64_t *)&time->tv_sec, &time->tv_nsec, &data_type, 145 (time64_t *)&time->tv_sec, &time->tv_nsec, &data_type,
146 &header_length) == 3) { 146 &header_length) == 3) {
147 time->tv_nsec *= 1000;
147 if (data_type == 'C') 148 if (data_type == 'C')
148 *compressed = true; 149 *compressed = true;
149 else 150 else
@@ -151,6 +152,7 @@ static int ramoops_read_kmsg_hdr(char *buffer, struct timespec64 *time,
151 } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lld.%lu\n%n", 152 } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lld.%lu\n%n",
152 (time64_t *)&time->tv_sec, &time->tv_nsec, 153 (time64_t *)&time->tv_sec, &time->tv_nsec,
153 &header_length) == 2) { 154 &header_length) == 2) {
155 time->tv_nsec *= 1000;
154 *compressed = false; 156 *compressed = false;
155 } else { 157 } else {
156 time->tv_sec = 0; 158 time->tv_sec = 0;
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 922d083bbc7c..e8da1cde87b9 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -201,6 +201,8 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent)
201 s->s_op = &qnx4_sops; 201 s->s_op = &qnx4_sops;
202 s->s_magic = QNX4_SUPER_MAGIC; 202 s->s_magic = QNX4_SUPER_MAGIC;
203 s->s_flags |= SB_RDONLY; /* Yup, read-only yet */ 203 s->s_flags |= SB_RDONLY; /* Yup, read-only yet */
204 s->s_time_min = 0;
205 s->s_time_max = U32_MAX;
204 206
205 /* Check the superblock signature. Since the qnx4 code is 207 /* Check the superblock signature. Since the qnx4 code is
206 dangerous, we should leave as quickly as possible 208 dangerous, we should leave as quickly as possible
diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c
index 0f8b0ff1ba43..345db56c98fd 100644
--- a/fs/qnx6/inode.c
+++ b/fs/qnx6/inode.c
@@ -429,6 +429,8 @@ mmi_success:
429 s->s_op = &qnx6_sops; 429 s->s_op = &qnx6_sops;
430 s->s_magic = QNX6_SUPER_MAGIC; 430 s->s_magic = QNX6_SUPER_MAGIC;
431 s->s_flags |= SB_RDONLY; /* Yup, read-only yet */ 431 s->s_flags |= SB_RDONLY; /* Yup, read-only yet */
432 s->s_time_min = 0;
433 s->s_time_max = U32_MAX;
432 434
433 /* ease the later tree level calculations */ 435 /* ease the later tree level calculations */
434 sbi = QNX6_SB(s); 436 sbi = QNX6_SB(s);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index ab028ea0e561..d69b4ac0ae2f 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1976,6 +1976,9 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
1976 goto error_unlocked; 1976 goto error_unlocked;
1977 } 1977 }
1978 1978
1979 s->s_time_min = 0;
1980 s->s_time_max = U32_MAX;
1981
1979 rs = SB_DISK_SUPER_BLOCK(s); 1982 rs = SB_DISK_SUPER_BLOCK(s);
1980 /* 1983 /*
1981 * Let's do basic sanity check to verify that underlying device is not 1984 * Let's do basic sanity check to verify that underlying device is not
diff --git a/fs/romfs/super.c b/fs/romfs/super.c
index 7d580f7c3f1d..a42c0e3079dc 100644
--- a/fs/romfs/super.c
+++ b/fs/romfs/super.c
@@ -478,6 +478,8 @@ static int romfs_fill_super(struct super_block *sb, void *data, int silent)
478 sb->s_maxbytes = 0xFFFFFFFF; 478 sb->s_maxbytes = 0xFFFFFFFF;
479 sb->s_magic = ROMFS_MAGIC; 479 sb->s_magic = ROMFS_MAGIC;
480 sb->s_flags |= SB_RDONLY | SB_NOATIME; 480 sb->s_flags |= SB_RDONLY | SB_NOATIME;
481 sb->s_time_min = 0;
482 sb->s_time_max = 0;
481 sb->s_op = &romfs_super_ops; 483 sb->s_op = &romfs_super_ops;
482 484
483#ifdef CONFIG_ROMFS_ON_MTD 485#ifdef CONFIG_ROMFS_ON_MTD
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index effa638d6d85..a9e9837617a9 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -183,6 +183,8 @@ static int squashfs_fill_super(struct super_block *sb, void *data, int silent)
183 (u64) le64_to_cpu(sblk->id_table_start)); 183 (u64) le64_to_cpu(sblk->id_table_start));
184 184
185 sb->s_maxbytes = MAX_LFS_FILESIZE; 185 sb->s_maxbytes = MAX_LFS_FILESIZE;
186 sb->s_time_min = 0;
187 sb->s_time_max = U32_MAX;
186 sb->s_flags |= SB_RDONLY; 188 sb->s_flags |= SB_RDONLY;
187 sb->s_op = &squashfs_super_ops; 189 sb->s_op = &squashfs_super_ops;
188 190
diff --git a/fs/super.c b/fs/super.c
index 9459ba75a32e..2d679db9e8c7 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -258,6 +258,8 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags,
258 s->s_maxbytes = MAX_NON_LFS; 258 s->s_maxbytes = MAX_NON_LFS;
259 s->s_op = &default_op; 259 s->s_op = &default_op;
260 s->s_time_gran = 1000000000; 260 s->s_time_gran = 1000000000;
261 s->s_time_min = TIME64_MIN;
262 s->s_time_max = TIME64_MAX;
261 s->cleancache_poolid = CLEANCACHE_NO_POOL; 263 s->cleancache_poolid = CLEANCACHE_NO_POOL;
262 264
263 s->s_shrink.seeks = DEFAULT_SEEKS; 265 s->s_shrink.seeks = DEFAULT_SEEKS;
diff --git a/fs/sysv/super.c b/fs/sysv/super.c
index d788b1daa7eb..cc8e2ed155c8 100644
--- a/fs/sysv/super.c
+++ b/fs/sysv/super.c
@@ -368,7 +368,8 @@ static int sysv_fill_super(struct super_block *sb, void *data, int silent)
368 sbi->s_block_base = 0; 368 sbi->s_block_base = 0;
369 mutex_init(&sbi->s_lock); 369 mutex_init(&sbi->s_lock);
370 sb->s_fs_info = sbi; 370 sb->s_fs_info = sbi;
371 371 sb->s_time_min = 0;
372 sb->s_time_max = U32_MAX;
372 sb_set_blocksize(sb, BLOCK_SIZE); 373 sb_set_blocksize(sb, BLOCK_SIZE);
373 374
374 for (i = 0; i < ARRAY_SIZE(flavours) && !size; i++) { 375 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)
487 sbi->s_type = FSTYPE_V7; 488 sbi->s_type = FSTYPE_V7;
488 mutex_init(&sbi->s_lock); 489 mutex_init(&sbi->s_lock);
489 sb->s_fs_info = sbi; 490 sb->s_fs_info = sbi;
491 sb->s_time_min = 0;
492 sb->s_time_max = U32_MAX;
490 493
491 sb_set_blocksize(sb, 512); 494 sb_set_blocksize(sb, 512);
492 495
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 400970d740bb..cd52585c8f4f 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1078,15 +1078,18 @@ static void do_attr_changes(struct inode *inode, const struct iattr *attr)
1078 inode->i_uid = attr->ia_uid; 1078 inode->i_uid = attr->ia_uid;
1079 if (attr->ia_valid & ATTR_GID) 1079 if (attr->ia_valid & ATTR_GID)
1080 inode->i_gid = attr->ia_gid; 1080 inode->i_gid = attr->ia_gid;
1081 if (attr->ia_valid & ATTR_ATIME) 1081 if (attr->ia_valid & ATTR_ATIME) {
1082 inode->i_atime = timespec64_trunc(attr->ia_atime, 1082 inode->i_atime = timestamp_truncate(attr->ia_atime,
1083 inode->i_sb->s_time_gran); 1083 inode);
1084 if (attr->ia_valid & ATTR_MTIME) 1084 }
1085 inode->i_mtime = timespec64_trunc(attr->ia_mtime, 1085 if (attr->ia_valid & ATTR_MTIME) {
1086 inode->i_sb->s_time_gran); 1086 inode->i_mtime = timestamp_truncate(attr->ia_mtime,
1087 if (attr->ia_valid & ATTR_CTIME) 1087 inode);
1088 inode->i_ctime = timespec64_trunc(attr->ia_ctime, 1088 }
1089 inode->i_sb->s_time_gran); 1089 if (attr->ia_valid & ATTR_CTIME) {
1090 inode->i_ctime = timestamp_truncate(attr->ia_ctime,
1091 inode);
1092 }
1090 if (attr->ia_valid & ATTR_MODE) { 1093 if (attr->ia_valid & ATTR_MODE) {
1091 umode_t mode = attr->ia_mode; 1094 umode_t mode = attr->ia_mode;
1092 1095
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 4ed0dca52ec8..1da0be667409 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -843,6 +843,10 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
843 843
844 sb->s_maxbytes = MAX_LFS_FILESIZE; 844 sb->s_maxbytes = MAX_LFS_FILESIZE;
845 845
846 sb->s_time_gran = NSEC_PER_SEC;
847 sb->s_time_min = S32_MIN;
848 sb->s_time_max = S32_MAX;
849
846 switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) { 850 switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) {
847 case UFS_MOUNT_UFSTYPE_44BSD: 851 case UFS_MOUNT_UFSTYPE_44BSD:
848 UFSD("ufstype=44bsd\n"); 852 UFSD("ufstype=44bsd\n");
@@ -861,6 +865,9 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent)
861 uspi->s_fshift = 9; 865 uspi->s_fshift = 9;
862 uspi->s_sbsize = super_block_size = 1536; 866 uspi->s_sbsize = super_block_size = 1536;
863 uspi->s_sbbase = 0; 867 uspi->s_sbbase = 0;
868 sb->s_time_gran = 1;
869 sb->s_time_min = S64_MIN;
870 sb->s_time_max = S64_MAX;
864 flags |= UFS_TYPE_UFS2 | UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD; 871 flags |= UFS_TYPE_UFS2 | UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD;
865 break; 872 break;
866 873
diff --git a/fs/utimes.c b/fs/utimes.c
index 350c9c16ace1..1ba3f7883870 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -36,16 +36,14 @@ static int utimes_common(const struct path *path, struct timespec64 *times)
36 if (times[0].tv_nsec == UTIME_OMIT) 36 if (times[0].tv_nsec == UTIME_OMIT)
37 newattrs.ia_valid &= ~ATTR_ATIME; 37 newattrs.ia_valid &= ~ATTR_ATIME;
38 else if (times[0].tv_nsec != UTIME_NOW) { 38 else if (times[0].tv_nsec != UTIME_NOW) {
39 newattrs.ia_atime.tv_sec = times[0].tv_sec; 39 newattrs.ia_atime = timestamp_truncate(times[0], inode);
40 newattrs.ia_atime.tv_nsec = times[0].tv_nsec;
41 newattrs.ia_valid |= ATTR_ATIME_SET; 40 newattrs.ia_valid |= ATTR_ATIME_SET;
42 } 41 }
43 42
44 if (times[1].tv_nsec == UTIME_OMIT) 43 if (times[1].tv_nsec == UTIME_OMIT)
45 newattrs.ia_valid &= ~ATTR_MTIME; 44 newattrs.ia_valid &= ~ATTR_MTIME;
46 else if (times[1].tv_nsec != UTIME_NOW) { 45 else if (times[1].tv_nsec != UTIME_NOW) {
47 newattrs.ia_mtime.tv_sec = times[1].tv_sec; 46 newattrs.ia_mtime = timestamp_truncate(times[1], inode);
48 newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
49 newattrs.ia_valid |= ATTR_MTIME_SET; 47 newattrs.ia_valid |= ATTR_MTIME_SET;
50 } 48 }
51 /* 49 /*
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 391b4748cae3..8d1df9f8be07 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1664,6 +1664,8 @@ xfs_fs_fill_super(
1664 sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); 1664 sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
1665 sb->s_max_links = XFS_MAXLINK; 1665 sb->s_max_links = XFS_MAXLINK;
1666 sb->s_time_gran = 1; 1666 sb->s_time_gran = 1;
1667 sb->s_time_min = S32_MIN;
1668 sb->s_time_max = S32_MAX;
1667 sb->s_iflags |= SB_I_CGROUPWB; 1669 sb->s_iflags |= SB_I_CGROUPWB;
1668 1670
1669 set_posix_acl_flag(sb); 1671 set_posix_acl_flag(sb);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ffe35d97afcb..866268c2c6e3 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -732,6 +732,8 @@ struct inode {
732 void *i_private; /* fs or device private pointer */ 732 void *i_private; /* fs or device private pointer */
733} __randomize_layout; 733} __randomize_layout;
734 734
735struct timespec64 timestamp_truncate(struct timespec64 t, struct inode *inode);
736
735static inline unsigned int i_blocksize(const struct inode *node) 737static inline unsigned int i_blocksize(const struct inode *node)
736{ 738{
737 return (1 << node->i_blkbits); 739 return (1 << node->i_blkbits);
@@ -1458,6 +1460,9 @@ struct super_block {
1458 1460
1459 /* Granularity of c/m/atime in ns (cannot be worse than a second) */ 1461 /* Granularity of c/m/atime in ns (cannot be worse than a second) */
1460 u32 s_time_gran; 1462 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;
1461#ifdef CONFIG_FSNOTIFY 1466#ifdef CONFIG_FSNOTIFY
1462 __u32 s_fsnotify_mask; 1467 __u32 s_fsnotify_mask;
1463 struct fsnotify_mark_connector __rcu *s_fsnotify_marks; 1468 struct fsnotify_mark_connector __rcu *s_fsnotify_marks;
diff --git a/include/linux/time64.h b/include/linux/time64.h
index a620ee610b9f..19125489ae94 100644
--- a/include/linux/time64.h
+++ b/include/linux/time64.h
@@ -30,6 +30,8 @@ struct itimerspec64 {
30 30
31/* Located here for timespec[64]_valid_strict */ 31/* Located here for timespec[64]_valid_strict */
32#define TIME64_MAX ((s64)~((u64)1 << 63)) 32#define TIME64_MAX ((s64)~((u64)1 << 63))
33#define TIME64_MIN (-TIME64_MAX - 1)
34
33#define KTIME_MAX ((s64)~((u64)1 << 63)) 35#define KTIME_MAX ((s64)~((u64)1 << 63))
34#define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) 36#define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC)
35 37