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
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 } else72 } 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)
fs/affs/amigaffs.c+1−1
@@ -375,7 +375,7 @@ affs_secs_to_datestamp(time64_t secs, struct affs_date *ds) · 374 unmodified lines
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);
fs/affs/amigaffs.h+3−0
@@ -32,6 +32,9 @@ · 31 unmodified lines
32 32
33#define AFFS_ROOT_BMAPS 2533#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;
fs/affs/inode.c+2−2
@@ -150,10 +150,10 @@ struct inode *affs_iget(struct super_block *sb, unsigned long ino) · 149 unmodified lines
150 }150 }
151 151
152 inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec152 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);
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
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;
fs/attr.c+12−9
@@ -183,15 +183,18 @@ void setattr_copy(struct inode *inode, const struct iattr *attr) · 182 unmodified lines
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
fs/befs/linuxvfs.c+2−0
@@ -893,6 +893,8 @@ befs_fill_super(struct super_block *sb, void *data, int silent) · 892 unmodified lines
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);
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
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
fs/ceph/super.c+2−0
@@ -979,6 +979,8 @@ static int ceph_set_super(struct super_block *s, void *data) · 978 unmodified lines
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)
fs/cifs/cifsfs.c+22−0
@@ -56,6 +56,15 @@ · 55 unmodified lines
56#include "dfs_cache.h"56#include "dfs_cache.h"
57#endif57#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) · 80 unmodified lines
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) · 13 unmodified lines
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;
fs/cifs/netmisc.c+7−7
@@ -949,8 +949,8 @@ static const int total_days_of_prev_months[] = { · 948 unmodified lines
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) · 9 unmodified lines
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;
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
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)
fs/configfs/inode.c+6−6
@@ -76,14 +76,14 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) · 75 unmodified lines
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
fs/cramfs/inode.c+2−0
@@ -597,6 +597,8 @@ static int cramfs_finalize_super(struct super_block *sb, · 596 unmodified lines
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))
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
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)) {
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
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;
fs/ext4/ext4.h+7−1
@@ -832,11 +832,13 @@ static inline void ext4_decode_extra_time(struct timespec64 *time, · 831 unmodified lines
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) · 800 unmodified lines
1643 1645
1644#define EXT4_GOOD_OLD_INODE_SIZE 1281646#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 definitions1653 * Feature set definitions
1648 */1654 */
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
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);
fs/f2fs/file.c+12−9
@@ -745,15 +745,18 @@ static void __setattr_copy(struct inode *inode, const struct iattr *attr) · 744 unmodified lines
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
fs/fat/inode.c+12−0
@@ -31,6 +31,11 @@ · 30 unmodified lines
31 31
32#define KB_IN_SECTORS 232#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 struct40 * 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, · 1568 unmodified lines
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 the1616 * 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
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;
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
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))) {
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
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) · 2 unmodified lines
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)
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
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);
fs/inode.c+32−1
@@ -2166,6 +2166,37 @@ struct timespec64 timespec64_trunc(struct timespec64 t, unsigned gran) · 2165 unmodified lines
2166}2166}
2167EXPORT_SYMBOL(timespec64_trunc);2167EXPORT_SYMBOL(timespec64_trunc);
2168 2168
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
2169/**2200/**
2170 * current_time - Return FS time2201 * current_time - Return FS time
2171 * @inode: inode.2202 * @inode: inode.
@@ -2187,7 +2218,7 @@ struct timespec64 current_time(struct inode *inode) · 15 unmodified lines
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
fs/isofs/inode.c+7−0
@@ -30,6 +30,9 @@ · 29 unmodified lines
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 BEQUIET36#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: · 765 unmodified lines
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 write811 /* 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
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
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;
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
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;
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
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)
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
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);
fs/namespace.c+32−1
@@ -2466,6 +2466,26 @@ static void set_mount_attributes(struct mount *mnt, unsigned int mnt_flags) · 2465 unmodified lines
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 the2490 * Handle reconfiguration of the mountpoint only without alteration of the
2471 * superblock it refers to. This is triggered by specifying MS_REMOUNT|MS_BIND2491 * 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
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, · 34 unmodified lines
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, · 202 unmodified lines
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
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
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, · 14 unmodified lines
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, · 1 unmodified line
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);
fs/ntfs/inode.c+12−9
@@ -2899,15 +2899,18 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr) · 2898 unmodified lines
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;
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
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);
fs/pstore/ram.c+2−0
@@ -144,6 +144,7 @@ static int ramoops_read_kmsg_hdr(char *buffer, struct timespec64 *time, · 143 unmodified lines
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 else150 else
@@ -151,6 +152,7 @@ static int ramoops_read_kmsg_hdr(char *buffer, struct timespec64 *time, · 1 unmodified line
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;
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
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 is207 /* Check the superblock signature. Since the qnx4 code is
206 dangerous, we should leave as quickly as possible208 dangerous, we should leave as quickly as possible
fs/qnx6/inode.c+2−0
@@ -429,6 +429,8 @@ mmi_success: · 428 unmodified lines
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);
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
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 not1984 * 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
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_MTD485#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
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
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
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;
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
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) · 112 unmodified lines
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
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
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
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
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) · 12 unmodified lines
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
fs/utimes.c+2−4
@@ -36,16 +36,14 @@ static int utimes_common(const struct path *path, struct timespec64 *times) · 35 unmodified lines
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 /*
fs/xfs/xfs_super.c+2−0
@@ -1664,6 +1664,8 @@ xfs_fs_fill_super( · 1663 unmodified lines
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);
include/linux/fs.h+5−0
@@ -732,6 +732,8 @@ struct inode { · 731 unmodified lines
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 { · 720 unmodified lines
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_FSNOTIFY1466#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;
include/linux/time64.h+2−0
@@ -30,6 +30,8 @@ struct itimerspec64 { · 29 unmodified lines
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

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