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

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

+294 -72
+5 -1
fs/9p/vfs_super.c
··· 69 69 if (v9fs_proto_dotl(v9ses)) { 70 70 sb->s_op = &v9fs_super_ops_dotl; 71 71 sb->s_xattr = v9fs_xattr_handlers; 72 - } else 72 + } else { 73 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 79 ret = super_setup_bdi(sb); 76 80 if (ret)
+1 -1
fs/affs/amigaffs.c
··· 375 375 u32 minute; 376 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 379 if (secs < 0) 380 380 secs = 0; 381 381 days = div_s64_rem(secs, 86400, &rem);
+3
fs/affs/amigaffs.h
··· 32 32 33 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 + 35 38 struct affs_date { 36 39 __be32 days; 37 40 __be32 mins;
+2 -2
fs/affs/inode.c
··· 150 150 } 151 151 152 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 154 be32_to_cpu(tail->change.mins) * 60 + 155 155 be32_to_cpu(tail->change.ticks) / 50 + 156 - ((8 * 365 + 2) * 24 * 60 * 60)) + 156 + AFFS_EPOCH_DELTA) + 157 157 sys_tz.tz_minuteswest * 60; 158 158 inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_atime.tv_nsec = 0; 159 159 affs_brelse(bh);
+4
fs/affs/super.c
··· 355 355 sb->s_op = &affs_sops; 356 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 362 sbi = kzalloc(sizeof(struct affs_sb_info), GFP_KERNEL); 359 363 if (!sbi) 360 364 return -ENOMEM;
+12 -9
fs/attr.c
··· 183 183 inode->i_uid = attr->ia_uid; 184 184 if (ia_valid & ATTR_GID) 185 185 inode->i_gid = attr->ia_gid; 186 - if (ia_valid & ATTR_ATIME) 187 - inode->i_atime = timespec64_trunc(attr->ia_atime, 188 - inode->i_sb->s_time_gran); 189 - if (ia_valid & ATTR_MTIME) 190 - inode->i_mtime = timespec64_trunc(attr->ia_mtime, 191 - inode->i_sb->s_time_gran); 192 - if (ia_valid & ATTR_CTIME) 193 - inode->i_ctime = timespec64_trunc(attr->ia_ctime, 194 - inode->i_sb->s_time_gran); 186 + if (ia_valid & ATTR_ATIME) { 187 + inode->i_atime = timestamp_truncate(attr->ia_atime, 188 + inode); 189 + } 190 + if (ia_valid & ATTR_MTIME) { 191 + inode->i_mtime = timestamp_truncate(attr->ia_mtime, 192 + inode); 193 + } 194 + if (ia_valid & ATTR_CTIME) { 195 + inode->i_ctime = timestamp_truncate(attr->ia_ctime, 196 + inode); 197 + } 195 198 if (ia_valid & ATTR_MODE) { 196 199 umode_t mode = attr->ia_mode; 197 200
+2
fs/befs/linuxvfs.c
··· 893 893 sb_set_blocksize(sb, (ulong) befs_sb->block_size); 894 894 sb->s_op = &befs_sops; 895 895 sb->s_export_op = &befs_export_operations; 896 + sb->s_time_min = 0; 897 + sb->s_time_max = 0xffffffffffffll; 896 898 root = befs_iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir))); 897 899 if (IS_ERR(root)) { 898 900 ret = PTR_ERR(root);
+2
fs/bfs/inode.c
··· 324 324 return -ENOMEM; 325 325 mutex_init(&info->bfs_lock); 326 326 s->s_fs_info = info; 327 + s->s_time_min = 0; 328 + s->s_time_max = U32_MAX; 327 329 328 330 sb_set_blocksize(s, BFS_BSIZE); 329 331
+2
fs/ceph/super.c
··· 979 979 s->s_export_op = &ceph_export_ops; 980 980 981 981 s->s_time_gran = 1; 982 + s->s_time_min = 0; 983 + s->s_time_max = U32_MAX; 982 984 983 985 ret = set_anon_super(s, NULL); /* what is that second arg for? */ 984 986 if (ret != 0)
+22
fs/cifs/cifsfs.c
··· 56 56 #include "dfs_cache.h" 57 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 + 59 68 int cifsFYI = 0; 60 69 bool traceSMB; 61 70 bool enable_oplocks = true; ··· 151 142 struct inode *inode; 152 143 struct cifs_sb_info *cifs_sb; 153 144 struct cifs_tcon *tcon; 145 + struct timespec64 ts; 154 146 int rc = 0; 155 147 156 148 cifs_sb = CIFS_SB(sb); ··· 170 160 171 161 /* BB FIXME fix time_gran to be larger for LANMAN sessions */ 172 162 sb->s_time_gran = 100; 163 + 164 + if (tcon->unix_ext) { 165 + ts = cifs_NTtimeToUnix(0); 166 + sb->s_time_min = ts.tv_sec; 167 + ts = cifs_NTtimeToUnix(cpu_to_le64(S64_MAX)); 168 + sb->s_time_max = ts.tv_sec; 169 + } else { 170 + ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MIN), 0, 0); 171 + sb->s_time_min = ts.tv_sec; 172 + ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MAX), cpu_to_le16(SMB_TIME_MAX), 0); 173 + sb->s_time_max = ts.tv_sec; 174 + } 173 175 174 176 sb->s_magic = CIFS_MAGIC_NUMBER; 175 177 sb->s_op = &cifs_super_ops;
+7 -7
fs/cifs/netmisc.c
··· 949 949 struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) 950 950 { 951 951 struct timespec64 ts; 952 - time64_t sec; 953 - int min, days, month, year; 952 + time64_t sec, days; 953 + int min, day, month, year; 954 954 u16 date = le16_to_cpu(le_date); 955 955 u16 time = le16_to_cpu(le_time); 956 956 SMB_TIME *st = (SMB_TIME *)&time; ··· 966 966 sec += 60 * 60 * st->Hours; 967 967 if (st->Hours > 24) 968 968 cifs_dbg(VFS, "illegal hours %d\n", st->Hours); 969 - days = sd->Day; 969 + day = sd->Day; 970 970 month = sd->Month; 971 - if (days < 1 || days > 31 || month < 1 || month > 12) { 972 - cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, days); 973 - days = clamp(days, 1, 31); 971 + if (day < 1 || day > 31 || month < 1 || month > 12) { 972 + cifs_dbg(VFS, "illegal date, month %d day: %d\n", month, day); 973 + day = clamp(day, 1, 31); 974 974 month = clamp(month, 1, 12); 975 975 } 976 976 month -= 1; 977 - days += total_days_of_prev_months[month]; 977 + days = day + total_days_of_prev_months[month]; 978 978 days += 3652; /* account for difference in days between 1980 and 1970 */ 979 979 year = sd->Year; 980 980 days += year * 365;
+3
fs/coda/inode.c
··· 188 188 sb->s_magic = CODA_SUPER_MAGIC; 189 189 sb->s_op = &coda_super_operations; 190 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 195 error = super_setup_bdi(sb); 193 196 if (error)
+6 -6
fs/configfs/inode.c
··· 76 76 if (ia_valid & ATTR_GID) 77 77 sd_iattr->ia_gid = iattr->ia_gid; 78 78 if (ia_valid & ATTR_ATIME) 79 - sd_iattr->ia_atime = timespec64_trunc(iattr->ia_atime, 80 - inode->i_sb->s_time_gran); 79 + sd_iattr->ia_atime = timestamp_truncate(iattr->ia_atime, 80 + inode); 81 81 if (ia_valid & ATTR_MTIME) 82 - sd_iattr->ia_mtime = timespec64_trunc(iattr->ia_mtime, 83 - inode->i_sb->s_time_gran); 82 + sd_iattr->ia_mtime = timestamp_truncate(iattr->ia_mtime, 83 + inode); 84 84 if (ia_valid & ATTR_CTIME) 85 - sd_iattr->ia_ctime = timespec64_trunc(iattr->ia_ctime, 86 - inode->i_sb->s_time_gran); 85 + sd_iattr->ia_ctime = timestamp_truncate(iattr->ia_ctime, 86 + inode); 87 87 if (ia_valid & ATTR_MODE) { 88 88 umode_t mode = iattr->ia_mode; 89 89
+2
fs/cramfs/inode.c
··· 597 597 598 598 /* Set it all up.. */ 599 599 sb->s_flags |= SB_RDONLY; 600 + sb->s_time_min = 0; 601 + sb->s_time_max = 0; 600 602 sb->s_op = &cramfs_ops; 601 603 root = get_cramfs_inode(sb, cramfs_root, 0); 602 604 if (IS_ERR(root))
+2
fs/efs/super.c
··· 257 257 if (!sb) 258 258 return -ENOMEM; 259 259 s->s_fs_info = sb; 260 + s->s_time_min = 0; 261 + s->s_time_max = U32_MAX; 260 262 261 263 s->s_magic = EFS_SUPER_MAGIC; 262 264 if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) {
+2
fs/ext2/super.c
··· 1002 1002 1003 1003 sb->s_maxbytes = ext2_max_size(sb->s_blocksize_bits); 1004 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 1008 if (le32_to_cpu(es->s_rev_level) == EXT2_GOOD_OLD_REV) { 1007 1009 sbi->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
+7 -1
fs/ext4/ext4.h
··· 832 832 833 833 #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \ 834 834 do { \ 835 - (raw_inode)->xtime = cpu_to_le32((inode)->xtime.tv_sec); \ 836 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 837 (raw_inode)->xtime ## _extra = \ 838 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 842 } while (0) 841 843 842 844 #define EXT4_EINODE_SET_XTIME(xtime, einode, raw_inode) \ ··· 1644 1642 #define EXT4_MAX_SUPP_REV EXT4_DYNAMIC_REV 1645 1643 1646 1644 #define EXT4_GOOD_OLD_INODE_SIZE 128 1645 + 1646 + #define EXT4_EXTRA_TIMESTAMP_MAX (((s64)1 << 34) - 1 + S32_MIN) 1647 + #define EXT4_NON_EXTRA_TIMESTAMP_MAX S32_MAX 1648 + #define EXT4_TIMESTAMP_MIN S32_MIN 1647 1649 1648 1650 /* 1649 1651 * Feature set definitions
+15 -2
fs/ext4/super.c
··· 4039 4039 sbi->s_inode_size); 4040 4040 goto failed_mount; 4041 4041 } 4042 - if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) 4043 - sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); 4042 + /* 4043 + * i_atime_extra is the last extra field available for [acm]times in 4044 + * struct ext4_inode. Checking for that field should suffice to ensure 4045 + * we have extra space for all three. 4046 + */ 4047 + if (sbi->s_inode_size >= offsetof(struct ext4_inode, i_atime_extra) + 4048 + sizeof(((struct ext4_inode *)0)->i_atime_extra)) { 4049 + sb->s_time_gran = 1; 4050 + sb->s_time_max = EXT4_EXTRA_TIMESTAMP_MAX; 4051 + } else { 4052 + sb->s_time_gran = NSEC_PER_SEC; 4053 + sb->s_time_max = EXT4_NON_EXTRA_TIMESTAMP_MAX; 4054 + } 4055 + 4056 + sb->s_time_min = EXT4_TIMESTAMP_MIN; 4044 4057 } 4045 4058 4046 4059 sbi->s_desc_size = le16_to_cpu(es->s_desc_size);
+12 -9
fs/f2fs/file.c
··· 745 745 inode->i_uid = attr->ia_uid; 746 746 if (ia_valid & ATTR_GID) 747 747 inode->i_gid = attr->ia_gid; 748 - if (ia_valid & ATTR_ATIME) 749 - inode->i_atime = timespec64_trunc(attr->ia_atime, 750 - inode->i_sb->s_time_gran); 751 - if (ia_valid & ATTR_MTIME) 752 - inode->i_mtime = timespec64_trunc(attr->ia_mtime, 753 - inode->i_sb->s_time_gran); 754 - if (ia_valid & ATTR_CTIME) 755 - inode->i_ctime = timespec64_trunc(attr->ia_ctime, 756 - inode->i_sb->s_time_gran); 748 + if (ia_valid & ATTR_ATIME) { 749 + inode->i_atime = timestamp_truncate(attr->ia_atime, 750 + inode); 751 + } 752 + if (ia_valid & ATTR_MTIME) { 753 + inode->i_mtime = timestamp_truncate(attr->ia_mtime, 754 + inode); 755 + } 756 + if (ia_valid & ATTR_CTIME) { 757 + inode->i_ctime = timestamp_truncate(attr->ia_ctime, 758 + inode); 759 + } 757 760 if (ia_valid & ATTR_MODE) { 758 761 umode_t mode = attr->ia_mode; 759 762
+12
fs/fat/inode.c
··· 31 31 32 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 40 * A deserialized copy of the on-disk structure laid out in struct 36 41 * fat_boot_sector. ··· 1610 1605 int debug; 1611 1606 long error; 1612 1607 char buf[50]; 1608 + struct timespec64 ts; 1613 1609 1614 1610 /* 1615 1611 * GFP_KERNEL is ok here, because while we do hold the ··· 1704 1698 sbi->free_clus_valid = 0; 1705 1699 sbi->prev_free = FAT_START_ENT; 1706 1700 sb->s_maxbytes = 0xffffffff; 1701 + fat_time_fat2unix(sbi, &ts, 0, cpu_to_le16(FAT_DATE_MIN), 0); 1702 + sb->s_time_min = ts.tv_sec; 1703 + 1704 + fat_time_fat2unix(sbi, &ts, cpu_to_le16(FAT_TIME_MAX), 1705 + cpu_to_le16(FAT_DATE_MAX), 0); 1706 + sb->s_time_max = ts.tv_sec; 1707 1707 1708 1708 if (!sbi->fat_length && bpb.fat32_length) { 1709 1709 struct fat_boot_fsinfo *fsinfo;
+2
fs/freevxfs/vxfs_super.c
··· 229 229 230 230 sbp->s_op = &vxfs_super_ops; 231 231 sbp->s_fs_info = infp; 232 + sbp->s_time_min = 0; 233 + sbp->s_time_max = U32_MAX; 232 234 233 235 if (!vxfs_try_sb_magic(sbp, silent, 1, 234 236 (__force __fs32)cpu_to_le32(VXFS_SUPER_MAGIC))) {
+2 -4
fs/hpfs/hpfs_fn.h
··· 334 334 * local time (HPFS) to GMT (Unix) 335 335 */ 336 336 337 - static inline time64_t local_to_gmt(struct super_block *s, time32_t t) 337 + static inline time64_t local_to_gmt(struct super_block *s, time64_t t) 338 338 { 339 339 extern struct timezone sys_tz; 340 340 return t + sys_tz.tz_minuteswest * 60 + hpfs_sb(s)->sb_timeshift; ··· 343 343 static inline time32_t gmt_to_local(struct super_block *s, time64_t t) 344 344 { 345 345 extern struct timezone sys_tz; 346 - t = t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift; 347 - 348 - return clamp_t(time64_t, t, 0, U32_MAX); 346 + return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift; 349 347 } 350 348 351 349 static inline time32_t local_get_seconds(struct super_block *s)
+2
fs/hpfs/super.c
··· 614 614 s->s_magic = HPFS_SUPER_MAGIC; 615 615 s->s_op = &hpfs_sops; 616 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 620 sbi->sb_root = le32_to_cpu(superblock->root); 619 621 sbi->sb_fs_size = le32_to_cpu(superblock->n_sectors);
+32 -1
fs/inode.c
··· 2167 2167 EXPORT_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 + */ 2178 + struct timespec64 timestamp_truncate(struct timespec64 t, struct inode *inode) 2179 + { 2180 + struct super_block *sb = inode->i_sb; 2181 + unsigned int gran = sb->s_time_gran; 2182 + 2183 + t.tv_sec = clamp(t.tv_sec, sb->s_time_min, sb->s_time_max); 2184 + if (unlikely(t.tv_sec == sb->s_time_max || t.tv_sec == sb->s_time_min)) 2185 + t.tv_nsec = 0; 2186 + 2187 + /* Avoid division in the common cases 1 ns and 1 s. */ 2188 + if (gran == 1) 2189 + ; /* nothing */ 2190 + else if (gran == NSEC_PER_SEC) 2191 + t.tv_nsec = 0; 2192 + else if (gran > 1 && gran < NSEC_PER_SEC) 2193 + t.tv_nsec -= t.tv_nsec % gran; 2194 + else 2195 + WARN(1, "invalid file time granularity: %u", gran); 2196 + return t; 2197 + } 2198 + EXPORT_SYMBOL(timestamp_truncate); 2199 + 2200 + /** 2170 2201 * current_time - Return FS time 2171 2202 * @inode: inode. 2172 2203 * ··· 2218 2187 return now; 2219 2188 } 2220 2189 2221 - return timespec64_trunc(now, inode->i_sb->s_time_gran); 2190 + return timestamp_truncate(now, inode); 2222 2191 } 2223 2192 EXPORT_SYMBOL(current_time); 2224 2193
+7
fs/isofs/inode.c
··· 30 30 #include "isofs.h" 31 31 #include "zisofs.h" 32 32 33 + /* max tz offset is 13 hours */ 34 + #define MAX_TZ_OFFSET (52*15*60) 35 + 33 36 #define BEQUIET 34 37 35 38 static int isofs_hashi(const struct dentry *parent, struct qstr *qstr); ··· 803 800 * size of a file system, which is 8 TB. 804 801 */ 805 802 s->s_maxbytes = 0x80000000000LL; 803 + 804 + /* ECMA-119 timestamp from 1900/1/1 with tz offset */ 805 + s->s_time_min = mktime64(1900, 1, 1, 0, 0, 0) - MAX_TZ_OFFSET; 806 + s->s_time_max = mktime64(U8_MAX+1900, 12, 31, 23, 59, 59) + MAX_TZ_OFFSET; 806 807 807 808 /* Set this for reference. Its not currently used except on write 808 809 which we don't have .. */
+3
fs/jffs2/fs.c
··· 590 590 sb->s_blocksize = PAGE_SIZE; 591 591 sb->s_blocksize_bits = PAGE_SHIFT; 592 592 sb->s_magic = JFFS2_SUPER_MAGIC; 593 + sb->s_time_min = 0; 594 + sb->s_time_max = U32_MAX; 595 + 593 596 if (!sb_rdonly(sb)) 594 597 jffs2_start_garbage_collect_thread(c); 595 598 return 0;
+2
fs/jfs/super.c
··· 503 503 504 504 sb->s_fs_info = sbi; 505 505 sb->s_max_links = JFS_LINK_MAX; 506 + sb->s_time_min = 0; 507 + sb->s_time_max = U32_MAX; 506 508 sbi->sb = sb; 507 509 sbi->uid = INVALID_UID; 508 510 sbi->gid = INVALID_GID;
+3 -4
fs/kernfs/inode.c
··· 158 158 static inline void set_inode_attr(struct inode *inode, 159 159 struct kernfs_iattrs *attrs) 160 160 { 161 - struct super_block *sb = inode->i_sb; 162 161 inode->i_uid = attrs->ia_uid; 163 162 inode->i_gid = attrs->ia_gid; 164 - inode->i_atime = timespec64_trunc(attrs->ia_atime, sb->s_time_gran); 165 - inode->i_mtime = timespec64_trunc(attrs->ia_mtime, sb->s_time_gran); 166 - inode->i_ctime = timespec64_trunc(attrs->ia_ctime, sb->s_time_gran); 163 + inode->i_atime = timestamp_truncate(attrs->ia_atime, inode); 164 + inode->i_mtime = timestamp_truncate(attrs->ia_mtime, inode); 165 + inode->i_ctime = timestamp_truncate(attrs->ia_ctime, inode); 167 166 } 168 167 169 168 static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
+2
fs/minix/inode.c
··· 277 277 278 278 /* set up enough so that it can read an inode */ 279 279 s->s_op = &minix_sops; 280 + s->s_time_min = 0; 281 + s->s_time_max = U32_MAX; 280 282 root_inode = minix_iget(s, MINIX_ROOT_INO); 281 283 if (IS_ERR(root_inode)) { 282 284 ret = PTR_ERR(root_inode);
+32 -1
fs/namespace.c
··· 2466 2466 unlock_mount_hash(); 2467 2467 } 2468 2468 2469 + static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *mnt) 2470 + { 2471 + struct super_block *sb = mnt->mnt_sb; 2472 + 2473 + if (!__mnt_is_readonly(mnt) && 2474 + (ktime_get_real_seconds() + TIME_UPTIME_SEC_MAX > sb->s_time_max)) { 2475 + char *buf = (char *)__get_free_page(GFP_KERNEL); 2476 + char *mntpath = buf ? d_path(mountpoint, buf, PAGE_SIZE) : ERR_PTR(-ENOMEM); 2477 + struct tm tm; 2478 + 2479 + time64_to_tm(sb->s_time_max, 0, &tm); 2480 + 2481 + pr_warn("Mounted %s file system at %s supports timestamps until %04ld (0x%llx)\n", 2482 + sb->s_type->name, mntpath, 2483 + tm.tm_year+1900, (unsigned long long)sb->s_time_max); 2484 + 2485 + free_page((unsigned long)buf); 2486 + } 2487 + } 2488 + 2469 2489 /* 2470 2490 * Handle reconfiguration of the mountpoint only without alteration of the 2471 2491 * superblock it refers to. This is triggered by specifying MS_REMOUNT|MS_BIND ··· 2511 2491 if (ret == 0) 2512 2492 set_mount_attributes(mnt, mnt_flags); 2513 2493 up_write(&sb->s_umount); 2494 + 2495 + mnt_warn_timestamp_expiry(path, &mnt->mnt); 2496 + 2514 2497 return ret; 2515 2498 } 2516 2499 ··· 2554 2531 } 2555 2532 up_write(&sb->s_umount); 2556 2533 } 2534 + 2535 + mnt_warn_timestamp_expiry(path, &mnt->mnt); 2536 + 2557 2537 put_fs_context(fc); 2558 2538 return err; 2559 2539 } ··· 2765 2739 return PTR_ERR(mnt); 2766 2740 2767 2741 error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags); 2768 - if (error < 0) 2742 + if (error < 0) { 2769 2743 mntput(mnt); 2744 + return error; 2745 + } 2746 + 2747 + mnt_warn_timestamp_expiry(mountpoint, mnt); 2748 + 2770 2749 return error; 2771 2750 } 2772 2751
+19 -1
fs/nfs/super.c
··· 2382 2382 sb->s_flags |= SB_POSIXACL; 2383 2383 sb->s_time_gran = 1; 2384 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 2396 nfs_initialise_sb(sb); ··· 2411 2402 sb->s_maxbytes = old_sb->s_maxbytes; 2412 2403 sb->s_xattr = old_sb->s_xattr; 2413 2404 sb->s_op = old_sb->s_op; 2414 - sb->s_time_gran = 1; 2415 2405 sb->s_export_op = old_sb->s_export_op; 2416 2406 2417 2407 if (server->nfs_client->rpc_ops->version != 2) { ··· 2418 2410 * so ourselves when necessary. 2419 2411 */ 2420 2412 sb->s_flags |= SB_POSIXACL; 2413 + sb->s_time_gran = 1; 2414 + } else 2415 + sb->s_time_gran = 1000; 2416 + 2417 + if (server->nfs_client->rpc_ops->version != 4) { 2418 + sb->s_time_min = 0; 2419 + sb->s_time_max = U32_MAX; 2420 + } else { 2421 + sb->s_time_min = S64_MIN; 2422 + sb->s_time_max = S64_MAX; 2421 2423 } 2422 2424 2423 2425 nfs_initialise_sb(sb);
+12 -9
fs/ntfs/inode.c
··· 2899 2899 ia_valid |= ATTR_MTIME | ATTR_CTIME; 2900 2900 } 2901 2901 } 2902 - if (ia_valid & ATTR_ATIME) 2903 - vi->i_atime = timespec64_trunc(attr->ia_atime, 2904 - vi->i_sb->s_time_gran); 2905 - if (ia_valid & ATTR_MTIME) 2906 - vi->i_mtime = timespec64_trunc(attr->ia_mtime, 2907 - vi->i_sb->s_time_gran); 2908 - if (ia_valid & ATTR_CTIME) 2909 - vi->i_ctime = timespec64_trunc(attr->ia_ctime, 2910 - vi->i_sb->s_time_gran); 2902 + if (ia_valid & ATTR_ATIME) { 2903 + vi->i_atime = timestamp_truncate(attr->ia_atime, 2904 + vi); 2905 + } 2906 + if (ia_valid & ATTR_MTIME) { 2907 + vi->i_mtime = timestamp_truncate(attr->ia_mtime, 2908 + vi); 2909 + } 2910 + if (ia_valid & ATTR_CTIME) { 2911 + vi->i_ctime = timestamp_truncate(attr->ia_ctime, 2912 + vi); 2913 + } 2911 2914 mark_inode_dirty(vi); 2912 2915 out: 2913 2916 return err;
+4
fs/omfs/inode.c
··· 478 478 479 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 485 sb_set_blocksize(sb, 0x200); 482 486 483 487 bh = sb_bread(sb, 0);
+2
fs/pstore/ram.c
··· 144 144 if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lld.%lu-%c\n%n", 145 145 (time64_t *)&time->tv_sec, &time->tv_nsec, &data_type, 146 146 &header_length) == 3) { 147 + time->tv_nsec *= 1000; 147 148 if (data_type == 'C') 148 149 *compressed = true; 149 150 else ··· 152 151 } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lld.%lu\n%n", 153 152 (time64_t *)&time->tv_sec, &time->tv_nsec, 154 153 &header_length) == 2) { 154 + time->tv_nsec *= 1000; 155 155 *compressed = false; 156 156 } else { 157 157 time->tv_sec = 0;
+2
fs/qnx4/inode.c
··· 201 201 s->s_op = &qnx4_sops; 202 202 s->s_magic = QNX4_SUPER_MAGIC; 203 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 207 /* Check the superblock signature. Since the qnx4 code is 206 208 dangerous, we should leave as quickly as possible
+2
fs/qnx6/inode.c
··· 429 429 s->s_op = &qnx6_sops; 430 430 s->s_magic = QNX6_SUPER_MAGIC; 431 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 435 /* ease the later tree level calculations */ 434 436 sbi = QNX6_SB(s);
+3
fs/reiserfs/super.c
··· 1976 1976 goto error_unlocked; 1977 1977 } 1978 1978 1979 + s->s_time_min = 0; 1980 + s->s_time_max = U32_MAX; 1981 + 1979 1982 rs = SB_DISK_SUPER_BLOCK(s); 1980 1983 /* 1981 1984 * Let's do basic sanity check to verify that underlying device is not
+2
fs/romfs/super.c
··· 478 478 sb->s_maxbytes = 0xFFFFFFFF; 479 479 sb->s_magic = ROMFS_MAGIC; 480 480 sb->s_flags |= SB_RDONLY | SB_NOATIME; 481 + sb->s_time_min = 0; 482 + sb->s_time_max = 0; 481 483 sb->s_op = &romfs_super_ops; 482 484 483 485 #ifdef CONFIG_ROMFS_ON_MTD
+2
fs/squashfs/super.c
··· 183 183 (u64) le64_to_cpu(sblk->id_table_start)); 184 184 185 185 sb->s_maxbytes = MAX_LFS_FILESIZE; 186 + sb->s_time_min = 0; 187 + sb->s_time_max = U32_MAX; 186 188 sb->s_flags |= SB_RDONLY; 187 189 sb->s_op = &squashfs_super_ops; 188 190
+2
fs/super.c
··· 258 258 s->s_maxbytes = MAX_NON_LFS; 259 259 s->s_op = &default_op; 260 260 s->s_time_gran = 1000000000; 261 + s->s_time_min = TIME64_MIN; 262 + s->s_time_max = TIME64_MAX; 261 263 s->cleancache_poolid = CLEANCACHE_NO_POOL; 262 264 263 265 s->s_shrink.seeks = DEFAULT_SEEKS;
+4 -1
fs/sysv/super.c
··· 368 368 sbi->s_block_base = 0; 369 369 mutex_init(&sbi->s_lock); 370 370 sb->s_fs_info = sbi; 371 - 371 + sb->s_time_min = 0; 372 + sb->s_time_max = U32_MAX; 372 373 sb_set_blocksize(sb, BLOCK_SIZE); 373 374 374 375 for (i = 0; i < ARRAY_SIZE(flavours) && !size; i++) { ··· 488 487 sbi->s_type = FSTYPE_V7; 489 488 mutex_init(&sbi->s_lock); 490 489 sb->s_fs_info = sbi; 490 + sb->s_time_min = 0; 491 + sb->s_time_max = U32_MAX; 491 492 492 493 sb_set_blocksize(sb, 512); 493 494
+12 -9
fs/ubifs/file.c
··· 1078 1078 inode->i_uid = attr->ia_uid; 1079 1079 if (attr->ia_valid & ATTR_GID) 1080 1080 inode->i_gid = attr->ia_gid; 1081 - if (attr->ia_valid & ATTR_ATIME) 1082 - inode->i_atime = timespec64_trunc(attr->ia_atime, 1083 - inode->i_sb->s_time_gran); 1084 - if (attr->ia_valid & ATTR_MTIME) 1085 - inode->i_mtime = timespec64_trunc(attr->ia_mtime, 1086 - inode->i_sb->s_time_gran); 1087 - if (attr->ia_valid & ATTR_CTIME) 1088 - inode->i_ctime = timespec64_trunc(attr->ia_ctime, 1089 - inode->i_sb->s_time_gran); 1081 + if (attr->ia_valid & ATTR_ATIME) { 1082 + inode->i_atime = timestamp_truncate(attr->ia_atime, 1083 + inode); 1084 + } 1085 + if (attr->ia_valid & ATTR_MTIME) { 1086 + inode->i_mtime = timestamp_truncate(attr->ia_mtime, 1087 + inode); 1088 + } 1089 + if (attr->ia_valid & ATTR_CTIME) { 1090 + inode->i_ctime = timestamp_truncate(attr->ia_ctime, 1091 + inode); 1092 + } 1090 1093 if (attr->ia_valid & ATTR_MODE) { 1091 1094 umode_t mode = attr->ia_mode; 1092 1095
+7
fs/ufs/super.c
··· 843 843 844 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 850 switch (sbi->s_mount_opt & UFS_MOUNT_UFSTYPE) { 847 851 case UFS_MOUNT_UFSTYPE_44BSD: 848 852 UFSD("ufstype=44bsd\n"); ··· 865 861 uspi->s_fshift = 9; 866 862 uspi->s_sbsize = super_block_size = 1536; 867 863 uspi->s_sbbase = 0; 864 + sb->s_time_gran = 1; 865 + sb->s_time_min = S64_MIN; 866 + sb->s_time_max = S64_MAX; 868 867 flags |= UFS_TYPE_UFS2 | UFS_DE_44BSD | UFS_UID_44BSD | UFS_ST_44BSD | UFS_CG_44BSD; 869 868 break; 870 869
+2 -4
fs/utimes.c
··· 36 36 if (times[0].tv_nsec == UTIME_OMIT) 37 37 newattrs.ia_valid &= ~ATTR_ATIME; 38 38 else if (times[0].tv_nsec != UTIME_NOW) { 39 - newattrs.ia_atime.tv_sec = times[0].tv_sec; 40 - newattrs.ia_atime.tv_nsec = times[0].tv_nsec; 39 + newattrs.ia_atime = timestamp_truncate(times[0], inode); 41 40 newattrs.ia_valid |= ATTR_ATIME_SET; 42 41 } 43 42 44 43 if (times[1].tv_nsec == UTIME_OMIT) 45 44 newattrs.ia_valid &= ~ATTR_MTIME; 46 45 else if (times[1].tv_nsec != UTIME_NOW) { 47 - newattrs.ia_mtime.tv_sec = times[1].tv_sec; 48 - newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; 46 + newattrs.ia_mtime = timestamp_truncate(times[1], inode); 49 47 newattrs.ia_valid |= ATTR_MTIME_SET; 50 48 } 51 49 /*
+2
fs/xfs/xfs_super.c
··· 1664 1664 sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); 1665 1665 sb->s_max_links = XFS_MAXLINK; 1666 1666 sb->s_time_gran = 1; 1667 + sb->s_time_min = S32_MIN; 1668 + sb->s_time_max = S32_MAX; 1667 1669 sb->s_iflags |= SB_I_CGROUPWB; 1668 1670 1669 1671 set_posix_acl_flag(sb);
+5
include/linux/fs.h
··· 732 732 void *i_private; /* fs or device private pointer */ 733 733 } __randomize_layout; 734 734 735 + struct timespec64 timestamp_truncate(struct timespec64 t, struct inode *inode); 736 + 735 737 static inline unsigned int i_blocksize(const struct inode *node) 736 738 { 737 739 return (1 << node->i_blkbits); ··· 1460 1458 1461 1459 /* Granularity of c/m/atime in ns (cannot be worse than a second) */ 1462 1460 u32 s_time_gran; 1461 + /* Time limits for c/m/atime in seconds */ 1462 + time64_t s_time_min; 1463 + time64_t s_time_max; 1463 1464 #ifdef CONFIG_FSNOTIFY 1464 1465 __u32 s_fsnotify_mask; 1465 1466 struct fsnotify_mark_connector __rcu *s_fsnotify_marks;
+2
include/linux/time64.h
··· 30 30 31 31 /* Located here for timespec[64]_valid_strict */ 32 32 #define TIME64_MAX ((s64)~((u64)1 << 63)) 33 + #define TIME64_MIN (-TIME64_MAX - 1) 34 + 33 35 #define KTIME_MAX ((s64)~((u64)1 << 63)) 34 36 #define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) 35 37