vfs/y2038: inode timestamps conversion to timespec64

This is a late set of changes from Deepa Dinamani doing an automated
 treewide conversion of the inode and iattr structures from 'timespec'
 to 'timespec64', to push the conversion from the VFS layer into the
 individual file systems.
 
 There were no conflicts between this and the contents of linux-next
 until just before the merge window, when we saw multiple problems:
 
 - A minor conflict with my own y2038 fixes, which I could address
   by adding another patch on top here.
 - One semantic conflict with late changes to the NFS tree. I addressed
   this by merging Deepa's original branch on top of the changes that
   now got merged into mainline and making sure the merge commit includes
   the necessary changes as produced by coccinelle.
 - A trivial conflict against the removal of staging/lustre.
 - Multiple conflicts against the VFS changes in the overlayfs tree.
   These are still part of linux-next, but apparently this is no longer
   intended for 4.18 [1], so I am ignoring that part.
 
 As Deepa writes:
 
   The series aims to switch vfs timestamps to use struct timespec64.
   Currently vfs uses struct timespec, which is not y2038 safe.
 
   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.
 
   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.
 
 Thomas Gleixner adds:
 
   I think there is no point to drag that out for the next merge window.
   The whole thing needs to be done in one go for the core changes which
   means that you're going to play that catchup game forever. Let's get
   over with it towards the end of the merge window.
 
 [1] https://www.spinics.net/lists/linux-fsdevel/msg128294.html
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJbInZAAAoJEGCrR//JCVInReoQAIlVIIMt5ZX6wmaKbrjy9Itf
 MfgbFihQ/djLnuSPVQ3nztcxF0d66BKHZ9puVjz6+mIHqfDvJTRwZs9nU+sOF/T1
 g78fRkM1cxq6ZCkGYAbzyjyo5aC4PnSMP/NQLmwqvi0MXqqrbDoq5ZdP9DHJw39h
 L9lD8FM/P7T29Fgp9tq/pT5l9X8VU8+s5KQG1uhB5hii4VL6pD6JyLElDita7rg+
 Z7/V7jkxIGEUWF7vGaiR1QTFzEtpUA/exDf9cnsf51OGtK/LJfQ0oiZPPuq3oA/E
 LSbt8YQQObc+dvfnGxwgxEg1k5WP5ekj/Wdibv/+rQKgGyLOTz6Q4xK6r8F2ahxs
 nyZQBdXqHhJYyKr1H1reUH3mrSgQbE5U5R1i3My0xV2dSn+vtK5vgF21v2Ku3A1G
 wJratdtF/kVBzSEQUhsYTw14Un+xhBLRWzcq0cELonqxaKvRQK9r92KHLIWNE7/v
 c0TmhFbkZA+zR8HdsaL3iYf1+0W/eYy8PcvepyldKNeW2pVk3CyvdTfY2Z87G2XK
 tIkK+BUWbG3drEGG3hxZ3757Ln3a9qWyC5ruD3mBVkuug/wekbI8PykYJS7Mx4s/
 WNXl0dAL0Eeu1M8uEJejRAe1Q3eXoMWZbvCYZc+wAm92pATfHVcKwPOh8P7NHlfy
 A3HkjIBrKW5AgQDxfgvm
 =CZX2
 -----END PGP SIGNATURE-----

Merge tag 'vfs-timespec64' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground

Pull inode timestamps conversion to timespec64 from Arnd Bergmann:
 "This is a late set of changes from Deepa Dinamani doing an automated
  treewide conversion of the inode and iattr structures from 'timespec'
  to 'timespec64', to push the conversion from the VFS layer into the
  individual file systems.

  As Deepa writes:

   'The series aims to switch vfs timestamps to use struct timespec64.
    Currently vfs uses struct timespec, which is not y2038 safe.

    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.

    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'

  Thomas Gleixner adds:

   'I think there is no point to drag that out for the next merge
    window. The whole thing needs to be done in one go for the core
    changes which means that you're going to play that catchup game
    forever. Let's get over with it towards the end of the merge window'"

