Change all struct timespec references to struct inode_timespec. This will help the switch to struct timespec64 when CONFIG_FS_USES_64BIT_TIME is enabled.
Use current_fs_time() instead of CURRENT_TIME macros to help range and precesion checks.
Truncate and perform range checks before saving the times in struct inode.
Switch over connection times to use SYSTEM_TIME macro instead of CURRENT_TIME. Since SYSTEM_TIME is also under the CONFIG_FS_USES_64BIT_TIME this will help the switch to use timespec64.
The time conversion api's will be moved to kernel/time with more generic implementations for all file systems to share. This will be in a separate patch series.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com --- fs/cifs/cache.c | 16 +++++++----- fs/cifs/cifsencrypt.c | 2 +- fs/cifs/cifsglob.h | 6 ++--- fs/cifs/cifsproto.h | 7 +++--- fs/cifs/cifssmb.c | 9 ++++--- fs/cifs/file.c | 9 ++++--- fs/cifs/inode.c | 68 ++++++++++++++++++++++++++++++++------------------- fs/cifs/netmisc.c | 10 ++++---- 8 files changed, 78 insertions(+), 49 deletions(-)
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c index 6c665bf..b662e8a 100644 --- a/fs/cifs/cache.c +++ b/fs/cifs/cache.c @@ -221,8 +221,8 @@ const struct fscache_cookie_def cifs_fscache_super_index_def = { * Auxiliary data attached to CIFS inode within the cache */ struct cifs_fscache_inode_auxdata { - struct timespec last_write_time; - struct timespec last_change_time; + struct inode_timespec last_write_time; + struct inode_timespec last_change_time; u64 eof; };
@@ -259,8 +259,10 @@ cifs_fscache_inode_get_aux(const void *cookie_netfs_data, void *buffer,
memset(&auxdata, 0, sizeof(auxdata)); auxdata.eof = cifsi->server_eof; - auxdata.last_write_time = cifsi->vfs_inode.i_mtime; - auxdata.last_change_time = cifsi->vfs_inode.i_ctime; + auxdata.last_write_time = + inode_get_inode_time(&cifsi->vfs_inode.i_mtime); + auxdata.last_change_time = + inode_get_inode_time(&cifsi->vfs_inode.i_ctime);
if (maxbuf > sizeof(auxdata)) maxbuf = sizeof(auxdata); @@ -283,8 +285,10 @@ fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
memset(&auxdata, 0, sizeof(auxdata)); auxdata.eof = cifsi->server_eof; - auxdata.last_write_time = cifsi->vfs_inode.i_mtime; - auxdata.last_change_time = cifsi->vfs_inode.i_ctime; + auxdata.last_write_time = + inode_get_inode_time(&cifsi->vfs_inode.i_mtime); + auxdata.last_change_time = + inode_get_inode_time(&cifsi->vfs_inode.i_ctime);
if (memcmp(data, &auxdata, datalen) != 0) return FSCACHE_CHECKAUX_OBSOLETE; diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index afa09fc..721676e 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -483,7 +483,7 @@ find_timestamp(struct cifs_ses *ses) blobptr += attrsize; /* advance attr value */ }
- return cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); + return cpu_to_le64(cifs_UnixTimeToNT(SYSTEM_TIME)); }
static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 472daeb..a25b2e6 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1389,9 +1389,9 @@ struct cifs_fattr { dev_t cf_rdev; unsigned int cf_nlink; unsigned int cf_dtype; - struct timespec cf_atime; - struct timespec cf_mtime; - struct timespec cf_ctime; + struct inode_timespec cf_atime; + struct inode_timespec cf_mtime; + struct inode_timespec cf_ctime; };
static inline void free_dfs_info_param(struct dfs_info3_param *param) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index eed7ff5..d2f8fd4 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -126,9 +126,10 @@ extern enum securityEnum select_sectype(struct TCP_Server_Info *server, enum securityEnum requested); extern int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, const struct nls_table *nls_cp); -extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); -extern u64 cifs_UnixTimeToNT(struct timespec); -extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, +extern struct inode_timespec + cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); +extern u64 cifs_UnixTimeToNT(struct inode_timespec); +extern struct inode_timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset); extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); extern int cifs_get_writer(struct cifsInodeInfo *cinode); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 90b4f9f..2c8b550 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -478,8 +478,9 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) * this requirement. */ int val, seconds, remain, result; - struct timespec ts, utc; - utc = CURRENT_TIME; + struct inode_timespec ts, utc; + + utc = SYSTEM_TIME; ts = cnvrtDosUnixTm(rsp->SrvTime.Date, rsp->SrvTime.Time, 0); cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n", @@ -4000,7 +4001,9 @@ QInfRetry: if (rc) { cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc); } else if (data) { - struct timespec ts; + + struct inode_timespec ts; + __u32 time = le32_to_cpu(pSMBr->last_write_time);
/* decode response */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 0a2752b..a79c664 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1839,6 +1839,7 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) int bytes_written = 0; struct inode *inode; struct cifsFileInfo *open_file; + struct inode_timespec now;
if (!mapping || !mapping->host) return -EFAULT; @@ -1870,7 +1871,9 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) write_data, to - from, &offset); cifsFileInfo_put(open_file); /* Does mm or vfs already set times? */ - inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb); + now = current_fs_time(inode->i_sb); + inode_set_inode_time(&inode->i_atime, now); + inode_set_inode_time(&inode->i_mtime, now); if ((bytes_written > 0) && (offset)) rc = 0; else if (bytes_written < 0) @@ -3567,6 +3570,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page, loff_t *poffset) { char *read_data; + struct inode *inode = file_inode(file); int rc;
/* Is the page cached? */ @@ -3584,8 +3588,7 @@ static int cifs_readpage_worker(struct file *file, struct page *page, else cifs_dbg(FYI, "Bytes read %d\n", rc);
- file_inode(file)->i_atime = - current_fs_time(file_inode(file)->i_sb); + inode_set_inode_time(&inode->i_atime, current_fs_time(inode->i_sb));
if (PAGE_CACHE_SIZE > rc) memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 6b66dd5..fde63b8 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -92,6 +92,7 @@ static void cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) { struct cifsInodeInfo *cifs_i = CIFS_I(inode); + struct inode_timespec mtime;
cifs_dbg(FYI, "%s: revalidating inode %llu\n", __func__, cifs_i->uniqueid); @@ -110,12 +111,13 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) }
/* revalidate if mtime or size have changed */ - if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) && - cifs_i->server_eof == fattr->cf_eof) { + mtime = inode_get_inode_time(&inode->i_mtime); + if (inode_timespec_equal(&mtime, &fattr->cf_mtime) + && cifs_i->server_eof == fattr->cf_eof) { cifs_dbg(FYI, "%s: inode %llu is unchanged\n", - __func__, cifs_i->uniqueid); - return; - } + __func__, cifs_i->uniqueid); + return; + }
cifs_dbg(FYI, "%s: invalidating inode %llu mapping\n", __func__, cifs_i->uniqueid); @@ -155,13 +157,17 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) { struct cifsInodeInfo *cifs_i = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct super_block *sb = inode->i_sb;
cifs_revalidate_cache(inode, fattr);
spin_lock(&inode->i_lock); - inode->i_atime = fattr->cf_atime; - inode->i_mtime = fattr->cf_mtime; - inode->i_ctime = fattr->cf_ctime; + inode_set_inode_time(&inode->i_atime, + fs_time_trunc(fattr->cf_atime, sb)); + inode_set_inode_time(&inode->i_mtime, + fs_time_trunc(fattr->cf_mtime, sb)); + inode_set_inode_time(&inode->i_ctime, + fs_time_trunc(fattr->cf_ctime, sb)); inode->i_rdev = fattr->cf_rdev; cifs_nlink_fattr_to_inode(inode, fattr); inode->i_uid = fattr->cf_uid; @@ -227,10 +233,10 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, fattr->cf_uniqueid = le64_to_cpu(info->UniqueId); fattr->cf_bytes = le64_to_cpu(info->NumOfBytes); fattr->cf_eof = le64_to_cpu(info->EndOfFile); - fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime); fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange); + fattr->cf_mode = le64_to_cpu(info->Permissions);
/* @@ -288,7 +294,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, fattr->cf_uid = uid; } } - + fattr->cf_gid = cifs_sb->mnt_gid; if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) { u64 id = le64_to_cpu(info->Gid); @@ -313,6 +319,7 @@ static void cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) { struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + struct inode_timespec now;
cifs_dbg(FYI, "creating fake fattr for DFS referral\n");
@@ -320,9 +327,10 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU; fattr->cf_uid = cifs_sb->mnt_uid; fattr->cf_gid = cifs_sb->mnt_gid; - fattr->cf_atime = CURRENT_TIME; - fattr->cf_ctime = CURRENT_TIME; - fattr->cf_mtime = CURRENT_TIME; + now = current_fs_time(sb); + fattr->cf_atime = now; + fattr->cf_ctime = now; + fattr->cf_mtime = now; fattr->cf_nlink = 2; fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; } @@ -584,9 +592,10 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, /* Fill a cifs_fattr struct with info from FILE_ALL_INFO */ static void cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, - struct cifs_sb_info *cifs_sb, bool adjust_tz, + struct super_block *sb, bool adjust_tz, bool symlink) { + struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
memset(fattr, 0, sizeof(*fattr)); @@ -597,7 +606,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, if (info->LastAccessTime) fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); else - fattr->cf_atime = CURRENT_TIME; + fattr->cf_atime = current_fs_time(sb);
fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); @@ -657,7 +666,6 @@ cifs_get_file_info(struct file *filp) FILE_ALL_INFO find_data; struct cifs_fattr fattr; struct inode *inode = file_inode(filp); - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifsFileInfo *cfile = filp->private_data; struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); struct TCP_Server_Info *server = tcon->ses->server; @@ -669,7 +677,7 @@ cifs_get_file_info(struct file *filp) rc = server->ops->query_file_info(xid, tcon, &cfile->fid, &find_data); switch (rc) { case 0: - cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false, + cifs_all_info_to_fattr(&fattr, &find_data, inode->i_sb, false, false); break; case -EREMOTE: @@ -751,7 +759,7 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, }
if (!rc) { - cifs_all_info_to_fattr(&fattr, data, cifs_sb, adjust_tz, + cifs_all_info_to_fattr(&fattr, data, sb, adjust_tz, symlink); } else if (rc == -EREMOTE) { cifs_create_dfs_fattr(&fattr, sb); @@ -1146,7 +1154,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry, rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, fid.netfid, current->tgid); /* although we would like to mark the file hidden - if that fails we will still try to rename it */ + if that fails we will still try to rename it */ if (!rc) cifsInode->cifsAttrs = dosattr; else @@ -1232,6 +1240,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) unsigned int xid; char *full_path = NULL; struct inode *inode = d_inode(dentry); + struct inode_timespec now; struct cifsInodeInfo *cifs_inode; struct super_block *sb = dir->i_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); @@ -1323,9 +1332,11 @@ out_reval: cifs_inode = CIFS_I(inode); cifs_inode->time = 0; /* will force revalidate to get info when needed */ - inode->i_ctime = current_fs_time(sb); + inode_set_inode_time(&inode->i_ctime, current_fs_time(sb)); } - dir->i_ctime = dir->i_mtime = current_fs_time(sb); + now = current_fs_time(sb); + inode_set_inode_time(&dir->i_ctime, now); + inode_set_inode_time(&dir->i_mtime, now); cifs_inode = CIFS_I(dir); CIFS_I(dir)->time = 0; /* force revalidate of dir as well */ unlink_out: @@ -1545,6 +1556,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) struct TCP_Server_Info *server; char *full_path = NULL; struct cifsInodeInfo *cifsInode; + struct inode_timespec now;
cifs_dbg(FYI, "cifs_rmdir, inode = 0x%p\n", inode);
@@ -1592,8 +1604,10 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) */ cifsInode->time = 0;
- d_inode(direntry)->i_ctime = inode->i_ctime = inode->i_mtime = - current_fs_time(inode->i_sb); + now = current_fs_time(inode->i_sb); + inode_set_inode_time(&d_inode(direntry)->i_ctime, now); + inode_set_inode_time(&inode->i_ctime, now); + inode_set_inode_time(&inode->i_mtime, now);
rmdir_exit: kfree(full_path); @@ -1672,6 +1686,7 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry, struct cifs_tcon *tcon; FILE_UNIX_BASIC_INFO *info_buf_source = NULL; FILE_UNIX_BASIC_INFO *info_buf_target; + struct inode_timespec now; unsigned int xid; int rc, tmprc;
@@ -1765,8 +1780,11 @@ unlink_target: /* force revalidate to go get info when needed */ CIFS_I(source_dir)->time = CIFS_I(target_dir)->time = 0;
- source_dir->i_ctime = source_dir->i_mtime = target_dir->i_ctime = - target_dir->i_mtime = current_fs_time(source_dir->i_sb); + now = current_fs_time(source_dir->i_sb); + inode_set_inode_time(&source_dir->i_ctime, now); + inode_set_inode_time(&source_dir->i_mtime, now); + inode_set_inode_time(&target_dir->i_ctime, now); + inode_set_inode_time(&target_dir->i_mtime, now);
cifs_rename_exit: kfree(info_buf_source); diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index abae6dd..adcc88c 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -918,10 +918,10 @@ smbCalcSize(void *buf) * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) * into Unix UTC (based 1970-01-01, in seconds). */ -struct timespec +struct inode_timespec cifs_NTtimeToUnix(__le64 ntutc) { - struct timespec ts; + struct inode_timespec ts; /* BB what about the timezone? BB */
/* Subtract the NTFS time offset, then convert to 1s intervals. */ @@ -949,7 +949,7 @@ cifs_NTtimeToUnix(__le64 ntutc)
/* Convert the Unix UTC into NT UTC. */ u64 -cifs_UnixTimeToNT(struct timespec t) +cifs_UnixTimeToNT(struct inode_timespec t) { /* Convert to 100ns intervals and then add the NTFS time offset. */ return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; @@ -959,9 +959,9 @@ static const int total_days_of_prev_months[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
-struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) +struct inode_timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) { - struct timespec ts; + struct inode_timespec ts; int sec, min, days, month, year; u16 date = le16_to_cpu(le_date); u16 time = le16_to_cpu(le_time);