Commit bddea11b authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'imm.timestamp' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs timestamp updates from Al Viro:
 "More 64bit timestamp work"

* 'imm.timestamp' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  kernfs: don't bother with timestamp truncation
  fs: Do not overload update_time
  fs: Delete timespec64_trunc()
  fs: ubifs: Eliminate timespec64_trunc() usage
  fs: ceph: Delete timespec64_trunc() usage
  fs: cifs: Delete usage of timespec64_trunc
  fs: fat: Eliminate timespec64_trunc() usage
  utimes: Clamp the timestamps in notify_change()
parents 33b40134 f0f3588f
...@@ -183,18 +183,12 @@ void setattr_copy(struct inode *inode, const struct iattr *attr) ...@@ -183,18 +183,12 @@ void setattr_copy(struct inode *inode, const struct iattr *attr)
inode->i_uid = attr->ia_uid; inode->i_uid = attr->ia_uid;
if (ia_valid & ATTR_GID) if (ia_valid & ATTR_GID)
inode->i_gid = attr->ia_gid; inode->i_gid = attr->ia_gid;
if (ia_valid & ATTR_ATIME) { if (ia_valid & ATTR_ATIME)
inode->i_atime = timestamp_truncate(attr->ia_atime, inode->i_atime = attr->ia_atime;
inode); if (ia_valid & ATTR_MTIME)
} inode->i_mtime = attr->ia_mtime;
if (ia_valid & ATTR_MTIME) { if (ia_valid & ATTR_CTIME)
inode->i_mtime = timestamp_truncate(attr->ia_mtime, inode->i_ctime = attr->ia_ctime;
inode);
}
if (ia_valid & ATTR_CTIME) {
inode->i_ctime = timestamp_truncate(attr->ia_ctime,
inode);
}
if (ia_valid & ATTR_MODE) { if (ia_valid & ATTR_MODE) {
umode_t mode = attr->ia_mode; umode_t mode = attr->ia_mode;
...@@ -268,8 +262,13 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de ...@@ -268,8 +262,13 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
attr->ia_ctime = now; attr->ia_ctime = now;
if (!(ia_valid & ATTR_ATIME_SET)) if (!(ia_valid & ATTR_ATIME_SET))
attr->ia_atime = now; attr->ia_atime = now;
else
attr->ia_atime = timestamp_truncate(attr->ia_atime, inode);
if (!(ia_valid & ATTR_MTIME_SET)) if (!(ia_valid & ATTR_MTIME_SET))
attr->ia_mtime = now; attr->ia_mtime = now;
else
attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode);
if (ia_valid & ATTR_KILL_PRIV) { if (ia_valid & ATTR_KILL_PRIV) {
error = security_inode_need_killpriv(dentry); error = security_inode_need_killpriv(dentry);
if (error < 0) if (error < 0)
......
...@@ -2072,7 +2072,6 @@ struct ceph_mds_request * ...@@ -2072,7 +2072,6 @@ struct ceph_mds_request *
ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode) ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
{ {
struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS); struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS);
struct timespec64 ts;
if (!req) if (!req)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -2091,8 +2090,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode) ...@@ -2091,8 +2090,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
init_completion(&req->r_safe_completion); init_completion(&req->r_safe_completion);
INIT_LIST_HEAD(&req->r_unsafe_item); INIT_LIST_HEAD(&req->r_unsafe_item);
ktime_get_coarse_real_ts64(&ts); ktime_get_coarse_real_ts64(&req->r_stamp);
req->r_stamp = timespec64_trunc(ts, mdsc->fsc->sb->s_time_gran);
req->r_op = op; req->r_op = op;
req->r_direct_mode = mode; req->r_direct_mode = mode;
......
...@@ -113,6 +113,7 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) ...@@ -113,6 +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 */
fattr->cf_mtime = timestamp_truncate(fattr->cf_mtime, inode);
if (timespec64_equal(&inode->i_mtime, &fattr->cf_mtime) && if (timespec64_equal(&inode->i_mtime, &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",
...@@ -162,6 +163,9 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) ...@@ -162,6 +163,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);
fattr->cf_mtime = timestamp_truncate(fattr->cf_mtime, inode);
fattr->cf_atime = timestamp_truncate(fattr->cf_atime, inode);
fattr->cf_ctime = timestamp_truncate(fattr->cf_ctime, inode);
/* we do not want atime to be less than mtime, it broke some apps */ /* we do not want atime to be less than mtime, it broke some apps */
if (timespec64_compare(&fattr->cf_atime, &fattr->cf_mtime) < 0) if (timespec64_compare(&fattr->cf_atime, &fattr->cf_mtime) < 0)
inode->i_atime = fattr->cf_mtime; inode->i_atime = fattr->cf_mtime;
...@@ -329,8 +333,7 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) ...@@ -329,8 +333,7 @@ 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_ts64(&fattr->cf_mtime); ktime_get_coarse_real_ts64(&fattr->cf_mtime);
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;
...@@ -609,10 +612,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, ...@@ -609,10 +612,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_ts64(&fattr->cf_atime); ktime_get_coarse_real_ts64(&fattr->cf_atime);
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);
fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
......
...@@ -76,14 +76,11 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) ...@@ -76,14 +76,11 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
if (ia_valid & ATTR_GID) if (ia_valid & ATTR_GID)
sd_iattr->ia_gid = iattr->ia_gid; sd_iattr->ia_gid = iattr->ia_gid;
if (ia_valid & ATTR_ATIME) if (ia_valid & ATTR_ATIME)
sd_iattr->ia_atime = timestamp_truncate(iattr->ia_atime, sd_iattr->ia_atime = iattr->ia_atime;
inode);
if (ia_valid & ATTR_MTIME) if (ia_valid & ATTR_MTIME)
sd_iattr->ia_mtime = timestamp_truncate(iattr->ia_mtime, sd_iattr->ia_mtime = iattr->ia_mtime;
inode);
if (ia_valid & ATTR_CTIME) if (ia_valid & ATTR_CTIME)
sd_iattr->ia_ctime = timestamp_truncate(iattr->ia_ctime, sd_iattr->ia_ctime = iattr->ia_ctime;
inode);
if (ia_valid & ATTR_MODE) { if (ia_valid & ATTR_MODE) {
umode_t mode = iattr->ia_mode; umode_t mode = iattr->ia_mode;
......
...@@ -829,18 +829,12 @@ static void __setattr_copy(struct inode *inode, const struct iattr *attr) ...@@ -829,18 +829,12 @@ static void __setattr_copy(struct inode *inode, const struct iattr *attr)
inode->i_uid = attr->ia_uid; inode->i_uid = attr->ia_uid;
if (ia_valid & ATTR_GID) if (ia_valid & ATTR_GID)
inode->i_gid = attr->ia_gid; inode->i_gid = attr->ia_gid;
if (ia_valid & ATTR_ATIME) { if (ia_valid & ATTR_ATIME)
inode->i_atime = timestamp_truncate(attr->ia_atime, inode->i_atime = attr->ia_atime;
inode); if (ia_valid & ATTR_MTIME)
} inode->i_mtime = attr->ia_mtime;
if (ia_valid & ATTR_MTIME) { if (ia_valid & ATTR_CTIME)
inode->i_mtime = timestamp_truncate(attr->ia_mtime, inode->i_ctime = attr->ia_ctime;
inode);
}
if (ia_valid & ATTR_CTIME) {
inode->i_ctime = timestamp_truncate(attr->ia_ctime,
inode);
}
if (ia_valid & ATTR_MODE) { if (ia_valid & ATTR_MODE) {
umode_t mode = attr->ia_mode; umode_t mode = attr->ia_mode;
......
...@@ -271,6 +271,14 @@ static inline struct timespec64 fat_timespec64_trunc_2secs(struct timespec64 ts) ...@@ -271,6 +271,14 @@ static inline struct timespec64 fat_timespec64_trunc_2secs(struct timespec64 ts)
{ {
return (struct timespec64){ ts.tv_sec & ~1ULL, 0 }; return (struct timespec64){ ts.tv_sec & ~1ULL, 0 };
} }
static inline struct timespec64 fat_timespec64_trunc_10ms(struct timespec64 ts)
{
if (ts.tv_nsec)
ts.tv_nsec -= ts.tv_nsec % 10000000UL;
return ts;
}
/* /*
* truncate the various times with appropriate granularity: * truncate the various times with appropriate granularity:
* root inode: * root inode:
...@@ -308,7 +316,7 @@ int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags) ...@@ -308,7 +316,7 @@ int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags)
} }
if (flags & S_CTIME) { if (flags & S_CTIME) {
if (sbi->options.isvfat) if (sbi->options.isvfat)
inode->i_ctime = timespec64_trunc(*now, 10000000); inode->i_ctime = fat_timespec64_trunc_10ms(*now);
else else
inode->i_ctime = fat_timespec64_trunc_2secs(*now); inode->i_ctime = fat_timespec64_trunc_2secs(*now);
} }
......
...@@ -1683,12 +1683,9 @@ EXPORT_SYMBOL(generic_update_time); ...@@ -1683,12 +1683,9 @@ EXPORT_SYMBOL(generic_update_time);
*/ */
static int update_time(struct inode *inode, struct timespec64 *time, int flags) static int update_time(struct inode *inode, struct timespec64 *time, int flags)
{ {
int (*update_time)(struct inode *, struct timespec64 *, int); if (inode->i_op->update_time)
return inode->i_op->update_time(inode, time, flags);
update_time = inode->i_op->update_time ? inode->i_op->update_time : return generic_update_time(inode, time, flags);
generic_update_time;
return update_time(inode, time, flags);
} }
/** /**
...@@ -2153,30 +2150,6 @@ void inode_nohighmem(struct inode *inode) ...@@ -2153,30 +2150,6 @@ void inode_nohighmem(struct inode *inode)
} }
EXPORT_SYMBOL(inode_nohighmem); EXPORT_SYMBOL(inode_nohighmem);
/**
* timespec64_trunc - Truncate timespec64 to a granularity
* @t: Timespec64
* @gran: Granularity in ns.
*
* Truncate a timespec64 to a granularity. Always rounds down. gran must
* not be 0 nor greater than a second (NSEC_PER_SEC, or 10^9 ns).
*/
struct timespec64 timespec64_trunc(struct timespec64 t, unsigned gran)
{
/* Avoid division in the common cases 1 ns and 1 s. */
if (gran == 1) {
/* nothing */
} else if (gran == NSEC_PER_SEC) {
t.tv_nsec = 0;
} else if (gran > 1 && gran < NSEC_PER_SEC) {
t.tv_nsec -= t.tv_nsec % gran;
} else {
WARN(1, "illegal file time granularity: %u", gran);
}
return t;
}
EXPORT_SYMBOL(timespec64_trunc);
/** /**
* timestamp_truncate - Truncate timespec to a granularity * timestamp_truncate - Truncate timespec to a granularity
* @t: Timespec * @t: Timespec
......
...@@ -160,9 +160,9 @@ static inline void set_inode_attr(struct inode *inode, ...@@ -160,9 +160,9 @@ static inline void set_inode_attr(struct inode *inode,
{ {
inode->i_uid = attrs->ia_uid; inode->i_uid = attrs->ia_uid;
inode->i_gid = attrs->ia_gid; inode->i_gid = attrs->ia_gid;
inode->i_atime = timestamp_truncate(attrs->ia_atime, inode); inode->i_atime = attrs->ia_atime;
inode->i_mtime = timestamp_truncate(attrs->ia_mtime, inode); inode->i_mtime = attrs->ia_mtime;
inode->i_ctime = timestamp_truncate(attrs->ia_ctime, inode); inode->i_ctime = attrs->ia_ctime;
} }
static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
......
...@@ -2899,18 +2899,12 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -2899,18 +2899,12 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
ia_valid |= ATTR_MTIME | ATTR_CTIME; ia_valid |= ATTR_MTIME | ATTR_CTIME;
} }
} }
if (ia_valid & ATTR_ATIME) { if (ia_valid & ATTR_ATIME)
vi->i_atime = timestamp_truncate(attr->ia_atime, vi->i_atime = attr->ia_atime;
vi); if (ia_valid & ATTR_MTIME)
} vi->i_mtime = attr->ia_mtime;
if (ia_valid & ATTR_MTIME) { if (ia_valid & ATTR_CTIME)
vi->i_mtime = timestamp_truncate(attr->ia_mtime, vi->i_ctime = attr->ia_ctime;
vi);
}
if (ia_valid & ATTR_CTIME) {
vi->i_ctime = timestamp_truncate(attr->ia_ctime,
vi);
}
mark_inode_dirty(vi); mark_inode_dirty(vi);
out: out:
return err; return err;
......
...@@ -1080,18 +1080,12 @@ static void do_attr_changes(struct inode *inode, const struct iattr *attr) ...@@ -1080,18 +1080,12 @@ static void do_attr_changes(struct inode *inode, const struct iattr *attr)
inode->i_uid = attr->ia_uid; inode->i_uid = attr->ia_uid;
if (attr->ia_valid & ATTR_GID) if (attr->ia_valid & ATTR_GID)
inode->i_gid = attr->ia_gid; inode->i_gid = attr->ia_gid;
if (attr->ia_valid & ATTR_ATIME) { if (attr->ia_valid & ATTR_ATIME)
inode->i_atime = timestamp_truncate(attr->ia_atime, inode->i_atime = attr->ia_atime;
inode); if (attr->ia_valid & ATTR_MTIME)
} inode->i_mtime = attr->ia_mtime;
if (attr->ia_valid & ATTR_MTIME) { if (attr->ia_valid & ATTR_CTIME)
inode->i_mtime = timestamp_truncate(attr->ia_mtime, inode->i_ctime = attr->ia_ctime;
inode);
}
if (attr->ia_valid & ATTR_CTIME) {
inode->i_ctime = timestamp_truncate(attr->ia_ctime,
inode);
}
if (attr->ia_valid & ATTR_MODE) { if (attr->ia_valid & ATTR_MODE) {
umode_t mode = attr->ia_mode; umode_t mode = attr->ia_mode;
......
...@@ -84,7 +84,6 @@ static int create_default_filesystem(struct ubifs_info *c) ...@@ -84,7 +84,6 @@ static int create_default_filesystem(struct ubifs_info *c)
int idx_node_size; int idx_node_size;
long long tmp64, main_bytes; long long tmp64, main_bytes;
__le64 tmp_le64; __le64 tmp_le64;
__le32 tmp_le32;
struct timespec64 ts; struct timespec64 ts;
u8 hash[UBIFS_HASH_ARR_SZ]; u8 hash[UBIFS_HASH_ARR_SZ];
u8 hash_lpt[UBIFS_HASH_ARR_SZ]; u8 hash_lpt[UBIFS_HASH_ARR_SZ];
...@@ -291,16 +290,14 @@ static int create_default_filesystem(struct ubifs_info *c) ...@@ -291,16 +290,14 @@ static int create_default_filesystem(struct ubifs_info *c)
ino->creat_sqnum = cpu_to_le64(++c->max_sqnum); ino->creat_sqnum = cpu_to_le64(++c->max_sqnum);
ino->nlink = cpu_to_le32(2); ino->nlink = cpu_to_le32(2);
ktime_get_real_ts64(&ts); ktime_get_coarse_real_ts64(&ts);
ts = timespec64_trunc(ts, DEFAULT_TIME_GRAN);
tmp_le64 = cpu_to_le64(ts.tv_sec); tmp_le64 = cpu_to_le64(ts.tv_sec);
ino->atime_sec = tmp_le64; ino->atime_sec = tmp_le64;
ino->ctime_sec = tmp_le64; ino->ctime_sec = tmp_le64;
ino->mtime_sec = tmp_le64; ino->mtime_sec = tmp_le64;
tmp_le32 = cpu_to_le32(ts.tv_nsec); ino->atime_nsec = 0;
ino->atime_nsec = tmp_le32; ino->ctime_nsec = 0;
ino->ctime_nsec = tmp_le32; ino->mtime_nsec = 0;
ino->mtime_nsec = tmp_le32;
ino->mode = cpu_to_le32(S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO); ino->mode = cpu_to_le32(S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO);
ino->size = cpu_to_le64(UBIFS_INO_NODE_SZ); ino->size = cpu_to_le64(UBIFS_INO_NODE_SZ);
......
...@@ -36,14 +36,14 @@ static int utimes_common(const struct path *path, struct timespec64 *times) ...@@ -36,14 +36,14 @@ static int utimes_common(const struct path *path, struct timespec64 *times)
if (times[0].tv_nsec == UTIME_OMIT) if (times[0].tv_nsec == UTIME_OMIT)
newattrs.ia_valid &= ~ATTR_ATIME; newattrs.ia_valid &= ~ATTR_ATIME;
else if (times[0].tv_nsec != UTIME_NOW) { else if (times[0].tv_nsec != UTIME_NOW) {
newattrs.ia_atime = timestamp_truncate(times[0], inode); newattrs.ia_atime = times[0];
newattrs.ia_valid |= ATTR_ATIME_SET; newattrs.ia_valid |= ATTR_ATIME_SET;
} }
if (times[1].tv_nsec == UTIME_OMIT) if (times[1].tv_nsec == UTIME_OMIT)
newattrs.ia_valid &= ~ATTR_MTIME; newattrs.ia_valid &= ~ATTR_MTIME;
else if (times[1].tv_nsec != UTIME_NOW) { else if (times[1].tv_nsec != UTIME_NOW) {
newattrs.ia_mtime = timestamp_truncate(times[1], inode); newattrs.ia_mtime = times[1];
newattrs.ia_valid |= ATTR_MTIME_SET; newattrs.ia_valid |= ATTR_MTIME_SET;
} }
/* /*
......
...@@ -1575,7 +1575,6 @@ static inline void i_gid_write(struct inode *inode, gid_t gid) ...@@ -1575,7 +1575,6 @@ static inline void i_gid_write(struct inode *inode, gid_t gid)
inode->i_gid = make_kgid(inode->i_sb->s_user_ns, gid); inode->i_gid = make_kgid(inode->i_sb->s_user_ns, gid);
} }
extern struct timespec64 timespec64_trunc(struct timespec64 t, unsigned gran);
extern struct timespec64 current_time(struct inode *inode); extern struct timespec64 current_time(struct inode *inode);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment