Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 95390201 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Steve French
Browse files

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: default avatarArnd Bergmann <arnd@arndb.de>
Reviewed-by: default avatarPaulo Alcantara <palcantara@suse.de>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent ff361fda
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -452,7 +452,7 @@ find_timestamp(struct cifs_ses *ses)
	unsigned char *blobptr;
	unsigned char *blobptr;
	unsigned char *blobend;
	unsigned char *blobend;
	struct ntlmssp2_name *attrptr;
	struct ntlmssp2_name *attrptr;
	struct timespec ts;
	struct timespec64 ts;


	if (!ses->auth_key.len || !ses->auth_key.response)
	if (!ses->auth_key.len || !ses->auth_key.response)
		return 0;
		return 0;
@@ -477,7 +477,7 @@ find_timestamp(struct cifs_ses *ses)
		blobptr += attrsize; /* advance attr value */
		blobptr += attrsize; /* advance attr value */
	}
	}


	ktime_get_real_ts(&ts);
	ktime_get_real_ts64(&ts);
	return cpu_to_le64(cifs_UnixTimeToNT(ts));
	return cpu_to_le64(cifs_UnixTimeToNT(ts));
}
}


+3 −3
Original line number Original line Diff line number Diff line
@@ -1544,9 +1544,9 @@ struct cifs_fattr {
	dev_t		cf_rdev;
	dev_t		cf_rdev;
	unsigned int	cf_nlink;
	unsigned int	cf_nlink;
	unsigned int	cf_dtype;
	unsigned int	cf_dtype;
	struct timespec	cf_atime;
	struct timespec64 cf_atime;
	struct timespec	cf_mtime;
	struct timespec64 cf_mtime;
	struct timespec	cf_ctime;
	struct timespec64 cf_ctime;
};
};


static inline void free_dfs_info_param(struct dfs_info3_param *param)
static inline void free_dfs_info_param(struct dfs_info3_param *param)
+3 −3
Original line number Original line Diff line number Diff line
@@ -143,9 +143,9 @@ extern enum securityEnum select_sectype(struct TCP_Server_Info *server,
				enum securityEnum requested);
				enum securityEnum requested);
extern int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
extern int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses,
			  const struct nls_table *nls_cp);
			  const struct nls_table *nls_cp);
extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
extern struct timespec64 cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
extern u64 cifs_UnixTimeToNT(struct timespec);
extern u64 cifs_UnixTimeToNT(struct timespec64);
extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
extern struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
				      int offset);
				      int offset);
extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
extern int cifs_get_writer(struct cifsInodeInfo *cinode);
extern int cifs_get_writer(struct cifsInodeInfo *cinode);
+6 −6
Original line number Original line Diff line number Diff line
@@ -508,13 +508,13 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr)
		 * this requirement.
		 * this requirement.
		 */
		 */
		int val, seconds, remain, result;
		int val, seconds, remain, result;
		struct timespec ts;
		struct timespec64 ts;
		unsigned long utc = ktime_get_real_seconds();
		time64_t utc = ktime_get_real_seconds();
		ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
		ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
				    rsp->SrvTime.Time, 0);
				    rsp->SrvTime.Time, 0);
		cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n",
		cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n",
			 (int)ts.tv_sec, (int)utc,
			 ts.tv_sec, utc,
			 (int)(utc - ts.tv_sec));
			 utc - ts.tv_sec);
		val = (int)(utc - ts.tv_sec);
		val = (int)(utc - ts.tv_sec);
		seconds = abs(val);
		seconds = abs(val);
		result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
		result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
