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

cifs: use timespec64 internally

In cifs, the timestamps are stored in memory in the cifs_fattr structure,
which uses the deprecated 'timespec' structure. Now that the VFS code
has moved on to 'timespec64', the next step is to change over the fattr
as well.

This also makes 32-bit and 64-bit systems behave the same way, and
no longer overflow the 32-bit time_t in year 2038.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Paulo Alcantara <palcantara@suse.de>
Signed-off-by: Steve French <stfrench@microsoft.com>

authored by

Arnd Bergmann and committed by
Steve French
95390201 ff361fda

+40 -41
+2 -2
fs/cifs/cifsencrypt.c
··· 452 452 unsigned char *blobptr; 453 453 unsigned char *blobend; 454 454 struct ntlmssp2_name *attrptr; 455 - struct timespec ts; 455 + struct timespec64 ts; 456 456 457 457 if (!ses->auth_key.len || !ses->auth_key.response) 458 458 return 0; ··· 477 477 blobptr += attrsize; /* advance attr value */ 478 478 } 479 479 480 - ktime_get_real_ts(&ts); 480 + ktime_get_real_ts64(&ts); 481 481 return cpu_to_le64(cifs_UnixTimeToNT(ts)); 482 482 } 483 483
+3 -3
fs/cifs/cifsglob.h
··· 1544 1544 dev_t cf_rdev; 1545 1545 unsigned int cf_nlink; 1546 1546 unsigned int cf_dtype; 1547 - struct timespec cf_atime; 1548 - struct timespec cf_mtime; 1549 - struct timespec cf_ctime; 1547 + struct timespec64 cf_atime; 1548 + struct timespec64 cf_mtime; 1549 + struct timespec64 cf_ctime; 1550 1550 }; 1551 1551 1552 1552 static inline void free_dfs_info_param(struct dfs_info3_param *param)
+3 -3
fs/cifs/cifsproto.h
··· 143 143 enum securityEnum requested); 144 144 extern int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, 145 145 const struct nls_table *nls_cp); 146 - extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); 147 - extern u64 cifs_UnixTimeToNT(struct timespec); 148 - extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, 146 + extern struct timespec64 cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); 147 + extern u64 cifs_UnixTimeToNT(struct timespec64); 148 + extern struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, 149 149 int offset); 150 150 extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); 151 151 extern int cifs_get_writer(struct cifsInodeInfo *cinode);
+6 -6
fs/cifs/cifssmb.c
··· 508 508 * this requirement. 509 509 */ 510 510 int val, seconds, remain, result; 511 - struct timespec ts; 512 - unsigned long utc = ktime_get_real_seconds(); 511 + struct timespec64 ts; 512 + time64_t utc = ktime_get_real_seconds(); 513 513 ts = cnvrtDosUnixTm(rsp->SrvTime.Date, 514 514 rsp->SrvTime.Time, 0); 515 - cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n", 516 - (int)ts.tv_sec, (int)utc, 517 - (int)(utc - ts.tv_sec)); 515 + cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n", 516 + ts.tv_sec, utc, 517 + utc - ts.tv_sec); 518 518 val = (int)(utc - ts.tv_sec); 519 519 seconds = abs(val); 520 520 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; ··· 4082 4082 if (rc) { 4083 4083 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc); 4084 4084 } else if (data) { 4085 - struct timespec ts; 4085 + struct timespec64 ts; 4086 4086 __u32 time = le32_to_cpu(pSMBr->last_write_time); 4087 4087 4088 4088 /* decode response */
+16 -18
fs/cifs/inode.c
··· 95 95 cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) 96 96 { 97 97 struct cifsInodeInfo *cifs_i = CIFS_I(inode); 98 - struct timespec ts; 99 98 100 99 cifs_dbg(FYI, "%s: revalidating inode %llu\n", 101 100 __func__, cifs_i->uniqueid); ··· 113 114 } 114 115 115 116 /* revalidate if mtime or size have changed */ 116 - ts = timespec64_to_timespec(inode->i_mtime); 117 - if (timespec_equal(&ts, &fattr->cf_mtime) && 117 + if (timespec64_equal(&inode->i_mtime, &fattr->cf_mtime) && 118 118 cifs_i->server_eof == fattr->cf_eof) { 119 119 cifs_dbg(FYI, "%s: inode %llu is unchanged\n", 120 120 __func__, cifs_i->uniqueid); ··· 162 164 cifs_revalidate_cache(inode, fattr); 163 165 164 166 spin_lock(&inode->i_lock); 165 - inode->i_atime = timespec_to_timespec64(fattr->cf_atime); 166 - inode->i_mtime = timespec_to_timespec64(fattr->cf_mtime); 167 - inode->i_ctime = timespec_to_timespec64(fattr->cf_ctime); 167 + inode->i_atime = fattr->cf_atime; 168 + inode->i_mtime = fattr->cf_mtime; 169 + inode->i_ctime = fattr->cf_ctime; 168 170 inode->i_rdev = fattr->cf_rdev; 169 171 cifs_nlink_fattr_to_inode(inode, fattr); 170 172 inode->i_uid = fattr->cf_uid; ··· 325 327 fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU; 326 328 fattr->cf_uid = cifs_sb->mnt_uid; 327 329 fattr->cf_gid = cifs_sb->mnt_gid; 328 - ktime_get_real_ts(&fattr->cf_mtime); 329 - fattr->cf_mtime = timespec_trunc(fattr->cf_mtime, sb->s_time_gran); 330 + ktime_get_real_ts64(&fattr->cf_mtime); 331 + fattr->cf_mtime = timespec64_trunc(fattr->cf_mtime, sb->s_time_gran); 330 332 fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime; 331 333 fattr->cf_nlink = 2; 332 334 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; ··· 602 604 if (info->LastAccessTime) 603 605 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); 604 606 else { 605 - ktime_get_real_ts(&fattr->cf_atime); 606 - fattr->cf_atime = timespec_trunc(fattr->cf_atime, sb->s_time_gran); 607 + ktime_get_real_ts64(&fattr->cf_atime); 608 + fattr->cf_atime = timespec64_trunc(fattr->cf_atime, sb->s_time_gran); 607 609 } 608 610 609 611 fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); ··· 1123 1125 if (attrs->ia_valid & ATTR_ATIME) { 1124 1126 set_time = true; 1125 1127 info_buf.LastAccessTime = 1126 - cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_atime))); 1128 + cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime)); 1127 1129 } else 1128 1130 info_buf.LastAccessTime = 0; 1129 1131 1130 1132 if (attrs->ia_valid & ATTR_MTIME) { 1131 1133 set_time = true; 1132 1134 info_buf.LastWriteTime = 1133 - cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_mtime))); 1135 + cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime)); 1134 1136 } else 1135 1137 info_buf.LastWriteTime = 0; 1136 1138 ··· 1143 1145 if (set_time && (attrs->ia_valid & ATTR_CTIME)) { 1144 1146 cifs_dbg(FYI, "CIFS - CTIME changed\n"); 1145 1147 info_buf.ChangeTime = 1146 - cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_ctime))); 1148 + cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); 1147 1149 } else 1148 1150 info_buf.ChangeTime = 0; 1149 1151 ··· 2069 2071 /* old CIFS Unix Extensions doesn't return create time */ 2070 2072 if (CIFS_I(inode)->createtime) { 2071 2073 stat->result_mask |= STATX_BTIME; 2072 - stat->btime = timespec_to_timespec64( 2073 - cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime))); 2074 + stat->btime = 2075 + cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime)); 2074 2076 } 2075 2077 2076 2078 stat->attributes_mask |= (STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED); ··· 2276 2278 args->gid = INVALID_GID; /* no change */ 2277 2279 2278 2280 if (attrs->ia_valid & ATTR_ATIME) 2279 - args->atime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_atime)); 2281 + args->atime = cifs_UnixTimeToNT(attrs->ia_atime); 2280 2282 else 2281 2283 args->atime = NO_CHANGE_64; 2282 2284 2283 2285 if (attrs->ia_valid & ATTR_MTIME) 2284 - args->mtime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_mtime)); 2286 + args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime); 2285 2287 else 2286 2288 args->mtime = NO_CHANGE_64; 2287 2289 2288 2290 if (attrs->ia_valid & ATTR_CTIME) 2289 - args->ctime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_ctime)); 2291 + args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime); 2290 2292 else 2291 2293 args->ctime = NO_CHANGE_64; 2292 2294
+10 -9
fs/cifs/netmisc.c
··· 918 918 * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) 919 919 * into Unix UTC (based 1970-01-01, in seconds). 920 920 */ 921 - struct timespec 921 + struct timespec64 922 922 cifs_NTtimeToUnix(__le64 ntutc) 923 923 { 924 - struct timespec ts; 924 + struct timespec64 ts; 925 925 /* BB what about the timezone? BB */ 926 926 927 927 /* Subtract the NTFS time offset, then convert to 1s intervals. */ ··· 935 935 */ 936 936 if (t < 0) { 937 937 abs_t = -t; 938 - ts.tv_nsec = (long)(do_div(abs_t, 10000000) * 100); 938 + ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100); 939 939 ts.tv_nsec = -ts.tv_nsec; 940 940 ts.tv_sec = -abs_t; 941 941 } else { 942 942 abs_t = t; 943 - ts.tv_nsec = (long)do_div(abs_t, 10000000) * 100; 943 + ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100; 944 944 ts.tv_sec = abs_t; 945 945 } 946 946 ··· 949 949 950 950 /* Convert the Unix UTC into NT UTC. */ 951 951 u64 952 - cifs_UnixTimeToNT(struct timespec t) 952 + cifs_UnixTimeToNT(struct timespec64 t) 953 953 { 954 954 /* Convert to 100ns intervals and then add the NTFS time offset. */ 955 955 return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; ··· 959 959 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 960 960 }; 961 961 962 - struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) 962 + struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) 963 963 { 964 - struct timespec ts; 965 - int sec, min, days, month, year; 964 + struct timespec64 ts; 965 + time64_t sec; 966 + int min, days, month, year; 966 967 u16 date = le16_to_cpu(le_date); 967 968 u16 time = le16_to_cpu(le_time); 968 969 SMB_TIME *st = (SMB_TIME *)&time; ··· 974 973 sec = 2 * st->TwoSeconds; 975 974 min = st->Minutes; 976 975 if ((sec > 59) || (min > 59)) 977 - cifs_dbg(VFS, "illegal time min %d sec %d\n", min, sec); 976 + cifs_dbg(VFS, "illegal time min %d sec %lld\n", min, sec); 978 977 sec += (min * 60); 979 978 sec += 60 * 60 * st->Hours; 980 979 if (st->Hours > 24)