Transition vfs to 64-bit timestamps
Subsystems (2)
Hi Thomas,
This is a pull request for the series that I sent earlier. The series aims to switch vfs timestamps to use struct timespec64. Currently vfs uses struct timespec, which is not y2038 safe.
The flag patch applies cleanly. I've not seen the timestamps update logic change often. The series applies cleanly on 4.17-rc6 and linux-next tip (top commit: next-20180517).
I'm not sure how to merge this kind of a series with a flag patch. We are targeting 4.18 for this.
Let me know if you have other suggestions.
The series involves the following:
1. Add vfs helper functions for supporting struct timepec64 timestamps.
2. Cast prints of vfs timestamps to avoid warnings after the switch.
3. Simplify code using vfs timestamps so that the actual replacement becomes easy.
4. Convert vfs timestamps to use struct timespec64 using a script. This is a flag day patch.
I've tried to keep the conversions with the script simple, to aid in the reviews. I've kept all the internal filesystem data structures and function signatures the same.
Next steps:
1. Convert APIs that can handle timespec64, instead of converting timestamps at the boundaries.
2. Update internal data structures to avoid timestamp conversions.
Signature · 122 lines
Changes from v1:
* Fix the pointer bug in the udf patch.
* Include Kees's patch for pstore.
* Fix hostfs regression found by kbuild bot.
The following changes since commit 771c577c23bac90597c685971d7297ea00f99d11:
Linux 4.17-rc6 (2018-05-20 15:31:38 -0700)
are available in the Git repository at:
https://github.com/deepa-hub/vfs vfs_timespec64
for you to fetch changes up to 213ae530f442029284ab6041812df0571ebd9da7:
vfs: change inode times to use struct timespec64 (2018-05-25 15:31:14 -0700)
----------------------------------------------------------------
Deepa Dinamani (6):
fs: add timespec64_truncate()
lustre: Use long long type to print inode time
ceph: make inode time prints to be long long
fs: nfs: get rid of memcpys for inode times
udf: Simplify calls to udf_disk_stamp_to_time
vfs: change inode times to use struct timespec64
Kees Cook (1):
pstore: Convert internal records to timespec64
drivers/firmware/efi/efi-pstore.c | 27 ++++----
drivers/staging/lustre/lustre/llite/llite_lib.c | 12 ++--
drivers/staging/lustre/lustre/llite/namei.c | 5 +-
drivers/staging/lustre/lustre/lmv/lmv_obd.c | 7 +-
drivers/staging/lustre/lustre/mdc/mdc_reint.c | 6 +-
drivers/staging/lustre/lustre/obdclass/obdo.c | 6 +-
drivers/tty/tty_io.c | 15 ++++-
drivers/usb/gadget/function/f_fs.c | 2 +-
fs/adfs/inode.c | 7 +-
fs/afs/fsclient.c | 2 +-
fs/attr.c | 14 ++--
fs/bad_inode.c | 2 +-
fs/btrfs/file.c | 6 +-
fs/btrfs/inode.c | 8 +--
fs/btrfs/ioctl.c | 4 +-
fs/btrfs/root-tree.c | 4 +-
fs/btrfs/transaction.c | 2 +-
fs/ceph/addr.c | 12 ++--
fs/ceph/cache.c | 4 +-
fs/ceph/caps.c | 6 +-
fs/ceph/file.c | 6 +-
fs/ceph/inode.c | 86 +++++++++++++------------
fs/ceph/mds_client.c | 7 +-
fs/ceph/snap.c | 6 +-
fs/cifs/cache.c | 4 +-
fs/cifs/fscache.c | 8 +--
fs/cifs/inode.c | 26 ++++----
fs/coda/coda_linux.c | 12 ++--
fs/configfs/inode.c | 12 ++--
fs/cramfs/inode.c | 2 +-
fs/ext4/ext4.h | 34 ++++++----
fs/ext4/ialloc.c | 4 +-
fs/ext4/namei.c | 2 +-
fs/f2fs/f2fs.h | 10 ++-
fs/f2fs/file.c | 12 ++--
fs/f2fs/inode.c | 12 ++--
fs/f2fs/namei.c | 4 +-
fs/fat/inode.c | 20 ++++--
fs/fat/namei_msdos.c | 21 +++---
fs/fat/namei_vfat.c | 22 ++++---
fs/fuse/inode.c | 2 +-
fs/gfs2/dir.c | 6 +-
fs/gfs2/glops.c | 4 +-
fs/hfs/inode.c | 4 +-
fs/hfsplus/inode.c | 12 ++--
fs/hostfs/hostfs_kern.c | 12 ++--
fs/inode.c | 58 ++++++++++++-----
fs/jffs2/dir.c | 18 +++---
fs/jffs2/file.c | 2 +-
fs/jffs2/fs.c | 12 ++--
fs/kernfs/dir.c | 4 +-
fs/kernfs/inode.c | 8 +--
fs/locks.c | 2 +-
fs/nfs/callback_proc.c | 4 +-
fs/nfs/fscache-index.c | 4 +-
fs/nfs/fscache.c | 12 ++--
fs/nfs/inode.c | 39 ++++++-----
fs/nfs/nfs2xdr.c | 25 ++++---
fs/nfs/nfs3xdr.c | 8 ++-
fs/nfs/nfs4xdr.c | 7 +-
fs/nfsd/blocklayout.c | 8 ++-
fs/nfsd/nfs3xdr.c | 14 ++--
fs/nfsd/nfs4xdr.c | 7 +-
fs/nfsd/nfsxdr.c | 2 +-
fs/ntfs/inode.c | 30 ++++-----
fs/ocfs2/dlmglue.c | 20 ++++--
fs/ocfs2/file.c | 6 +-
fs/orangefs/inode.c | 2 +-
fs/orangefs/orangefs-kernel.h | 2 +-
fs/overlayfs/inode.c | 2 +-
fs/overlayfs/overlayfs.h | 2 +-
fs/proc/uptime.c | 2 +-
fs/pstore/platform.c | 2 +-
fs/pstore/ram.c | 21 ++++--
fs/reiserfs/namei.c | 2 +-
fs/reiserfs/xattr.c | 4 +-
fs/ubifs/dir.c | 4 +-
fs/ubifs/file.c | 23 +++----
fs/ubifs/ubifs.h | 2 +-
fs/udf/ialloc.c | 4 +-
fs/udf/inode.c | 59 +++++++++--------
fs/udf/super.c | 17 +++--
fs/udf/udfdecl.h | 4 +-
fs/udf/udftime.c | 9 +--
fs/xfs/xfs_inode.c | 2 +-
fs/xfs/xfs_iops.c | 2 +-
fs/xfs/xfs_trans_inode.c | 2 +-
include/linux/fs.h | 24 +++----
include/linux/pstore.h | 2 +-
include/linux/stat.h | 8 +--
90 files changed, 558 insertions(+), 434 deletions(-)
--
2.17.0Quoted 3 lines · Deepa Dinamani
The flag patch applies cleanly. I've not seen the timestamps update logic change often. The series applies cleanly on 4.17-rc6 and linux-next tip (top commit: next-20180517).
It just stopped applying cleanly against the latest linux-next tree, due to a conflict against two patches from the overlayfs-next tree:
b2a285e1dc5d ("Revert "vfs: update ovl inode before relatime check"") 681b186a012d ("Revert "ovl: fix relatime for directories"")
After the conflict resolution below, it works fine again. Not sure what the best merge strategy would be, at least the bit in ovl_file_accessed() isn't obvious enough.
Arnd
fs/inode.c +0 -0
@@@ -1635,10 -1681,11 +1635,10 @@@ static int update_time(struct inode *in* This function automatically handles read only file systems and media, * as well as the "noatime" flag and inode specific "noatime" markers. */ -bool __atime_needs_update(const struct path *path, struct inode *inode, - bool rcu) +bool atime_needs_update(const struct path *path, struct inode *inode) { struct vfsmount *mnt = path->mnt; -struct timespec now; +struct timespec64 now;
if (inode->i_flags & S_NOATIME)
return false;@@@ -1661,10 -1708,10 +1661,14 @@@
now = current_time(inode);
- if (!relatime_need_update(mnt, inode, now))
- if (!relatime_need_update(path, inode,timespec64_to_timespec(now), rcu))
++ if (!relatime_need_update(mnt, inode, timespec64_to_timespec(now)))
return false;
- if (timespec_equal(&inode->i_atime, &now))
+ if (timespec64_equal(&inode->i_atime, &now))
return false;
return true;
@@@ -1674,9 -1721,9 +1678,9 @@@ void touch_atime(const struct path *pat
{
struct vfsmount *mnt = path->mnt;
struct inode *inode = d_inode(path->dentry);- struct timespec now;
+ struct timespec64 now;
- if (!__atime_needs_update(path, inode, false))
+ if (!atime_needs_update(path, inode))
return;
if (!sb_start_write_trylock(inode->i_sb))fs/overlayfs/inode.c +0 -0
@@ -169,8 +169,8 @@ static void ovl_file_accessed(struct file *file)if (!upperinode)return ; - if ((!timespec_equal(&inode->i_mtime, &upperinode->i_mtime) || - !timespec_equal(&inode->i_ctime, &upperinode->i_ctime))) { + if ((!timespec64_equal(&inode->i_mtime, &upperinode->i_mtime) || + !timespec64_equal(&inode->i_ctime, &upperinode->i_ctime))) { inode->i_mtime = upperinode->i_mtime;
inode->i_ctime = upperinode->i_ctime;
}
@@@ -439,7 -384,39 +439,7 @@@ struct posix_acl *ovl_get_acl(struct in
return acl;}
- int ovl_update_time(struct inode *inode, struct timespec *ts, int flags) -static bool ovl_open_need_copy_up(struct dentry *dentry, int flags) -{
- /* Copy up of disconnected dentry does not set upper alias */
- if (ovl_dentry_upper(dentry) &&
- (ovl_dentry_has_upper_alias(dentry) ||
- (dentry->d_flags & DCACHE_DISCONNECTED)))
- return false;
-
- if (special_file(d_inode(dentry)->i_mode))
- return false;
-
- if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC))
- return false;
-
- return true;
-}
-
-int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags) -{
- int err = 0;
-
- if (ovl_open_need_copy_up(dentry, file_flags)) {
- err = ovl_want_write(dentry);
- if (!err) {
- err = ovl_copy_up_flags(dentry, file_flags);
- ovl_drop_write(dentry);
- }
- }
-
- return err;
-}
-
+ int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags)
{
if (flags & S_ATIME) {
struct ovl_fs *ofs = inode->i_sb->s_fs_info;fs/overlayfs/overlayfs.h +0 -0
@@@ -356,18 -330,10 +356,18 @@@ int ovl_xattr_get(struct dentry *dentry void *value, size_t size);ssize_t ovl_listxattr (struct dentry *dentry,char *list,size_t size);struct posix_acl *ovl_get_acl (struct inode *inode,int type); -int ovl_update_time (struct inode *inode,struct timespec *ts,int flags); -int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); +int ovl_update_time (struct inode *inode,struct timespec64 *ts,int flags);bool ovl_is_private_xattr (const char *name);
There will be more conflicts if the lustre deletion patch gets into linux-next.
Regenerating the pull request close to when someone is ready to take it would be the best scenario.
Are there any other suggestions as to how to merge a flag day patch like this?
Thanks,
-Deepa
Quoted 131 lines · Arnd Bergmann
Quoted 3 lines · Deepa Dinamani
The flag patch applies cleanly. I've not seen the timestamps update logic change often. The series applies cleanly on 4.17-rc6 and linux-next tip (top commit: next-20180517).
It just stopped applying cleanly against the latest linux-next tree, due to a conflict against two patches from the overlayfs-next tree:
b2a285e1dc5d("Revert "vfs: update ovl inode before relatime check"")681b186a012d("Revert "ovl: fix relatime for directories"")After the conflict resolution below, it works fine again. Not sure what the best merge strategy would be, at least the bit in
ovl_file_accessed()isn't obvious enough.Arnd
fs/inode.c +1
-2@@@ -1635,10 -1681,11 +1635,10 @@@ static int update_time(struct inode *in* This function automatically handles read only file systems and media, * as well as the "noatime" flag and inode specific "noatime" markers. */ -bool __atime_needs_update(const struct path *path, struct inode *inode, - bool rcu) +bool atime_needs_update(const struct path *path, struct inode *inode) { struct vfsmount *mnt = path->mnt; -struct timespec now; +struct timespec64 now;if (inode->i_flags &S_NOATIME )return false;@@@ -1661,10 -1708,10 +1661,14 @@@ now =current_time (inode); - if (!relatime_need_update(mnt, inode, now)) - if (!relatime_need_update(path, inode,
timespec64_to_timespec(now), rcu))
++ if (!relatime_need_update(mnt, inode,timespec64_to_timespec(now)))return false;fs/inode.c +2
-2-if (timespec_equal (&inode->i_atime, &now)) +if (timespec64_equal (&inode->i_atime, &now))return false;return true;@@@ -1674,9 -1721,9 +1678,9 @@@ void touch_atime(const struct path *pat {struct vfsmount *mnt = path->mnt;struct inode *inode =d_inode (path->dentry); -struct timespec now; +struct timespec64 now; - if (!__atime_needs_update(path, inode, false)) + if (!atime_needs_update(path, inode)) return;if (!sb_start_write_trylock (inode->i_sb))fs/overlayfs/inode.c +0
-0@@ -169,8 +169,8 @@ static void ovl_file_accessed(struct file *file)if (!upperinode)return ; - if ((!timespec_equal(&inode->i_mtime, &upperinode->i_mtime) || - !timespec_equal(&inode->i_ctime, &upperinode->i_ctime))) { + if ((!timespec64_equal(&inode->i_mtime, &upperinode->i_mtime) || + !timespec64_equal(&inode->i_ctime, &upperinode->i_ctime))) { inode->i_mtime = upperinode->i_mtime;inode->i_ctime = upperinode->i_ctime; }fs/overlayfs/inode.c +1
-1@@@ -439,7 -384,39 +439,7 @@@ struct posix_acl *ovl_get_acl(struct inreturn acl; } - int ovl_update_time(struct inode *inode, struct timespec *ts, int flags) -static bool ovl_open_need_copy_up(struct dentry *dentry, int flags) -{ -/* Copy up of disconnected dentry does not set upper alias */ - if (ovl_dentry_upper(dentry) && - (ovl_dentry_has_upper_alias (dentry) || - (dentry->d_flags &DCACHE_DISCONNECTED ))) - return false; - - if (special_file(d_inode(dentry)->i_mode)) - return false; - - if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC)) - return false; - - return true; -} - -int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags) -{ - int err = 0; - - if (ovl_open_need_copy_up(dentry, file_flags)) { - err =ovl_want_write (dentry); - if (!err) { - err =ovl_copy_up_flags (dentry, file_flags); -ovl_drop_write (dentry); - } - } - - return err; -} - + int ovl_update_time(struct inode *inode, struct timespec64 *ts, int flags) { if (flags & S_ATIME) { struct ovl_fs *ofs = inode->i_sb->s_fs_info;fs/overlayfs/overlayfs.h +1
-1@@@ -356,18 -330,10 +356,18 @@@ int ovl_xattr_get(struct dentry *dentry void *value, size_t size);ssize_t ovl_listxattr (struct dentry *dentry,char *list,size_t size);struct posix_acl *ovl_get_acl (struct inode *inode,int type); -int ovl_update_time (struct inode *inode,struct timespec *ts,int flags); -int ovl_open_maybe_copy_up(struct dentry *dentry, unsigned int file_flags); +int ovl_update_time (struct inode *inode,struct timespec64 *ts,int flags);bool ovl_is_private_xattr (const char *name);