Introduction
This patch series is aimed at getting rid of CURRENT_TIME and CURRENT_TIME_SEC macros.
The idea for the series evolved from my discussions with Arnd Bergmann.
This was originally part of the RFC series[2]: https://lkml.org/lkml/2016/1/7/20 (under discussion).
Dave Chinner suggested moving bug fixes out of the feature series to keep the original series simple.
There are 354 occurrences of the the above macros in the kernel. The series will be divided into 4 or 5 parts to keep the parts manageable and so that each part could be reviewed and merged independently. This is part 2 of the series.
Motivation
The macros: CURRENT_TIME and CURRENT_TIME_SEC are primarily used for filesystem timestamps. But, they are not accurate as they do not perform clamping according to filesystem timestamps ranges, nor do they truncate the nanoseconds value to the granularity as required by the filesystem.
The series is also viewed as an ancillary to another upcoming series[2] that attempts to transition file system timestamps to use 64 bit time to make these y2038 safe.
There will also be another series[3] to add range checks and clamping to filesystem time functions that are meant to substitute the above macros.
Solution
CURRENT_TIME macro has an equivalent function:
struct timespec current_fs_time(struct super_block *sb)
These will be the changes to the above function: 1. Function will return the type y2038 safe timespec64 in [2]. 2. Function will use y2038 safe 64 bit functions in [2]. 3. Function will be extended to perform range checks in [3].
A new function will be added to substitute for CURRENT_TIME_SEC macro in the current series:
struct timespec current_fs_time_sec(struct super_block *sb)
These will be the changes to the above function: 1. Function will return the type y2038 safe timespec64 in [2]. 2. Function will use y2038 safe 64 bit functions in [2]. 3. Function will be extended to perform range checks in [3].
Any use of these macros outside of filesystem timestamps will be replaced by function calls to appropriate time functions.
Deepa Dinamani (8): fs: debugfs: Replace CURRENT_TIME by current_fs_time() fs: logfs: Replace CURRENT_TIME by current_fs_time() fs: devpts: Replace CURRENT_TIME by current_fs_time() fs: configfs: Replace CURRENT_TIME by current_fs_time() fs: proc: Replace CURRENT_TIME by current_fs_time() fs: ramfs: Replace CURRENT_TIME by current_fs_time() fs: kernfs: Replace CURRENT_TIME by current_fs_time() net: sunrpc: Replace CURRENT_TIME by current_fs_time()
fs/configfs/inode.c | 8 +++++--- fs/debugfs/inode.c | 3 ++- fs/devpts/inode.c | 9 ++++++--- fs/kernfs/dir.c | 8 +++++--- fs/kernfs/inode.c | 15 ++++++++++----- fs/logfs/dir.c | 11 +++++++---- fs/logfs/file.c | 2 +- fs/logfs/inode.c | 3 +-- fs/logfs/readwrite.c | 7 ++++--- fs/proc/base.c | 3 ++- fs/proc/inode.c | 6 ++++-- fs/proc/proc_sysctl.c | 3 ++- fs/proc/self.c | 3 ++- fs/proc/thread_self.c | 3 ++- fs/ramfs/inode.c | 13 ++++++++----- net/sunrpc/rpc_pipe.c | 4 +++- 16 files changed, 64 insertions(+), 37 deletions(-)
CURRENT_TIME macro is not appropriate for filesystems as it doesn't use the right granularity for filesystem timestamps. Use current_fs_time() instead.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/debugfs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index bece948..cc6aa2a 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -39,7 +39,8 @@ static struct inode *debugfs_get_inode(struct super_block *sb) struct inode *inode = new_inode(sb); if (inode) { inode->i_ino = get_next_ino(); - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_atime = inode->i_mtime = + inode->i_ctime = current_fs_time(sb); } return inode; }
CURRENT_TIME macro is not appropriate for filesystems as it doesn't use the right granularity for filesystem timestamps. Use current_fs_time() instead.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: Joern Engel joern@logfs.org Cc: Prasad Joshi prasadjoshi.linux@gmail.com Cc: logfs@logfs.org --- fs/logfs/dir.c | 11 +++++++---- fs/logfs/file.c | 2 +- fs/logfs/inode.c | 3 +-- fs/logfs/readwrite.c | 7 ++++--- 4 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 542468e..3b5f279 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c @@ -212,7 +212,8 @@ static void abort_transaction(struct inode *inode, struct logfs_transaction *ta)
static int logfs_unlink(struct inode *dir, struct dentry *dentry) { - struct logfs_super *super = logfs_super(dir->i_sb); + struct super_block *sb = dir->i_sb; + struct logfs_super *super = logfs_super(sb); struct inode *inode = d_inode(dentry); struct logfs_transaction *ta; struct page *page; @@ -226,7 +227,8 @@ static int logfs_unlink(struct inode *dir, struct dentry *dentry) ta->state = UNLINK_1; ta->ino = inode->i_ino;
- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; + inode->i_ctime = dir->i_ctime = + dir->i_mtime = current_fs_time(sb);
page = logfs_get_dd_page(dir, dentry); if (!page) { @@ -540,7 +542,8 @@ static int logfs_link(struct dentry *old_dentry, struct inode *dir, { struct inode *inode = d_inode(old_dentry);
- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; + inode->i_ctime = dir->i_ctime = + dir->i_mtime = current_fs_time(dir->i_sb); ihold(inode); inc_nlink(inode); mark_inode_dirty_sync(inode); @@ -573,7 +576,7 @@ static int logfs_delete_dd(struct inode *dir, loff_t pos) * (crc-protected) journal. */ BUG_ON(beyond_eof(dir, pos)); - dir->i_ctime = dir->i_mtime = CURRENT_TIME; + dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb); log_dir(" Delete dentry (%lx, %llx)\n", dir->i_ino, pos); return logfs_delete(dir, pos, NULL); } diff --git a/fs/logfs/file.c b/fs/logfs/file.c index 61eaeb1..339ae40 100644 --- a/fs/logfs/file.c +++ b/fs/logfs/file.c @@ -211,7 +211,7 @@ long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) li->li_flags = flags; inode_unlock(inode);
- inode->i_ctime = CURRENT_TIME; + inode->i_ctime = current_fs_time(inode->i_sb); mark_inode_dirty_sync(inode); return 0;
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index db9cfc5..65eaf09 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c @@ -213,8 +213,7 @@ static void logfs_init_inode(struct super_block *sb, struct inode *inode) i_gid_write(inode, 0); inode->i_size = 0; inode->i_blocks = 0; - inode->i_ctime = CURRENT_TIME; - inode->i_mtime = CURRENT_TIME; + inode->i_ctime = inode->i_mtime = current_fs_time(sb); li->li_refcount = 1; INIT_LIST_HEAD(&li->li_freeing_list);
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 20973c9..361a2d0 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c @@ -1539,14 +1539,15 @@ static int grow_inode(struct inode *inode, u64 bix, level_t level)
static int __logfs_write_buf(struct inode *inode, struct page *page, long flags) { - struct logfs_super *super = logfs_super(inode->i_sb); + struct super_block *sb = inode->i_sb; + struct logfs_super *super = logfs_super(sb); pgoff_t index = page->index; u64 bix; level_t level; int err;
flags |= WF_WRITE | WF_DELETE; - inode->i_ctime = inode->i_mtime = CURRENT_TIME; + inode->i_ctime = inode->i_mtime = current_fs_time(sb);
logfs_unpack_index(index, &bix, &level); if (logfs_block(page) && logfs_block(page)->reserved_bytes) @@ -1578,7 +1579,7 @@ static int __logfs_delete(struct inode *inode, struct page *page) long flags = WF_DELETE; int err;
- inode->i_ctime = inode->i_mtime = CURRENT_TIME; + inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
if (page->index < I0_BLOCKS) return logfs_write_direct(inode, page, flags);
CURRENT_TIME macro is not appropriate for filesystems as it doesn't use the right granularity for filesystem timestamps. Use current_fs_time() instead.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: Peter Hurley peter@hurleysoftware.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Josh Triplett josh@joshtriplett.org Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Andrew Morton akpm@linux-foundation.org --- fs/devpts/inode.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 655f21f..4eb338d4 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -280,7 +280,8 @@ static int mknod_ptmx(struct super_block *sb) }
inode->i_ino = 2; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_atime = + inode->i_ctime = current_fs_time(sb);
mode = S_IFCHR|opts->ptmxmode; init_special_inode(inode, mode, MKDEV(TTYAUX_MAJOR, 2)); @@ -392,7 +393,8 @@ devpts_fill_super(struct super_block *s, void *data, int silent) if (!inode) goto fail; inode->i_ino = 1; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_atime = + inode->i_ctime = current_fs_time(s); inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; inode->i_op = &simple_dir_inode_operations; inode->i_fop = &simple_dir_operations; @@ -629,7 +631,8 @@ struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index, inode->i_ino = index + 3; inode->i_uid = opts->setuid ? opts->uid : current_fsuid(); inode->i_gid = opts->setgid ? opts->gid : current_fsgid(); - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_atime = + inode->i_ctime = current_fs_time(sb); init_special_inode(inode, S_IFCHR|opts->mode, device); inode->i_private = priv;
CURRENT_TIME macro is not appropriate for filesystems as it doesn't use the right granularity for filesystem timestamps. Use current_fs_time() instead.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: Joel Becker jlbec@evilplan.org Cc: stoph Hellwig hch@lst.de --- fs/configfs/inode.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index cee087d..5f24ad3 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c @@ -75,7 +75,8 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) sd_iattr->ia_mode = sd->s_mode; sd_iattr->ia_uid = GLOBAL_ROOT_UID; sd_iattr->ia_gid = GLOBAL_ROOT_GID; - sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; + sd_iattr->ia_atime = sd_iattr->ia_mtime = + sd_iattr->ia_ctime = current_fs_time(inode->i_sb); sd->s_iattr = sd_iattr; } /* attributes were changed atleast once in past */ @@ -111,7 +112,8 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) static inline void set_default_inode_attr(struct inode * inode, umode_t mode) { inode->i_mode = mode; - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_atime = inode->i_mtime = + inode->i_ctime = current_fs_time(inode->i_sb); }
static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) @@ -195,7 +197,7 @@ int configfs_create(struct dentry * dentry, umode_t mode, void (*init)(struct in return -ENOMEM;
p_inode = d_inode(dentry->d_parent); - p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; + p_inode->i_mtime = p_inode->i_ctime = current_fs_time(p_inode->i_sb); configfs_set_inode_lock_class(sd, inode);
init(inode);
Acked-by: Joel Becker jlbec@evilplan.org
On Mon, Feb 22, 2016 at 07:17:50AM -0800, Deepa Dinamani wrote:
CURRENT_TIME macro is not appropriate for filesystems as it doesn't use the right granularity for filesystem timestamps. Use current_fs_time() instead.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: Joel Becker jlbec@evilplan.org Cc: stoph Hellwig hch@lst.de
fs/configfs/inode.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index cee087d..5f24ad3 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c @@ -75,7 +75,8 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) sd_iattr->ia_mode = sd->s_mode; sd_iattr->ia_uid = GLOBAL_ROOT_UID; sd_iattr->ia_gid = GLOBAL_ROOT_GID;
sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME;
sd_iattr->ia_atime = sd_iattr->ia_mtime =
sd->s_iattr = sd_iattr; } /* attributes were changed atleast once in past */sd_iattr->ia_ctime = current_fs_time(inode->i_sb);
@@ -111,7 +112,8 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr) static inline void set_default_inode_attr(struct inode * inode, umode_t mode) { inode->i_mode = mode;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- inode->i_atime = inode->i_mtime =
inode->i_ctime = current_fs_time(inode->i_sb);
} static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) @@ -195,7 +197,7 @@ int configfs_create(struct dentry * dentry, umode_t mode, void (*init)(struct in return -ENOMEM; p_inode = d_inode(dentry->d_parent);
- p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
- p_inode->i_mtime = p_inode->i_ctime = current_fs_time(p_inode->i_sb); configfs_set_inode_lock_class(sd, inode);
init(inode); -- 1.9.1
--
Thanks Deepa,
I've added this to the configfs tree.
CURRENT_TIME macro is not appropriate for filesystems as it doesn't use the right granularity for filesystem timestamps. Use current_fs_time() instead.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Michal Hocko mhocko@suse.com Cc: Konstantin Khlebnikov koct9i@gmail.com Cc: Naoya Horiguchi n-horiguchi@ah.jp.nec.com --- fs/proc/base.c | 3 ++- fs/proc/inode.c | 6 ++++-- fs/proc/proc_sysctl.c | 3 ++- fs/proc/self.c | 3 ++- fs/proc/thread_self.c | 3 ++- 5 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c index 4f764c2..bb18566 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1664,7 +1664,8 @@ struct inode *proc_pid_make_inode(struct super_block * sb, struct task_struct *t /* Common stuff */ ei = PROC_I(inode); inode->i_ino = get_next_ino(); - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_atime = + inode->i_ctime = current_fs_time(sb); inode->i_op = &proc_def_inode_operations;
/* diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 42305dd..8b902c4 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c @@ -68,7 +68,8 @@ static struct inode *proc_alloc_inode(struct super_block *sb) ei->sysctl_entry = NULL; ei->ns_ops = NULL; inode = &ei->vfs_inode; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_atime = + inode->i_ctime = current_fs_time(sb); return inode; }
@@ -421,7 +422,8 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
if (inode) { inode->i_ino = de->low_ino; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_atime = + inode->i_ctime = current_fs_time(sb); PROC_I(inode)->pde = de;
if (is_empty_pde(de)) { diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index fe5b6e6..7153daf 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -444,7 +444,8 @@ static struct inode *proc_sys_make_inode(struct super_block *sb, ei->sysctl = head; ei->sysctl_entry = table;
- inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_atime = + inode->i_ctime = current_fs_time(sb); inode->i_mode = table->mode; if (!S_ISDIR(table->mode)) { inode->i_mode |= S_IFREG; diff --git a/fs/proc/self.c b/fs/proc/self.c index b6a8d35..952ce1c 100644 --- a/fs/proc/self.c +++ b/fs/proc/self.c @@ -56,7 +56,8 @@ int proc_setup_self(struct super_block *s) struct inode *inode = new_inode_pseudo(s); if (inode) { inode->i_ino = self_inum; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_atime = + inode->i_ctime = current_fs_time(s); inode->i_mode = S_IFLNK | S_IRWXUGO; inode->i_uid = GLOBAL_ROOT_UID; inode->i_gid = GLOBAL_ROOT_GID; diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c index e58a31e..ef08485 100644 --- a/fs/proc/thread_self.c +++ b/fs/proc/thread_self.c @@ -58,7 +58,8 @@ int proc_setup_thread_self(struct super_block *s) struct inode *inode = new_inode_pseudo(s); if (inode) { inode->i_ino = thread_self_inum; - inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; + inode->i_mtime = inode->i_atime = + inode->i_ctime = current_fs_time(s); inode->i_mode = S_IFLNK | S_IRWXUGO; inode->i_uid = GLOBAL_ROOT_UID; inode->i_gid = GLOBAL_ROOT_GID;
CURRENT_TIME macro is not appropriate for filesystems as it doesn't use the right granularity for filesystem timestamps. Use current_fs_time() instead.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: Andrew Morton akpm@linux-foundation.org Cc: David Howells dhowells@redhat.com Cc: Michal Hocko mhocko@suse.com --- fs/ramfs/inode.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 38981b0..ce69aec 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -61,7 +61,8 @@ struct inode *ramfs_get_inode(struct super_block *sb, inode->i_mapping->a_ops = &ramfs_aops; mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); mapping_set_unevictable(inode->i_mapping); - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_atime = inode->i_mtime = + inode->i_ctime = current_fs_time(sb); switch (mode & S_IFMT) { default: init_special_inode(inode, mode, dev); @@ -93,14 +94,15 @@ struct inode *ramfs_get_inode(struct super_block *sb, static int ramfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { - struct inode * inode = ramfs_get_inode(dir->i_sb, dir, mode, dev); + struct super_block *sb = dir->i_sb; + struct inode *inode = ramfs_get_inode(sb, dir, mode, dev); int error = -ENOSPC;
if (inode) { d_instantiate(dentry, inode); dget(dentry); /* Extra count - pin the dentry in core */ error = 0; - dir->i_mtime = dir->i_ctime = CURRENT_TIME; + dir->i_mtime = dir->i_ctime = current_fs_time(sb); } return error; } @@ -120,17 +122,18 @@ static int ramfs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
static int ramfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) { + struct super_block *sb = dir->i_sb; struct inode *inode; int error = -ENOSPC;
- inode = ramfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0); + inode = ramfs_get_inode(sb, dir, S_IFLNK|S_IRWXUGO, 0); if (inode) { int l = strlen(symname)+1; error = page_symlink(inode, symname, l); if (!error) { d_instantiate(dentry, inode); dget(dentry); - dir->i_mtime = dir->i_ctime = CURRENT_TIME; + dir->i_mtime = dir->i_ctime = current_fs_time(sb); } else iput(inode); }
This is in preparation for the series that transitions filesystem timestamps to use 64 bit time and hence make them y2038 safe.
CURRENT_TIME macro will be deleted before merging the aforementioned series.
Use current_fs_time() instead of CURRENT_TIME for inode timestamps.
struct kernfs_node is associated with a sysfs file/ directory. Truncate the values to appropriate time granularity when writing to inode timestamps of the files.
ktime_get_real_ts() is used to obtain times for struct kernfs_iattrs. Since these times are later assigned to inode times using timespec_truncate() for all filesystem based operations, we can save the supers list traversal time here by using ktime_get_real_ts() directly.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/kernfs/dir.c | 8 +++++--- fs/kernfs/inode.c | 15 ++++++++++----- 2 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 118d033..939bd11 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -624,7 +624,8 @@ int kernfs_add_one(struct kernfs_node *kn) ps_iattr = parent->iattr; if (ps_iattr) { struct iattr *ps_iattrs = &ps_iattr->ia_iattr; - ps_iattrs->ia_ctime = ps_iattrs->ia_mtime = CURRENT_TIME; + ktime_get_real_ts(&ps_iattrs->ia_ctime); + ps_iattrs->ia_mtime = ps_iattrs->ia_ctime; }
mutex_unlock(&kernfs_mutex); @@ -1150,8 +1151,9 @@ static void __kernfs_remove(struct kernfs_node *kn)
/* update timestamps on the parent */ if (ps_iattr) { - ps_iattr->ia_iattr.ia_ctime = CURRENT_TIME; - ps_iattr->ia_iattr.ia_mtime = CURRENT_TIME; + ktime_get_real_ts(&ps_iattr->ia_iattr.ia_ctime); + ps_iattr->ia_iattr.ia_mtime = + ps_iattr->ia_iattr.ia_ctime; }
kernfs_put(pos); diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 16405ae..1ac1dba 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -54,7 +54,10 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) iattrs->ia_mode = kn->mode; iattrs->ia_uid = GLOBAL_ROOT_UID; iattrs->ia_gid = GLOBAL_ROOT_GID; - iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME; + + ktime_get_real_ts(&iattrs->ia_atime); + iattrs->ia_mtime = iattrs->ia_atime; + iattrs->ia_ctime = iattrs->ia_atime;
simple_xattrs_init(&kn->iattr->xattrs); out_unlock: @@ -236,16 +239,18 @@ ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) static inline void set_default_inode_attr(struct inode *inode, umode_t mode) { inode->i_mode = mode; - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_atime = inode->i_mtime = + inode->i_ctime = current_fs_time(inode->i_sb); }
static inline void set_inode_attr(struct inode *inode, struct iattr *iattr) { + struct super_block *sb = inode->i_sb; inode->i_uid = iattr->ia_uid; inode->i_gid = iattr->ia_gid; - inode->i_atime = iattr->ia_atime; - inode->i_mtime = iattr->ia_mtime; - inode->i_ctime = iattr->ia_ctime; + inode->i_atime = timespec_trunc(iattr->ia_atime, sb->s_time_gran); + inode->i_mtime = timespec_trunc(iattr->ia_mtime, sb->s_time_gran); + inode->i_ctime = timespec_trunc(iattr->ia_ctime, sb->s_time_gran); }
static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
CURRENT_TIME macro is not appropriate for filesystems as it doesn't use the right granularity for filesystem timestamps. Use current_fs_time() instead.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: "J. Bruce Fields" bfields@fieldses.org Cc: Jeff Layton jlayton@poochiereds.net Cc: Trond Myklebust trond.myklebust@primarydata.com Cc: Anna Schumaker anna.schumaker@netapp.com Cc: "David S. Miller" davem@davemloft.net Cc: linux-nfs@vger.kernel.org Cc: netdev@vger.kernel.org --- net/sunrpc/rpc_pipe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 31789ef..bab3187 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -477,7 +477,9 @@ rpc_get_inode(struct super_block *sb, umode_t mode) return NULL; inode->i_ino = get_next_ino(); inode->i_mode = mode; - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_atime = current_fs_time(sb); + inode->i_mtime = inode->i_atime; + inode->i_ctime = inode->i_atime; switch (mode & S_IFMT) { case S_IFDIR: inode->i_fop = &simple_dir_operations;
On Mon, Feb 22, 2016 at 10:17 AM, Deepa Dinamani deepa.kernel@gmail.com wrote:
CURRENT_TIME macro is not appropriate for filesystems as it doesn't use the right granularity for filesystem timestamps. Use current_fs_time() instead.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: "J. Bruce Fields" bfields@fieldses.org Cc: Jeff Layton jlayton@poochiereds.net Cc: Trond Myklebust trond.myklebust@primarydata.com Cc: Anna Schumaker anna.schumaker@netapp.com Cc: "David S. Miller" davem@davemloft.net Cc: linux-nfs@vger.kernel.org Cc: netdev@vger.kernel.org
net/sunrpc/rpc_pipe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 31789ef..bab3187 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -477,7 +477,9 @@ rpc_get_inode(struct super_block *sb, umode_t mode) return NULL; inode->i_ino = get_next_ino(); inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_atime = current_fs_time(sb);
inode->i_mtime = inode->i_atime;
inode->i_ctime = inode->i_atime; switch (mode & S_IFMT) { case S_IFDIR: inode->i_fop = &simple_dir_operations;
Why would we care? This is a pseudo-fs. There is no expectation w.r.t. timestamp accuracy or resolution.
Cheers, Trond
On Mon, Feb 22, 2016 at 9:04 PM, Trond Myklebust trond.myklebust@primarydata.com wrote:
On Mon, Feb 22, 2016 at 10:17 AM, Deepa Dinamani deepa.kernel@gmail.com wrote:
CURRENT_TIME macro is not appropriate for filesystems as it doesn't use the right granularity for filesystem timestamps. Use current_fs_time() instead.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com Cc: "J. Bruce Fields" bfields@fieldses.org Cc: Jeff Layton jlayton@poochiereds.net Cc: Trond Myklebust trond.myklebust@primarydata.com Cc: Anna Schumaker anna.schumaker@netapp.com Cc: "David S. Miller" davem@davemloft.net Cc: linux-nfs@vger.kernel.org Cc: netdev@vger.kernel.org
net/sunrpc/rpc_pipe.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 31789ef..bab3187 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -477,7 +477,9 @@ rpc_get_inode(struct super_block *sb, umode_t mode) return NULL; inode->i_ino = get_next_ino(); inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_atime = current_fs_time(sb);
inode->i_mtime = inode->i_atime;
inode->i_ctime = inode->i_atime; switch (mode & S_IFMT) { case S_IFDIR: inode->i_fop = &simple_dir_operations;
Why would we care? This is a pseudo-fs. There is no expectation w.r.t. timestamp accuracy or resolution.
CURRENT_TIME is not y2038 safe. We are switching all vfs timestamps to use 64 bit time. And, deleting all references to CURRENT_TIME. So CURRENT_TIME users will be replaced by either ktime_get_* apis or current_fs_time_* apis.
There is going to be another series (based on https://lkml.org/lkml/2016/2/12/76) which switches vfs time to 64 bit.
This means [a,c,m] times in struct inode, struct attr and struct kstat will be changed to use timespec64.
Even though this is a psuedo-fs, we choose to use filesystem apis rather than ktime_get_* apis as current_fs_time_* apis will switch time data types together with vfs.
-Deepa
On Monday 22 February 2016 10:34:31 Trond Myklebust wrote:
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 31789ef..bab3187 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -477,7 +477,9 @@ rpc_get_inode(struct super_block *sb, umode_t mode) return NULL; inode->i_ino = get_next_ino(); inode->i_mode = mode;
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
inode->i_atime = current_fs_time(sb);
inode->i_mtime = inode->i_atime;
inode->i_ctime = inode->i_atime; switch (mode & S_IFMT) { case S_IFDIR: inode->i_fop = &simple_dir_operations;
Why would we care? This is a pseudo-fs. There is no expectation w.r.t. timestamp accuracy or resolution.
As Deepa said, the primary goal is to unify the interface, so we have only one place function that handles setting the time in an inode, and we want to avoid CURRENT_TIME, as that is currently used in a couple of places for things other than inode timestamps that we don't want to convert to 64-bit times at the same time.
current_fs_time() has a very small overhead compared to CURRENT_TIME, if you think it's worth avoiding that, we could introduce a current_pseudo_fs_time() function that does not take a superblock argument but is more tied to inode timestamps than CURRENT_TIME is.
Arnd