[Y2038] [RFC v2a 11/12] net: ceph: use vfs_time data type instead of timespec
The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use vfs_time aliases here to access inode times. These timestamps are passed in as arguments to functions using inode timestamps. Hence, these need to change along with vfs to support 64 bit timestamps. vfs_time helps do this transition. Signed-off-by: Deepa Dinamani--- include/linux/ceph/messenger.h | 1 + include/linux/ceph/osd_client.h | 4 ++-- net/ceph/osd_client.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/linux/ceph/messenger.h b/include/linux/ceph/messenger.h index afe886b..28bba12 100644 --- a/include/linux/ceph/messenger.h +++ b/include/linux/ceph/messenger.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include diff --git a/include/linux/ceph/osd_client.h b/include/linux/ceph/osd_client.h index 7506b48..2b6f08b 100644 --- a/include/linux/ceph/osd_client.h +++ b/include/linux/ceph/osd_client.h @@ -322,7 +322,7 @@ extern struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client * extern void ceph_osdc_build_request(struct ceph_osd_request *req, u64 off, struct ceph_snap_context *snapc, u64 snap_id, - struct timespec *mtime); + struct vfs_time *mtime); extern struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *, struct ceph_file_layout *layout, @@ -364,7 +364,7 @@ extern int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_snap_context *sc, u64 off, u64 len, u32 truncate_seq, u64 truncate_size, - struct timespec *mtime, + struct vfs_time *mtime, struct page **pages, int nr_pages); /* watch/notify events */ diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index f8f2359..1273db6 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -2401,7 +2401,7 @@ bad: */ void ceph_osdc_build_request(struct ceph_osd_request *req, u64 off, struct ceph_snap_context *snapc, u64 snap_id, - struct timespec *mtime) + struct vfs_time *mtime) { struct ceph_msg *msg = req->r_request; void *p; -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2a 10/12] fs: ceph: Replace timespec data type with vfs_time
The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use vfs_time aliases here to access inode times. Use vfs_time data type for accessing inode timestamps. This is necessary as these accesses need to switch to using 64 bit timestamps along with vfs. Signed-off-by: Deepa Dinamani--- fs/ceph/cache.c | 2 +- fs/ceph/caps.c | 6 +++--- fs/ceph/dir.c| 4 ++-- fs/ceph/file.c | 6 +++--- fs/ceph/inode.c | 32 fs/ceph/mds_client.c | 2 +- fs/ceph/mds_client.h | 2 +- fs/ceph/super.h | 8 fs/ceph/xattr.c | 2 +- 9 files changed, 32 insertions(+), 32 deletions(-) diff --git a/fs/ceph/cache.c b/fs/ceph/cache.c index a351480..4b5b2da 100644 --- a/fs/ceph/cache.c +++ b/fs/ceph/cache.c @@ -25,7 +25,7 @@ #include "cache.h" struct ceph_aux_inode { - struct timespec mtime; + struct vfs_time mtime; loff_t size; }; diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index cdbf8cf..f407819 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -990,7 +990,7 @@ static int send_cap_msg(struct ceph_mds_session *session, int caps, int wanted, int dirty, u32 seq, u64 flush_tid, u64 oldest_flush_tid, u32 issue_seq, u32 mseq, u64 size, u64 max_size, - struct timespec *mtime, struct timespec *atime, + struct vfs_time *mtime, struct vfs_time *atime, u64 time_warp_seq, kuid_t uid, kgid_t gid, umode_t mode, u64 xattr_version, @@ -1116,7 +1116,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, int held, revoking, dropping, keep; u64 seq, issue_seq, mseq, time_warp_seq, follows; u64 size, max_size; - struct timespec mtime, atime; + struct vfs_time mtime, atime; int wake = 0; umode_t mode; kuid_t uid; @@ -2764,7 +2764,7 @@ static void handle_cap_grant(struct ceph_mds_client *mdsc, int used, wanted, dirty; u64 size = le64_to_cpu(grant->size); u64 max_size = le64_to_cpu(grant->max_size); - struct timespec mtime, atime, ctime; + struct vfs_time mtime, atime, ctime; int check_caps = 0; bool wake = false; bool writeback = false; diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index fd11fb2..83e6602 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1210,7 +1210,7 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size, " rfiles: %20lld\n" " rsubdirs: %20lld\n" "rbytes:%20lld\n" - "rctime:%10ld.%09ld\n", + "rctime:%10lld.%09ld\n", ci->i_files + ci->i_subdirs, ci->i_files, ci->i_subdirs, @@ -1218,7 +1218,7 @@ static ssize_t ceph_read_dir(struct file *file, char __user *buf, size_t size, ci->i_rfiles, ci->i_rsubdirs, ci->i_rbytes, - (long)ci->i_rctime.tv_sec, + (long long)ci->i_rctime.tv_sec, (long)ci->i_rctime.tv_nsec); } diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 9b338ff..c8a6f0d 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -555,7 +555,7 @@ struct ceph_aio_request { struct list_head osd_reqs; unsigned num_reqs; atomic_t pending_reqs; - struct timespec mtime; + struct vfs_time mtime; struct ceph_cap_flush *prealloc_cf; }; @@ -783,7 +783,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, int num_pages = 0; int flags; int ret; - struct timespec mtime = current_fs_time(inode->i_sb); + struct vfs_time mtime = current_fs_time(inode->i_sb); size_t count = iov_iter_count(iter); loff_t pos = iocb->ki_pos; bool write = iov_iter_rw(iter) == WRITE; @@ -988,7 +988,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos, int flags; int check_caps = 0; int ret; - struct timespec mtime = current_fs_time(inode->i_sb); + struct vfs_time mtime = current_fs_time(inode->i_sb); size_t count = iov_iter_count(from); if (ceph_snap(file_inode(file)) != CEPH_NOSNAP) diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 63d0198..b5bce93 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -590,8 +590,8 @@ int ceph_fill_file_size(struct
[Y2038] [RFC v2a 07/12] fs: btrfs: Use vfs_time data type for btrfs_update_time()
The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use vfs_time aliases here to access inode times. This is set as a vfs callback function for inode operations. This accepts inode timestamp as an argument. And, needs to switch to 64 bit time representation along with vfs. Signed-off-by: Deepa Dinamani--- fs/btrfs/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 59c0e22..6f0417b 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5942,7 +5942,7 @@ static int btrfs_dirty_inode(struct inode *inode) * This is a copy of file_update_time. We need this so we can return error on * ENOSPC for updating the inode in the case of file write and mmap writes. */ -static int btrfs_update_time(struct inode *inode, struct timespec *now, +static int btrfs_update_time(struct inode *inode, struct vfs_time *now, int flags) { struct btrfs_root *root = BTRFS_I(inode)->root; -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2a 08/12] fs: btrfs: Change timespec data types to use vfs_time
The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use vfs_time aliases here to access inode times. The following needs to switch along with vfs time representation. 1. inode times set/get. 2. For inode times comparison. 3. getting times from current_fs_time() btrfs_timespec already uses 64 bits to represent seconds in timestamps. The switch to 64 bit using vfs_time will allow for timestamps beyond 2038 to be represented corretly. Signed-off-by: Deepa Dinamani--- fs/btrfs/file.c| 6 +++--- fs/btrfs/ioctl.c | 4 ++-- fs/btrfs/root-tree.c | 2 +- fs/btrfs/transaction.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 610f569..f7d1e14 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1732,16 +1732,16 @@ out: static void update_time_for_write(struct inode *inode) { - struct timespec now; + struct vfs_time now; if (IS_NOCMTIME(inode)) return; now = current_fs_time(inode->i_sb); - if (!timespec_equal(>i_mtime, )) + if (!vfs_time_equal(>i_mtime, )) inode->i_mtime = now; - if (!timespec_equal(>i_ctime, )) + if (!vfs_time_equal(>i_ctime, )) inode->i_ctime = now; if (IS_I_VERSION(inode)) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 6f35d9c..471037f 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -443,7 +443,7 @@ static noinline int create_subvol(struct inode *dir, struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_root *new_root; struct btrfs_block_rsv block_rsv; - struct timespec cur_time = current_fs_time(dir->i_sb); + struct vfs_time cur_time = current_fs_time(dir->i_sb); struct inode *inode; int ret; int err; @@ -4956,7 +4956,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root_item *root_item = >root_item; struct btrfs_trans_handle *trans; - struct timespec ct = current_fs_time(inode->i_sb); + struct vfs_time ct = current_fs_time(inode->i_sb); int ret = 0; int received_uuid_changed; diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index a25f3b2..0a309f6b 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -488,7 +488,7 @@ void btrfs_update_root_times(struct btrfs_trans_handle *trans, struct btrfs_root *root) { struct btrfs_root_item *item = >root_item; - struct timespec ct = current_fs_time(root->fs_info->sb); + struct vfs_time ct = current_fs_time(root->fs_info->sb); spin_lock(>root_item_lock); btrfs_set_root_ctransid(item, trans->transid); diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 37562d6..5481ee0 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1333,7 +1333,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, struct dentry *dentry; struct extent_buffer *tmp; struct extent_buffer *old; - struct timespec cur_time; + struct vfs_time cur_time; int ret = 0; u64 to_reserve = 0; u64 index = 0; -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2a 12/12] fs: xfs: change inode times to use vfs_time data type
The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use vfs_time aliases here to access inode times. vfs_time is an abstraction that hides the type of timestamps across vfs. This is necessary because we want to change the data types of vfs timestamps to support 64 bit times. current_fs_time() will change along with vfs timestamp data type changes. xfs_vn_update_time() is a .update callback for inode operations and this needs to change along with vfs inode times. All the accesses to or from struct inode timestamps and current_fs_time() are also changed to vfs_time. Signed-off-by: Deepa Dinamani--- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_iops.c| 2 +- fs/xfs/xfs_trans_inode.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ceba1a8..ebf76a3 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -765,7 +765,7 @@ xfs_ialloc( xfs_inode_t *ip; uintflags; int error; - struct timespec tv; + struct vfs_time tv; /* * Call the space management code to pick diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 76b71a1..7f8a897 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -973,7 +973,7 @@ xfs_vn_setattr( STATIC int xfs_vn_update_time( struct inode*inode, - struct timespec *now, + struct vfs_time *now, int flags) { struct xfs_inode*ip = XFS_I(inode); diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index b97f1df..54fc3c4 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -68,7 +68,7 @@ xfs_trans_ichgtime( int flags) { struct inode*inode = VFS_I(ip); - struct timespec tv; + struct vfs_time tv; ASSERT(tp); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); @@ -76,13 +76,13 @@ xfs_trans_ichgtime( tv = current_fs_time(inode->i_sb); if ((flags & XFS_ICHGTIME_MOD) && - !timespec_equal(>i_mtime, )) { + !vfs_time_equal(>i_mtime, )) { inode->i_mtime = tv; ip->i_d.di_mtime.t_sec = tv.tv_sec; ip->i_d.di_mtime.t_nsec = tv.tv_nsec; } if ((flags & XFS_ICHGTIME_CHG) && - !timespec_equal(>i_ctime, )) { + !vfs_time_equal(>i_ctime, )) { inode->i_ctime = tv; ip->i_d.di_ctime.t_sec = tv.tv_sec; ip->i_d.di_ctime.t_nsec = tv.tv_nsec; -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2c 1/8] vfs: Add vfs_time abstractions
Add vfs_time accessors to help convert vfs timestamps to use 64 bit times. These create an abstraction layer so that vfs inode times can be switched to struct timespec64 from struct timespec without breaking the individual filesystems after they have incorporated these. Add vfs_time data type aliases to help convert vfs timestamps to use 64 bit times. These create an abstraction layer so that vfs inode times can be switched to struct timespec64 instead of struct timespec. Use uapi exposed data types, timespec and timespec64 here to keep minimal timestamp data type conversions in API's interfacing with vfs. Signed-off-by: Deepa Dinamani--- include/linux/fs.h | 21 + 1 file changed, 21 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index 4af612f..56e6373 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1412,6 +1412,27 @@ static inline struct timespec current_fs_time_sec(struct super_block *sb) return (struct timespec) { get_seconds(), 0 }; } +/* Place holder defines until it is safe to use timespec64 + * in the vfs layer. + * timespec64 data type and functions will be used at that + * time directly by all filesystems and these defines will be deleted. + */ +static inline struct timespec64 vfs_time_to_timespec64(struct timespec inode_ts) +{ + return timespec_to_timespec64(inode_ts); +} + +static inline struct timespec timespec64_to_vfs_time(struct timespec64 ts) +{ + return timespec64_to_timespec(ts); +} + + +#define vfs_time timespec + +#define vfs_time_compare timespec_compare +#define vfs_time_equal timespec_equal + /* * Snapshotting support. */ -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2a 02/12] fs: cifs: Change cifs_fscache_inode_auxdata to use vfs_time data type
The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use vfs_time aliases here to access inode times. aux data timestamps are only used to read in inode timestamps. Hence, they need to change data type along with vfs times. struct timespec64 is the same as struct timespec on 64 bit systems. So it is a no-op on 64 bit systems. The buffer length(datalen) passed in to read in auxdata in cifs_fscache_inode_get_aux() and cifs_fscache_inode_check_aux() should be big enough for the data type change from struct timespec to struct timespec64 to be safe on 32 bit systems. Following provide support for safe usage on 32 bit systems: 1. datalen already accounts for struct timespec64 on 64 bit systems. 2. datalen passed in is a constant with sufficient space to accommodate auxdata. 3. The keylen subtracted from datalen is a constant and also leaves in sufficient space for increase. Signed-off-by: Deepa Dinamani--- fs/cifs/cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c index 6c665bf..f0892ac 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 vfs_time last_write_time; + struct vfs_time last_change_time; u64 eof; }; -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2a 00/12] vfs 64 bit time transition proposal
Introduction The series is one of the proposals on how to transition VFS timestamps to use 64 bit time. This is the inode_timespec idea proposed in the original RFC series. The type name has been changed to vfs_time based on Dave Chinner’s suggestion. Solution This series defines a new type name for vfs timestamps: vfs_time. All the individual file systems will use struct vfs_time to access vfs timestamps. Current time APIs also return vfs times and are considered to be part of vfs as they are exclusively used for inode timestamps. These are the steps involved: 1.Define vfs_time as an alias to timespec 2.Change individual filesystems to use only vfs_time data type for timestamps. Make sure each filesystem will be safe when converted to use timespec64 3.Change vfs_time to be an alias for timespec64. 4.Change all filesystems to use timespec64 directly. Note that the series only includes patches for steps 1 and 2. Concerns 1.Before the vfs layer is done, it might be confusing to developers as individual filesystems now will have two options for access: timespec and vfs_time type. Deepa Dinamani (12): vfs: Add vfs_time abstractions fs: cifs: Change cifs_fscache_inode_auxdata to use vfs_time data type fs: cifs: Change cifs_fattr timestamps data type to vfs_time fs: cifs: Make cnvrtDosUnixTm() y2038 safe fs: cifs: Use vfs_time_get_real_* time functions fs: btrfs: Change btrfs_inode.i_otime to use vfs_time data type fs: btrfs: Use vfs_time data type for btrfs_update_time() fs: btrfs: Change timespec data types to use vfs_time fs: ceph: Change encode and decode functions to use vfs_time fs: ceph: Replace timespec data type with vfs_time net: ceph: use vfs_time data type instead of timespec fs: xfs: change inode times to use vfs_time data type fs/btrfs/btrfs_inode.h | 2 +- fs/btrfs/file.c | 6 +++--- fs/btrfs/inode.c| 2 +- fs/btrfs/ioctl.c| 4 ++-- fs/btrfs/root-tree.c| 2 +- fs/btrfs/transaction.c | 2 +- fs/ceph/cache.c | 2 +- fs/ceph/caps.c | 6 +++--- fs/ceph/dir.c | 4 ++-- fs/ceph/file.c | 6 +++--- fs/ceph/inode.c | 32 fs/ceph/mds_client.c| 2 +- fs/ceph/mds_client.h| 2 +- fs/ceph/super.h | 8 fs/ceph/xattr.c | 2 +- fs/cifs/cache.c | 4 ++-- fs/cifs/cifsencrypt.c | 4 ++-- fs/cifs/cifsglob.h | 6 +++--- fs/cifs/cifsproto.h | 6 +++--- fs/cifs/cifssmb.c | 10 +- fs/cifs/inode.c | 2 +- fs/cifs/netmisc.c | 15 --- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_iops.c | 2 +- fs/xfs/xfs_trans_inode.c| 6 +++--- include/linux/ceph/decode.h | 11 ++- include/linux/ceph/messenger.h | 1 + include/linux/ceph/osd_client.h | 4 ++-- include/linux/fs.h | 19 +++ net/ceph/osd_client.c | 2 +- 30 files changed, 99 insertions(+), 77 deletions(-) -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2] vfs 64 bit time transition proposals
Introduction This is a follow on to the series: https://lkml.org/lkml/2016/1/7/20 [1]. This is aimed at reaching a consensus on how to transition the vfs timestamps to use 64 bit time. This demonstrates three ways (2a, 2b and 2c) of solving this problem. Each of the proposals has its own cover letter that explains the individual approach. Proposals 2b and 2c also outline variant approaches which are similar to the respective proposals. This drives the proposal count to 5. All the changes have been discussed with Arnd Bergmann, who posted the original series: https://lkml.org/lkml/2014/5/30/669 [2] The series has been simplified to include only the 64 bit timestamp changes as per Dave Chinner’s suggestion. Motivation The problem is how to change the vfs inode timestamps to use 64 bit times to overcome the 2038 problem. Below table [3] gives an overview of the extent/ type of changes needed of changes needed. The series is aimed at obtaining small manageable patches for all the cases in [3]. Table [3] Terminology: vfs_time – data type of timestamps used in the vfs layer. Access type # of instances 1. timespec_*(struct vfs_time, struct timespec) / 34 timespec_*(struct vfs_time, struct vfs_time) 2. struct vfs_time = struct vfs_time 50 3. vfs_time = current_fs_time/ CURRENT_TIME/ CURRENT_TIME_SEC 312 4. setattr vfs_time assignments 141 5. vfs_time = other data types, outside of setattr() (timespec, s32, s64..) 74 6. other data types, outside of getattr() (timespec, s32, s64..) = vfs_time 85 7. internal individual fs funtions using inode timestamps as args 80 8. extra timestamp fields in individual filesystems ~10 9. VFS callback - int (*update_time)(struct inode *, struct timespec *, int) 3 10. VFS function - void lease_get_mtime(struct inode *inode, struct timespec *time) 3 Each series is used to demonstrate how each of the above cases is solved using their respective approaches. The example filesystems (btrfs, xfs, cifs, and ceph) were selected in such a way so as to showcase all these issues in table [3]. Source Tree The tree is hosted at github.com/deepa-hub/vfs.git The branches for the three approaches are 2a. https://github.com/deepa-hub/vfs.git refs/heads/vfs_time 2b. https://github.com/deepa-hub/vfs.git refs/heads/vfs_time_to_timespec 2c. https://github.com/deepa-hub/vfs.git refs/heads/vfs_time_to_ts64 All the above series are based off of: https://lkml.org/lkml/2016/2/3/34 [4] and a couple of other patches. Only the minimal changes are posted here to keep the series simple. There are a couple of bug fixes like data type conversion bugs that will be sent directly to the corresponding filesystem lists. Next steps The approaches 2a, 2b and 2c are posted as responses to this cover letter. Testing All the approaches have been compile tested only. ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2c 7/8] fs: ceph: Use vfs timestamp abstraction helpers
The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use timespec64 and conversion functions here to access inode times. All the timestamps are converted to use struct timespec64 data type. And, all the vfs timestamps are converted to timespec64 at the boundary of vfs. Signed-off-by: Deepa Dinamani--- fs/ceph/addr.c | 20 ++--- fs/ceph/cache.c | 6 +-- fs/ceph/caps.c | 10 ++--- fs/ceph/dir.c | 4 +- fs/ceph/file.c | 14 +-- fs/ceph/inode.c | 91 +++-- fs/ceph/mds_client.c| 9 ++-- fs/ceph/mds_client.h| 2 +- fs/ceph/snap.c | 6 +-- fs/ceph/super.h | 9 ++-- fs/ceph/xattr.c | 2 +- include/linux/ceph/decode.h | 9 ++-- include/linux/ceph/osd_client.h | 4 +- net/ceph/osd_client.c | 4 +- 14 files changed, 110 insertions(+), 80 deletions(-) diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index c222137..09a97b5 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -479,6 +479,7 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) struct ceph_fs_client *fsc; struct ceph_osd_client *osdc; struct ceph_snap_context *snapc, *oldest; + struct timespec64 ts; loff_t page_off = page_offset(page); loff_t snap_size = -1; long writeback_stat; @@ -540,11 +541,12 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc) ceph_readpage_to_fscache(inode, page); set_page_writeback(page); + ts = vfs_time_to_timespec64(inode->i_mtime); err = ceph_osdc_writepages(osdc, ceph_vino(inode), >i_layout, snapc, page_off, len, truncate_seq, truncate_size, - >i_mtime, , 1); + , , 1); if (err < 0) { dout("writepage setting page/mapping error %d %p\n", err, page); SetPageError(page); @@ -699,6 +701,7 @@ static int ceph_writepages_start(struct address_space *mapping, int rc = 0; unsigned wsize = 1 << inode->i_blkbits; struct ceph_osd_request *req = NULL; + struct timespec64 ts; int do_sync = 0; loff_t snap_size, i_size; u64 truncate_size; @@ -978,8 +981,9 @@ get_more_pages: osd_req_op_extent_update(req, 0, len); vino = ceph_vino(inode); + ts = vfs_time_to_timespec64(inode->i_mtime); ceph_osdc_build_request(req, offset, snapc, vino.snap, - >i_mtime); + ); rc = ceph_osdc_start_request(>client->osdc, req, true); BUG_ON(rc); @@ -1465,6 +1469,7 @@ int ceph_uninline_data(struct file *filp, struct page *locked_page) struct ceph_fs_client *fsc = ceph_inode_to_client(inode); struct ceph_osd_request *req; struct page *page = NULL; + struct timespec64 ts; u64 len, inline_version; int err = 0; bool from_pagecache = false; @@ -1528,7 +1533,8 @@ int ceph_uninline_data(struct file *filp, struct page *locked_page) goto out; } - ceph_osdc_build_request(req, 0, NULL, CEPH_NOSNAP, >i_mtime); + ts = vfs_time_to_timespec64(inode->i_mtime); + ceph_osdc_build_request(req, 0, NULL, CEPH_NOSNAP, ); err = ceph_osdc_start_request(>client->osdc, req, false); if (!err) err = ceph_osdc_wait_request(>client->osdc, req); @@ -1572,7 +1578,7 @@ int ceph_uninline_data(struct file *filp, struct page *locked_page) goto out_put; } - ceph_osdc_build_request(req, 0, NULL, CEPH_NOSNAP, >i_mtime); + ceph_osdc_build_request(req, 0, NULL, CEPH_NOSNAP, ); err = ceph_osdc_start_request(>client->osdc, req, false); if (!err) err = ceph_osdc_wait_request(>client->osdc, req); @@ -1622,6 +1628,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, u32 pool) struct ceph_osd_request *rd_req = NULL, *wr_req = NULL; struct rb_node **p, *parent; struct ceph_pool_perm *perm; + struct timespec64 ts; struct page **pages; int err = 0, err2 = 0, have = 0; @@ -1701,12 +1708,13 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, u32 pool) osd_req_op_raw_data_in_pages(rd_req, 0, pages, PAGE_SIZE, 0, false, true); + ts = vfs_time_to_timespec64(ci->vfs_inode.i_mtime);
[Y2038] [RFC v2c 5/8] fs: btrfs: Change btrfs_inode.i_otime to vfs_time data type
The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use timespec64 and conversion functions here to access inode times. struct btrfs_inode is the in memory inode structure for btrfs. i_otime is a member of the btrfs_inode that represents file creation times. Use struct timespec64 to represent this timestamp. Like all the other inode timestamps in struct inode, i_otime is assigned to/ from disk or struct inode times or 0. Hence, i_otime needs to use accessor functions to access inode timestamps. Signed-off-by: Deepa Dinamani--- fs/btrfs/btrfs_inode.h | 2 +- fs/btrfs/inode.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 61205e3..5200e68 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -190,7 +190,7 @@ struct btrfs_inode { struct btrfs_delayed_node *delayed_node; /* File creation time. */ - struct timespec i_otime; + struct timespec64 i_otime; /* Hook into fs_info->delayed_iputs */ struct list_head delayed_iput; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 59c0e22..bcd223c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5592,7 +5592,7 @@ static struct inode *new_simple_dir(struct super_block *s, inode->i_mtime = current_fs_time(inode->i_sb); inode->i_atime = inode->i_mtime; inode->i_ctime = inode->i_mtime; - BTRFS_I(inode)->i_otime = inode->i_mtime; + BTRFS_I(inode)->i_otime = vfs_time_to_timespec64(inode->i_mtime); return inode; } @@ -6164,7 +6164,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, inode->i_mtime = current_fs_time(inode->i_sb); inode->i_atime = inode->i_mtime; inode->i_ctime = inode->i_mtime; - BTRFS_I(inode)->i_otime = inode->i_mtime; + BTRFS_I(inode)->i_otime = vfs_time_to_timespec64(inode->i_mtime); inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0], struct btrfs_inode_item); -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2c 3/8] fs: cifs: Change cifs_fattr timestamps data type to timespec64
The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use timespec64 and conversion functions here to access inode times. This change is safe because cifs_fattr is accessed in following ways: 1. Assigning to/ from/ compared with struct inode timestamps, which will match vfs_time alias. 2. Assigned from cifs_NTtimeToUnix(). And, this function does not care about the data type sizes of tv_sec and tv_nsec fields. 3. Assigned from current_fs_time(), which will match vfs_time alias. 4. Assigned from cnvrtDosUnixTm(). And, this function does not care about the data type sizes of tv_sec and tv_nsec fields. Signed-off-by: Deepa Dinamani--- fs/cifs/cifsencrypt.c | 4 ++-- fs/cifs/cifsglob.h| 6 +++--- fs/cifs/cifsproto.h | 6 +++--- fs/cifs/cifssmb.c | 6 +++--- fs/cifs/inode.c | 35 --- fs/cifs/netmisc.c | 11 ++- 6 files changed, 37 insertions(+), 31 deletions(-) diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index f86e07d..2917d1d 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -460,7 +460,7 @@ find_timestamp(struct cifs_ses *ses) unsigned char *blobptr; unsigned char *blobend; struct ntlmssp2_name *attrptr; - struct timespec ts; + struct timespec64 ts; if (!ses->auth_key.len || !ses->auth_key.response) return 0; @@ -485,7 +485,7 @@ find_timestamp(struct cifs_ses *ses) blobptr += attrsize; /* advance attr value */ } - ktime_get_real_ts(); + ktime_get_real_ts64(); return cpu_to_le64(cifs_UnixTimeToNT(ts)); } diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a25b251..7dfb0e2 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1393,9 +1393,9 @@ struct cifs_fattr { dev_t cf_rdev; unsigned intcf_nlink; unsigned intcf_dtype; - struct timespec cf_atime; - struct timespec cf_mtime; - struct timespec cf_ctime; + struct timespec64 cf_atime; + struct timespec64 cf_mtime; + struct timespec64 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..2d78814 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -126,9 +126,9 @@ 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 timespec64 cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); +extern u64 cifs_UnixTimeToNT(struct timespec64); +extern struct timespec64 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 1a9e43d..db268ff 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -478,8 +478,8 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) * this requirement. */ int val, seconds, remain, result; - struct timespec ts; - unsigned long utc = get_seconds(); + struct timespec64 ts; + unsigned long utc = ktime_get_real_seconds(); ts = cnvrtDosUnixTm(rsp->SrvTime.Date, rsp->SrvTime.Time, 0); cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n", @@ -4000,7 +4000,7 @@ QInfRetry: if (rc) { cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc); } else if (data) { - struct timespec ts; + struct timespec64 ts; __u32 time = le32_to_cpu(pSMBr->last_write_time); /* decode response */ diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index fa72359..1ead483 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 timespec64 mtime; cifs_dbg(FYI, "%s: revalidating inode %llu\n", __func__, cifs_i->uniqueid); @@ -109,8 +110,9 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
[Y2038] [RFC v2c 2/8] fs: cifs: Change auxdata to struct timespec64 data type
Aux data timestamps are only used to read in inode timestamps for fscache. The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use accessor functions to access inode times before the vfs change. Also convert the timestamp data types in the individual filesystems to use y2038 safe struct timespec64. The data type change from struct timespec to struct timespec64 is safe because 1.Size of auxdata on 64 bit systems already accounts for struct timespec64. 2.Only auxdata length changes(increases) by a maximum of 128 bits (data type increase and alignment adjustments). 3.Everything else is the same size as before and possibly less big than on 64 bit systems. 4.64 bit data is aligned on a 64 bit boundary even on 32 bit systems, making the alignment requirements also same as on 64 bit systems, except for i386 where alignment requirements pack the struct tighter. Signed-off-by: Deepa Dinamani--- fs/cifs/cache.c | 16 ++-- 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c index 6c665bf..713055b 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 timespec64 last_write_time; + struct timespec64 last_change_time; u64 eof; }; @@ -259,8 +259,10 @@ cifs_fscache_inode_get_aux(const void *cookie_netfs_data, void *buffer, memset(, 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 = + vfs_time_to_timespec64(cifsi->vfs_inode.i_mtime); + auxdata.last_change_time = + vfs_time_to_timespec64(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(, 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 = + vfs_time_to_timespec64(cifsi->vfs_inode.i_mtime); + auxdata.last_change_time = + vfs_time_to_timespec64(cifsi->vfs_inode.i_ctime); if (memcmp(data, , datalen) != 0) return FSCACHE_CHECKAUX_OBSOLETE; -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2c 4/8] fs: cifs: Make cnvrtDosUnixTm() y2038 safe
The seconds calculated from the server(DOS format) cannot be saved in int data type as this cannot save seconds since epoch after the year 2038. Use long long for seconds field in cnvrtDosUnixTm(). This will help represent 64 bit time even on 32 bit systems. Note that even though the theoretical max on DOS times is 2107, its api's only support until the year 2099. This means we can get away with 32 bit unsigned sec field. But, the sec field uses long long to maintain uniformity in the kernel, where everyone uses the theoretical max. Signed-off-by: Deepa Dinamani--- fs/cifs/netmisc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index bf1b52e..ecbb7162 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -963,7 +963,8 @@ static const int total_days_of_prev_months[] = { struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) { struct timespec64 ts; - int sec, min, days, month, year; + long long sec; + int min, days, month, year; u16 date = le16_to_cpu(le_date); u16 time = le16_to_cpu(le_time); SMB_TIME *st = (SMB_TIME *) @@ -974,7 +975,7 @@ struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) sec = 2 * st->TwoSeconds; min = st->Minutes; if ((sec > 59) || (min > 59)) - cifs_dbg(VFS, "illegal time min %d sec %d\n", min, sec); + cifs_dbg(VFS, "illegal time min %d sec %lld\n", min, sec); sec += (min * 60); sec += 60 * 60 * st->Hours; if (st->Hours > 24) -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
Re: [Y2038] [RFC v2] vfs 64 bit time transition proposals
On Friday 12 February 2016 01:21:59 Deepa Dinamani wrote: > Introduction > > This is a follow on to the series: https://lkml.org/lkml/2016/1/7/20 [1]. > This is aimed at reaching a consensus on how to transition the vfs > timestamps to use 64 bit time. This demonstrates three ways (2a, 2b and > 2c) of solving this problem. Each of the proposals has its own cover > letter that explains the individual approach. Proposals 2b and 2c also > outline variant approaches which are similar to the respective proposals. > This drives the proposal count to 5. All the changes have been discussed > with Arnd Bergmann, who posted the original series: > https://lkml.org/lkml/2014/5/30/669 [2] > > The series has been simplified to include only the 64 bit timestamp > changes as per Dave Chinner’s suggestion. > > Motivation > > The problem is how to change the vfs inode timestamps to use 64 bit > times to overcome the 2038 problem. > > Below table [3] gives an overview of the extent/ type of changes > needed of changes needed. > The series is aimed at obtaining small manageable patches for all > the cases in [3]. > Hi Deepa, Thanks a lot for posting this updated series, very nice work! Regarding the three versions, I think all of them are doable doable, and they all have their upsides and downsides but no showstoppers. Let me summarize what I see in the patches: 2a is the smallest set of changes in number of lines, as you indicated in the previous discussion (I was skeptical here initially, but you were right). The main downside is that each patch has to carefully consider what happens at the point when the type gets flipped, so that printk format strings are correct and assignments to local variables don't truncate the range. It also requires changing the types again after the VFS change, but that is something we can automate using coccinelle. 2b has the main advantage of not changing behavior with the flip, so we can convert all file systems to use vfs_time relatively easily and then later make them actually use 64-bit timestamps with a patch that each file system developer can do for themselves. One downside is that it leads to rather ugly code as discussed before, examples are in "[RFC v2b 5/5] fs: xfs: change inode times to use vfs_time data type" and "[RFC v2b 3/5] fs: btrfs: Use vfs_time accessors". 2c gets us the furthest along the way for the conversion, close to where we want to end up in the long run, so we could do that to file systems one by one. The behavior change is immediate, so there are fewer possible surprises than with 2a, but it also means the most upfront work. Arnd ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
Re: [Y2038] [RFC v2b 3/5] fs: btrfs: Use vfs_time accessors
On Friday 12 February 2016 01:45:47 Deepa Dinamani wrote: > + ts = vfs_time_to_timespec(inode->i_mtime); > + if (!timespec_equal(, )) > + inode->i_mtime = timespec_to_vfs_time(now); > + > + ts = vfs_time_to_timespec(inode->i_mtime); > + if (!timespec_equal(, )) > + inode->i_ctime = timespec_to_vfs_time(now); > The second one needs to be fs_time_to_timespec(inode->i_ctime), not i_mtime. Arnd ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
[Y2038] [RFC v2c 6/8] fs: btrfs: Use vfs timestamp abstraction helper
The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use timespec64 and conversion functions here to access inode times. The following needs to switch along with vfs time representation. 1. inode times set/get. 2. For inode times comparison. 3. getting times from current_fs_time(). 4. btrfs_timespec already uses 64 bits to represent seconds in timestamps as 64 bits in btrfs_timespec. 5. btrfs_update_time() is a inode_ops callback. Signed-off-by: Deepa Dinamani--- fs/btrfs/file.c| 7 --- fs/btrfs/inode.c | 2 +- fs/btrfs/ioctl.c | 4 ++-- fs/btrfs/root-tree.c | 2 +- fs/btrfs/transaction.c | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 610f569..a5fb13c 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1732,16 +1732,17 @@ out: static void update_time_for_write(struct inode *inode) { - struct timespec now; + struct vfs_time now; if (IS_NOCMTIME(inode)) return; now = current_fs_time(inode->i_sb); - if (!timespec_equal(>i_mtime, )) + + if (!vfs_time_equal(>i_mtime, )) inode->i_mtime = now; - if (!timespec_equal(>i_ctime, )) + if (!vfs_time_equal(>i_ctime, )) inode->i_ctime = now; if (IS_I_VERSION(inode)) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index bcd223c..860e5e6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -5942,7 +5942,7 @@ static int btrfs_dirty_inode(struct inode *inode) * This is a copy of file_update_time. We need this so we can return error on * ENOSPC for updating the inode in the case of file write and mmap writes. */ -static int btrfs_update_time(struct inode *inode, struct timespec *now, +static int btrfs_update_time(struct inode *inode, struct vfs_time *now, int flags) { struct btrfs_root *root = BTRFS_I(inode)->root; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 6f35d9c..471037f 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -443,7 +443,7 @@ static noinline int create_subvol(struct inode *dir, struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_root *new_root; struct btrfs_block_rsv block_rsv; - struct timespec cur_time = current_fs_time(dir->i_sb); + struct vfs_time cur_time = current_fs_time(dir->i_sb); struct inode *inode; int ret; int err; @@ -4956,7 +4956,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root_item *root_item = >root_item; struct btrfs_trans_handle *trans; - struct timespec ct = current_fs_time(inode->i_sb); + struct vfs_time ct = current_fs_time(inode->i_sb); int ret = 0; int received_uuid_changed; diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index a25f3b2..0a309f6b 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -488,7 +488,7 @@ void btrfs_update_root_times(struct btrfs_trans_handle *trans, struct btrfs_root *root) { struct btrfs_root_item *item = >root_item; - struct timespec ct = current_fs_time(root->fs_info->sb); + struct vfs_time ct = current_fs_time(root->fs_info->sb); spin_lock(>root_item_lock); btrfs_set_root_ctransid(item, trans->transid); diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 37562d6..5481ee0 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1333,7 +1333,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, struct dentry *dentry; struct extent_buffer *tmp; struct extent_buffer *old; - struct timespec cur_time; + struct vfs_time cur_time; int ret = 0; u64 to_reserve = 0; u64 index = 0; -- 1.9.1 ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038
Re: [Y2038] [RFC v2] vfs 64 bit time transition proposals
> Regarding the three versions, I think all of them are doable > doable, and they all have their upsides and downsides but no > showstoppers. I agree that all the approaches are doable. > Let me summarize what I see in the patches: > > 2a is the smallest set of changes in number of lines, as you indicated >in the previous discussion (I was skeptical here initially, but >you were right). The main downside is that each patch has to >carefully consider what happens at the point when the type gets >flipped, so that printk format strings are correct and assignments >to local variables don't truncate the range. It also requires >changing the types again after the VFS change, but that is >something we can automate using coccinelle. 2c has the same downside as this. It also has to carefully consider what happens when you switch end filesystems to timespec64, be it for printks or assignments. I would say that the effort to do this was the same for 2a and 2c. And, 2c also needs to get rid of the abstraction macros when vfs is transitioned to using timespec64. > 2b has the main advantage of not changing behavior with the flip, so >we can convert all file systems to use vfs_time relatively easily >and then later make them actually use 64-bit timestamps with >a patch that each file system developer can do for themselves. >One downside is that it leads to rather ugly code as discussed >before, examples are in "[RFC v2b 5/5] fs: xfs: change inode >times to use vfs_time data type" and "[RFC v2b 3/5] fs: btrfs: >Use vfs_time accessors". Here is the breakup of the number of changes required from the table in the cover letter(https://lkml.org/lkml/2016/2/12/76): * # Changes needed in 2a = row 1 + row 7 + row 8 + row 9 + row 10 = 34 + 80 + 10 + 3 + 3 = 130 * # Changes needed in 2b = row 1 + row 4 + row 5 + row 6 + row 7 * (~3) = 34 + 80 + 141 + 74 + 85 + 240 = 654 * # Changes needed in 2c = Changes in 2b + some more It is clear to see from the above table that number of such changes will be considerably more for approaches 2b and 2c. And, 2b is not even close to what we want to achieve and will again confuse developers even more as there will be 2 sets of abstraction apis now: 1. vfs_time apis 2. timespec64 to timespec/ timespec to timespec64 apis Since there is no clean up effort here after vfs is switched over, we are just making all filesystems that use these apis harder to read. > 2c gets us the furthest along the way for the conversion, close >to where we want to end up in the long run, so we could do that >to file systems one by one. The behavior change is immediate, >so there are fewer possible surprises than with 2a, but it >also means the most upfront work. 2c abstractions can be used in more than one way. And, 2c also introduces a new timestamp data type along with timespec64 in the filesystem code. The above two factors can make it confusing for the developers until we transition vfs and remove abstractions from individual filesystems. And, this is a problem as we want to remove abstractions in a different kernel release than the one we do the transition in, as we discussed previously. 2a still seems like the right choice to me. And, will have the least number of changes. As Arnd thinks all of them are doable, if anybody else has other concerns we missed please comment. -Deepa ___ Y2038 mailing list Y2038@lists.linaro.org https://lists.linaro.org/mailman/listinfo/y2038