* tag 'vfs-timespec64' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground:
  pstore: Remove bogus format string definition
  vfs: change inode times to use struct timespec64
  pstore: Convert internal records to timespec64
  udf: Simplify calls to udf_disk_stamp_to_time
  fs: nfs: get rid of memcpys for inode times
  ceph: make inode time prints to be long long
  lustre: Use long long type to print inode time
  fs: add timespec64_truncate()
This commit is contained in:
Linus Torvalds 2018-06-15 07:31:07 +09:00
commit 7a932516f5
85 changed files with 539 additions and 424 deletions

View file

@ -502,6 +502,7 @@ static int fat_validate_dir(struct inode *dir)
/* doesn't deal with root inode */
int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
{
struct timespec ts;
struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
int error;
@ -552,11 +553,14 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
inode->i_blocks = ((inode->i_size + (sbi->cluster_size - 1))
& ~((loff_t)sbi->cluster_size - 1)) >> 9;
fat_time_fat2unix(sbi, &inode->i_mtime, de->time, de->date, 0);
fat_time_fat2unix(sbi, &ts, de->time, de->date, 0);
inode->i_mtime = timespec_to_timespec64(ts);
if (sbi->options.isvfat) {
fat_time_fat2unix(sbi, &inode->i_ctime, de->ctime,
fat_time_fat2unix(sbi, &ts, de->ctime,
de->cdate, de->ctime_cs);
fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0);
inode->i_ctime = timespec_to_timespec64(ts);
fat_time_fat2unix(sbi, &ts, 0, de->adate, 0);
inode->i_atime = timespec_to_timespec64(ts);
} else
inode->i_ctime = inode->i_atime = inode->i_mtime;
@ -825,6 +829,7 @@ static int fat_statfs(struct dentry *dentry, struct kstatfs *buf)
static int __fat_write_inode(struct inode *inode, int wait)
{
struct timespec ts;
struct super_block *sb = inode->i_sb;
struct msdos_sb_info *sbi = MSDOS_SB(sb);
struct buffer_head *bh;
@ -862,13 +867,16 @@ retry:
raw_entry->size = cpu_to_le32(inode->i_size);
raw_entry->attr = fat_make_attrs(inode);
fat_set_start(raw_entry, MSDOS_I(inode)->i_logstart);
fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time,
ts = timespec64_to_timespec(inode->i_mtime);
fat_time_unix2fat(sbi, &ts, &raw_entry->time,
&raw_entry->date, NULL);
if (sbi->options.isvfat) {
__le16 atime;
fat_time_unix2fat(sbi, &inode->i_ctime, &raw_entry->ctime,
ts = timespec64_to_timespec(inode->i_ctime);
fat_time_unix2fat(sbi, &ts, &raw_entry->ctime,
&raw_entry->cdate, &raw_entry->ctime_cs);
fat_time_unix2fat(sbi, &inode->i_atime, &atime,
ts = timespec64_to_timespec(inode->i_atime);
fat_time_unix2fat(sbi, &ts, &atime,
&raw_entry->adate, NULL);
}
spin_unlock(&sbi->inode_hash_lock);

View file

@ -250,7 +250,7 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name,
if (err)
return err;
dir->i_ctime = dir->i_mtime = *ts;
dir->i_ctime = dir->i_mtime = timespec_to_timespec64(*ts);
if (IS_DIRSYNC(dir))
(void)fat_sync_inode(dir);
else
@ -266,7 +266,8 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
struct super_block *sb = dir->i_sb;
struct inode *inode = NULL;
struct fat_slot_info sinfo;
struct timespec ts;
struct timespec64 ts;
struct timespec t;
unsigned char msdos_name[MSDOS_NAME];
int err, is_hid;
@ -285,7 +286,8 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode,
}
ts = current_time(dir);
err = msdos_add_entry(dir, msdos_name, 0, is_hid, 0, &ts, &sinfo);
t = timespec64_to_timespec(ts);
err = msdos_add_entry(dir, msdos_name, 0, is_hid, 0, &t, &sinfo);
if (err)
goto out;
inode = fat_build_inode(sb, sinfo.de, sinfo.i_pos);
@ -344,7 +346,8 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
struct fat_slot_info sinfo;
struct inode *inode;
unsigned char msdos_name[MSDOS_NAME];
struct timespec ts;
struct timespec64 ts;
struct timespec t;
int err, is_hid, cluster;
mutex_lock(&MSDOS_SB(sb)->s_lock);
@ -362,12 +365,13 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
}
ts = current_time(dir);
cluster = fat_alloc_new_dir(dir, &ts);
t = timespec64_to_timespec(ts);
cluster = fat_alloc_new_dir(dir, &t);
if (cluster < 0) {
err = cluster;
goto out;
}
err = msdos_add_entry(dir, msdos_name, 1, is_hid, cluster, &ts, &sinfo);
err = msdos_add_entry(dir, msdos_name, 1, is_hid, cluster, &t, &sinfo);
if (err)
goto out_free;
inc_nlink(dir);
@ -432,7 +436,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
struct msdos_dir_entry *dotdot_de;
struct inode *old_inode, *new_inode;
struct fat_slot_info old_sinfo, sinfo;
struct timespec ts;
struct timespec64 ts;
loff_t new_i_pos;
int err, old_attrs, is_dir, update_dotdot, corrupt = 0;
@ -499,8 +503,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name,
new_i_pos = MSDOS_I(new_inode)->i_pos;
fat_detach(new_inode);
} else {
struct timespec t = timespec64_to_timespec(ts);
err = msdos_add_entry(new_dir, new_name, is_dir, is_hid, 0,
&ts, &sinfo);
&t, &sinfo);
if (err)
goto out;
new_i_pos = sinfo.i_pos;

View file

@ -678,7 +678,7 @@ static int vfat_add_entry(struct inode *dir, const struct qstr *qname,
goto cleanup;
/* update timestamp */
dir->i_ctime = dir->i_mtime = dir->i_atime = *ts;
dir->i_ctime = dir->i_mtime = dir->i_atime = timespec_to_timespec64(*ts);
if (IS_DIRSYNC(dir))
(void)fat_sync_inode(dir);
else
@ -761,13 +761,15 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
struct super_block *sb = dir->i_sb;
struct inode *inode;
struct fat_slot_info sinfo;
struct timespec ts;
struct timespec64 ts;
struct timespec t;
int err;
mutex_lock(&MSDOS_SB(sb)->s_lock);
ts = current_time(dir);
err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo);
t = timespec64_to_timespec(ts);
err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &t, &sinfo);
if (err)
goto out;
inode_inc_iversion(dir);
@ -850,18 +852,20 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
struct super_block *sb = dir->i_sb;
struct inode *inode;
struct fat_slot_info sinfo;
struct timespec ts;
struct timespec64 ts;
struct timespec t;
int err, cluster;
mutex_lock(&MSDOS_SB(sb)->s_lock);
ts = current_time(dir);
cluster = fat_alloc_new_dir(dir, &ts);
t = timespec64_to_timespec(ts);
cluster = fat_alloc_new_dir(dir, &t);
if (cluster < 0) {
err = cluster;
goto out;
}
err = vfat_add_entry(dir, &dentry->d_name, 1, cluster, &ts, &sinfo);
err = vfat_add_entry(dir, &dentry->d_name, 1, cluster, &t, &sinfo);
if (err)
goto out_free;
inode_inc_iversion(dir);
@ -899,7 +903,8 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
struct msdos_dir_entry *dotdot_de;
struct inode *old_inode, *new_inode;
struct fat_slot_info old_sinfo, sinfo;
struct timespec ts;
struct timespec64 ts;
struct timespec t;
loff_t new_i_pos;
int err, is_dir, update_dotdot, corrupt = 0;
struct super_block *sb = old_dir->i_sb;
@ -934,8 +939,9 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry,
new_i_pos = MSDOS_I(new_inode)->i_pos;
fat_detach(new_inode);
} else {
t = timespec64_to_timespec(ts);
err = vfat_add_entry(new_dir, &new_dentry->d_name, is_dir, 0,
&ts, &sinfo);
&t, &sinfo);
if (err)
goto out;
new_i_pos = sinfo.i_pos;