@@ -4082,7 +4082,7 @@ SMBQueryInformation(const unsigned int xid, struct cifs_tcon *tcon,
	if (rc) {
	if (rc) {
		cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
		cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc);
	} else if (data) {
	} else if (data) {
		struct timespec ts;
		struct timespec64 ts;
		__u32 time = le32_to_cpu(pSMBr->last_write_time);
		__u32 time = le32_to_cpu(pSMBr->last_write_time);


		/* decode response */
		/* decode response */
+16 −18
Original line number Original line Diff line number Diff line
@@ -95,7 +95,6 @@ static void
cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
{
{
	struct cifsInodeInfo *cifs_i = CIFS_I(inode);
	struct cifsInodeInfo *cifs_i = CIFS_I(inode);
	struct timespec ts;


	cifs_dbg(FYI, "%s: revalidating inode %llu\n",
	cifs_dbg(FYI, "%s: revalidating inode %llu\n",
		 __func__, cifs_i->uniqueid);
		 __func__, cifs_i->uniqueid);
@@ -114,8 +113,7 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
	}
	}


	 /* revalidate if mtime or size have changed */
	 /* revalidate if mtime or size have changed */
	ts = timespec64_to_timespec(inode->i_mtime);
	if (timespec64_equal(&inode->i_mtime, &fattr->cf_mtime) &&
	if (timespec_equal(&ts, &fattr->cf_mtime) &&
	    cifs_i->server_eof == fattr->cf_eof) {
	    cifs_i->server_eof == fattr->cf_eof) {
		cifs_dbg(FYI, "%s: inode %llu is unchanged\n",
		cifs_dbg(FYI, "%s: inode %llu is unchanged\n",
			 __func__, cifs_i->uniqueid);
			 __func__, cifs_i->uniqueid);
@@ -164,9 +162,9 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
	cifs_revalidate_cache(inode, fattr);
	cifs_revalidate_cache(inode, fattr);


	spin_lock(&inode->i_lock);
	spin_lock(&inode->i_lock);
	inode->i_atime = timespec_to_timespec64(fattr->cf_atime);
	inode->i_atime = fattr->cf_atime;
	inode->i_mtime = timespec_to_timespec64(fattr->cf_mtime);
	inode->i_mtime = fattr->cf_mtime;
	inode->i_ctime = timespec_to_timespec64(fattr->cf_ctime);
	inode->i_ctime = fattr->cf_ctime;
	inode->i_rdev = fattr->cf_rdev;
	inode->i_rdev = fattr->cf_rdev;
	cifs_nlink_fattr_to_inode(inode, fattr);
	cifs_nlink_fattr_to_inode(inode, fattr);
	inode->i_uid = fattr->cf_uid;
	inode->i_uid = fattr->cf_uid;
@@ -327,8 +325,8 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
	fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
	fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
	fattr->cf_uid = cifs_sb->mnt_uid;
	fattr->cf_uid = cifs_sb->mnt_uid;
	fattr->cf_gid = cifs_sb->mnt_gid;
	fattr->cf_gid = cifs_sb->mnt_gid;
	ktime_get_real_ts(&fattr->cf_mtime);
	ktime_get_real_ts64(&fattr->cf_mtime);
	fattr->cf_mtime = timespec_trunc(fattr->cf_mtime, sb->s_time_gran);
	fattr->cf_mtime = timespec64_trunc(fattr->cf_mtime, sb->s_time_gran);
	fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime;
	fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime;
	fattr->cf_nlink = 2;
	fattr->cf_nlink = 2;
	fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
	fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
@@ -604,8 +602,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
	if (info->LastAccessTime)
	if (info->LastAccessTime)
		fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
		fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
	else {
	else {
		ktime_get_real_ts(&fattr->cf_atime);
		ktime_get_real_ts64(&fattr->cf_atime);
		fattr->cf_atime = timespec_trunc(fattr->cf_atime, sb->s_time_gran);
		fattr->cf_atime = timespec64_trunc(fattr->cf_atime, sb->s_time_gran);
	}
	}


	fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
	fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
@@ -1125,14 +1123,14 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid,
	if (attrs->ia_valid & ATTR_ATIME) {
	if (attrs->ia_valid & ATTR_ATIME) {
		set_time = true;
		set_time = true;
		info_buf.LastAccessTime =
		info_buf.LastAccessTime =
			cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_atime)));
			cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
	} else
	} else
		info_buf.LastAccessTime = 0;
		info_buf.LastAccessTime = 0;


	if (attrs->ia_valid & ATTR_MTIME) {
	if (attrs->ia_valid & ATTR_MTIME) {
		set_time = true;
		set_time = true;
		info_buf.LastWriteTime =
		info_buf.LastWriteTime =
		    cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_mtime)));
		    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
	} else
	} else
		info_buf.LastWriteTime = 0;
		info_buf.LastWriteTime = 0;


@@ -1145,7 +1143,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid,
	if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
	if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
		cifs_dbg(FYI, "CIFS - CTIME changed\n");
		cifs_dbg(FYI, "CIFS - CTIME changed\n");
		info_buf.ChangeTime =
		info_buf.ChangeTime =
		    cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_ctime)));
		    cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
	} else
	} else
		info_buf.ChangeTime = 0;
		info_buf.ChangeTime = 0;


@@ -2071,8 +2069,8 @@ int cifs_getattr(const struct path *path, struct kstat *stat,
	/* old CIFS Unix Extensions doesn't return create time */
	/* old CIFS Unix Extensions doesn't return create time */
	if (CIFS_I(inode)->createtime) {
	if (CIFS_I(inode)->createtime) {
		stat->result_mask |= STATX_BTIME;
		stat->result_mask |= STATX_BTIME;
		stat->btime = timespec_to_timespec64(
		stat->btime =
		      cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime)));
		      cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime));
	}
	}


	stat->attributes_mask |= (STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED);
	stat->attributes_mask |= (STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED);
@@ -2278,17 +2276,17 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
		args->gid = INVALID_GID; /* no change */
		args->gid = INVALID_GID; /* no change */


	if (attrs->ia_valid & ATTR_ATIME)
	if (attrs->ia_valid & ATTR_ATIME)
		args->atime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_atime));
		args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
	else
	else
		args->atime = NO_CHANGE_64;
		args->atime = NO_CHANGE_64;


	if (attrs->ia_valid & ATTR_MTIME)
	if (attrs->ia_valid & ATTR_MTIME)
		args->mtime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_mtime));
		args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
	else
	else
		args->mtime = NO_CHANGE_64;
		args->mtime = NO_CHANGE_64;


	if (attrs->ia_valid & ATTR_CTIME)
	if (attrs->ia_valid & ATTR_CTIME)
		args->ctime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_ctime));
		args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
	else
	else
		args->ctime = NO_CHANGE_64;
		args->ctime = NO_CHANGE_64;


Loading