FAT filesystem supports timestamps until the year 2099 even though the theoretical max is 2107. But, the struct timespec overflows in the year 2038 on 32 bit systems.
Use inode_timespec throughout the file system code so that the timestamps can switch to y2038 safe struct timespec64 when CONFIG_FS_USES_64BIT_TIME is turned on.
Use a larger data type for seconds in fat_time_fat2unix(). This extends timestamps beyond the year 2038.
Signed-off-by: Deepa Dinamani deepa.kernel@gmail.com --- fs/fat/dir.c | 7 +++++-- fs/fat/fat.h | 8 +++++--- fs/fat/file.c | 10 ++++++++-- fs/fat/inode.c | 46 ++++++++++++++++++++++++++++++++-------------- fs/fat/misc.c | 7 ++++--- fs/fat/namei_msdos.c | 40 +++++++++++++++++++++++++--------------- fs/fat/namei_vfat.c | 41 +++++++++++++++++++++++++++-------------- 7 files changed, 106 insertions(+), 53 deletions(-)
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 7def96c..fa8a922 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -1034,6 +1034,7 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo) struct super_block *sb = dir->i_sb; struct msdos_dir_entry *de; struct buffer_head *bh; + struct inode_timespec now; int err = 0, nr_slots;
/* @@ -1071,7 +1072,9 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo) } }
- dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC; + now = current_fs_time_sec(sb); + VFS_INODE_SET_XTIME(i_mtime, dir, now); + VFS_INODE_SET_XTIME(i_atime, dir, now); if (IS_DIRSYNC(dir)) (void)fat_sync_inode(dir); else @@ -1130,7 +1133,7 @@ error: return err; }
-int fat_alloc_new_dir(struct inode *dir, struct timespec *ts) +int fat_alloc_new_dir(struct inode *dir, struct inode_timespec *ts) { struct super_block *sb = dir->i_sb; struct msdos_sb_info *sbi = MSDOS_SB(sb); diff --git a/fs/fat/fat.h b/fs/fat/fat.h index e6b764a..cabb0fd 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -303,7 +303,7 @@ extern int fat_scan_logstart(struct inode *dir, int i_logstart, struct fat_slot_info *sinfo); extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, struct msdos_dir_entry **de); -extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts); +extern int fat_alloc_new_dir(struct inode *dir, struct inode_timespec *ts); extern int fat_add_entries(struct inode *dir, void *slots, int nr_slots, struct fat_slot_info *sinfo); extern int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo); @@ -405,9 +405,11 @@ void fat_msg(struct super_block *sb, const char *level, const char *fmt, ...); } while (0) extern int fat_clusters_flush(struct super_block *sb); extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster); -extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts, +extern void fat_time_fat2unix(struct msdos_sb_info *sbi, + struct inode_timespec *ts, __le16 __time, __le16 __date, u8 time_cs); -extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec *ts, +extern void fat_time_unix2fat(struct msdos_sb_info *sbi, + struct inode_timespec *ts, __le16 *time, __le16 *date, u8 *time_cs); extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs);
diff --git a/fs/fat/file.c b/fs/fat/file.c index 43d3475..e7f060f 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -188,13 +188,16 @@ static int fat_cont_expand(struct inode *inode, loff_t size) { struct address_space *mapping = inode->i_mapping; loff_t start = inode->i_size, count = size - inode->i_size; + struct inode_timespec ts; int err;
err = generic_cont_expand_simple(inode, size); if (err) goto out;
- inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; + ts = current_fs_time_sec(inode->i_sb); + VFS_INODE_SET_XTIME(i_ctime, inode, ts); + VFS_INODE_SET_XTIME(i_mtime, inode, ts); mark_inode_dirty(inode); if (IS_SYNC(inode)) { int err2; @@ -280,6 +283,7 @@ error: static int fat_free(struct inode *inode, int skip) { struct super_block *sb = inode->i_sb; + struct inode_timespec ts; int err, wait, free_start, i_start, i_logstart;
if (MSDOS_I(inode)->i_start == 0) @@ -297,7 +301,9 @@ static int fat_free(struct inode *inode, int skip) MSDOS_I(inode)->i_logstart = 0; } MSDOS_I(inode)->i_attrs |= ATTR_ARCH; - inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; + ts = current_fs_time_sec(sb); + VFS_INODE_SET_XTIME(i_ctime, inode, ts); + VFS_INODE_SET_XTIME(i_mtime, inode, ts); if (wait) { err = fat_sync_inode(inode); if (err) { diff --git a/fs/fat/inode.c b/fs/fat/inode.c index a559905..a1eba05 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -232,12 +232,15 @@ static int fat_write_end(struct file *file, struct address_space *mapping, struct page *pagep, void *fsdata) { struct inode *inode = mapping->host; + struct inode_timespec ts; int err; err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata); if (err < len) fat_write_failed(mapping, pos + len); if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) { - inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; + ts = current_fs_time_sec(inode->i_sb); + VFS_INODE_SET_XTIME(i_ctime, inode, ts); + VFS_INODE_SET_XTIME(i_mtime, inode, ts); MSDOS_I(inode)->i_attrs |= ATTR_ARCH; mark_inode_dirty(inode); } @@ -502,6 +505,7 @@ static int fat_validate_dir(struct inode *dir) int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) { struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); + struct inode_timespec mtime, ctime, atime; int error;
MSDOS_I(inode)->i_pos = 0; @@ -551,13 +555,21 @@ 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); + mtime = VFS_INODE_GET_XTIME(i_mtime, inode); + fat_time_fat2unix(sbi, &mtime, de->time, de->date, 0); if (sbi->options.isvfat) { - fat_time_fat2unix(sbi, &inode->i_ctime, de->ctime, - de->cdate, de->ctime_cs); - fat_time_fat2unix(sbi, &inode->i_atime, 0, de->adate, 0); - } else - inode->i_ctime = inode->i_atime = inode->i_mtime; + ctime = VFS_INODE_GET_XTIME(i_ctime, inode); + fat_time_fat2unix(sbi, + &ctime, + de->ctime, de->cdate, de->ctime_cs); + atime = VFS_INODE_GET_XTIME(i_atime, inode); + fat_time_fat2unix(sbi, &atime, + 0, de->adate, 0); + } else { + mtime = VFS_INODE_GET_XTIME(i_mtime, inode); + VFS_INODE_SET_XTIME(i_atime, inode, mtime); + VFS_INODE_SET_XTIME(i_ctime, inode, mtime); + }
return 0; } @@ -828,6 +840,7 @@ static int __fat_write_inode(struct inode *inode, int wait) struct msdos_sb_info *sbi = MSDOS_SB(sb); struct buffer_head *bh; struct msdos_dir_entry *raw_entry; + struct inode_timespec ts; loff_t i_pos; sector_t blocknr; int err, offset; @@ -861,14 +874,18 @@ 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, - &raw_entry->date, NULL); + ts = VFS_INODE_GET_XTIME(i_mtime, inode); + 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 = VFS_INODE_GET_XTIME(i_ctime, inode); + fat_time_unix2fat(sbi, &ts, + &raw_entry->ctime, &raw_entry->cdate, &raw_entry->ctime_cs); - fat_time_unix2fat(sbi, &inode->i_atime, &atime, - &raw_entry->adate, NULL); + ts = VFS_INODE_GET_XTIME(i_atime, inode); + fat_time_unix2fat(sbi, &ts, + &atime, &raw_entry->adate, NULL); } spin_unlock(&sbi->inode_hash_lock); mark_buffer_dirty(bh); @@ -1385,8 +1402,9 @@ static int fat_read_root(struct inode *inode) MSDOS_I(inode)->mmu_private = inode->i_size;
fat_save_attrs(inode, ATTR_DIR); - inode->i_mtime.tv_sec = inode->i_atime.tv_sec = inode->i_ctime.tv_sec = 0; - inode->i_mtime.tv_nsec = inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = 0; + VFS_INODE_SET_XTIME(i_atime, inode, ((struct inode_timespec) {0, 0})); + VFS_INODE_SET_XTIME(i_mtime, inode, ((struct inode_timespec) {0, 0})); + VFS_INODE_SET_XTIME(i_ctime, inode, ((struct inode_timespec) {0, 0})); set_nlink(inode, fat_subdirs(inode)+2);
return 0; diff --git a/fs/fat/misc.c b/fs/fat/misc.c index c4589e9..1544498 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -186,11 +186,12 @@ static time_t days_in_year[] = { };
/* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */ -void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts, +void fat_time_fat2unix(struct msdos_sb_info *sbi, struct inode_timespec *ts, __le16 __time, __le16 __date, u8 time_cs) { u16 time = le16_to_cpu(__time), date = le16_to_cpu(__date); - time_t second, day, leap_day, month, year; + long long second; + time_t day, leap_day, month, year;
year = date >> 9; month = max(1, (date >> 5) & 0xf); @@ -224,7 +225,7 @@ void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec *ts, }
/* Convert linear UNIX date to a FAT time/date pair. */ -void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec *ts, +void fat_time_unix2fat(struct msdos_sb_info *sbi, struct inode_timespec *ts, __le16 *time, __le16 *date, u8 *time_cs) { struct tm tm; diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index b7e2b33..457dcfb 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c @@ -224,7 +224,8 @@ static struct dentry *msdos_lookup(struct inode *dir, struct dentry *dentry, /***** Creates a directory entry (name is already formatted). */ static int msdos_add_entry(struct inode *dir, const unsigned char *name, int is_dir, int is_hid, int cluster, - struct timespec *ts, struct fat_slot_info *sinfo) + struct inode_timespec *ts, + struct fat_slot_info *sinfo) { struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb); struct msdos_dir_entry de; @@ -249,7 +250,8 @@ static int msdos_add_entry(struct inode *dir, const unsigned char *name, if (err) return err;
- dir->i_ctime = dir->i_mtime = *ts; + VFS_INODE_SET_XTIME(i_ctime, dir, *ts); + VFS_INODE_SET_XTIME(i_mtime, dir, *ts); if (IS_DIRSYNC(dir)) (void)fat_sync_inode(dir); else @@ -265,7 +267,7 @@ 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 inode_timespec ts; unsigned char msdos_name[MSDOS_NAME]; int err, is_hid;
@@ -283,7 +285,7 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode, goto out; }
- ts = CURRENT_TIME_SEC; + ts = current_fs_time_sec(sb); err = msdos_add_entry(dir, msdos_name, 0, is_hid, 0, &ts, &sinfo); if (err) goto out; @@ -293,7 +295,9 @@ static int msdos_create(struct inode *dir, struct dentry *dentry, umode_t mode, err = PTR_ERR(inode); goto out; } - inode->i_mtime = inode->i_atime = inode->i_ctime = ts; + VFS_INODE_SET_XTIME(i_atime, inode, ts); + VFS_INODE_SET_XTIME(i_mtime, inode, ts); + VFS_INODE_SET_XTIME(i_ctime, inode, ts); /* timestamp is already written, so mark_inode_dirty() is unneeded. */
d_instantiate(dentry, inode); @@ -330,7 +334,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) drop_nlink(dir);
clear_nlink(inode); - inode->i_ctime = CURRENT_TIME_SEC; + VFS_INODE_SET_XTIME(i_ctime, inode, current_fs_time_sec(sb)); fat_detach(inode); out: mutex_unlock(&MSDOS_SB(sb)->s_lock); @@ -347,7 +351,7 @@ 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 inode_timespec ts; int err, is_hid, cluster;
mutex_lock(&MSDOS_SB(sb)->s_lock); @@ -364,7 +368,7 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) goto out; }
- ts = CURRENT_TIME_SEC; + ts = current_fs_time_sec(sb); cluster = fat_alloc_new_dir(dir, &ts); if (cluster < 0) { err = cluster; @@ -383,7 +387,9 @@ static int msdos_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) goto out; } set_nlink(inode, 2); - inode->i_mtime = inode->i_atime = inode->i_ctime = ts; + VFS_INODE_SET_XTIME(i_atime, inode, ts); + VFS_INODE_SET_XTIME(i_mtime, inode, ts); + VFS_INODE_SET_XTIME(i_ctime, inode, ts); /* timestamp is already written, so mark_inode_dirty() is unneeded. */
d_instantiate(dentry, inode); @@ -416,7 +422,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry) if (err) goto out; clear_nlink(inode); - inode->i_ctime = CURRENT_TIME_SEC; + VFS_INODE_SET_XTIME(i_ctime, inode, current_fs_time_sec(sb)); fat_detach(inode); out: mutex_unlock(&MSDOS_SB(sb)->s_lock); @@ -434,8 +440,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, struct buffer_head *dotdot_bh; struct msdos_dir_entry *dotdot_de; struct inode *old_inode, *new_inode; + struct super_block *sb = old_dir->i_sb; struct fat_slot_info old_sinfo, sinfo; - struct timespec ts; + struct inode_timespec ts; loff_t new_i_pos; int err, old_attrs, is_dir, update_dotdot, corrupt = 0;
@@ -481,7 +488,9 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, mark_inode_dirty(old_inode);
old_dir->i_version++; - old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC; + ts = current_fs_time_sec(sb); + VFS_INODE_SET_XTIME(i_ctime, old_dir, ts); + VFS_INODE_SET_XTIME(i_mtime, old_dir, ts); if (IS_DIRSYNC(old_dir)) (void)fat_sync_inode(old_dir); else @@ -490,7 +499,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, } }
- ts = CURRENT_TIME_SEC; + ts = current_fs_time_sec(sb); if (new_inode) { if (err) goto out; @@ -541,7 +550,8 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, if (err) goto error_dotdot; old_dir->i_version++; - old_dir->i_ctime = old_dir->i_mtime = ts; + VFS_INODE_SET_XTIME(i_ctime, old_dir, ts); + VFS_INODE_SET_XTIME(i_mtime, old_dir, ts); if (IS_DIRSYNC(old_dir)) (void)fat_sync_inode(old_dir); else @@ -551,7 +561,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, drop_nlink(new_inode); if (is_dir) drop_nlink(new_inode); - new_inode->i_ctime = ts; + VFS_INODE_SET_XTIME(i_ctime, new_dir, ts); } out: brelse(sinfo.bh); diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 7092584..31da5b6 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -577,7 +577,7 @@ xlate_to_uni(const unsigned char *name, int len, unsigned char *outname,
static int vfat_build_slots(struct inode *dir, const unsigned char *name, int len, int is_dir, int cluster, - struct timespec *ts, + struct inode_timespec *ts, struct msdos_dir_slot *slots, int *nr_slots) { struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb); @@ -653,7 +653,7 @@ out_free: }
static int vfat_add_entry(struct inode *dir, struct qstr *qname, int is_dir, - int cluster, struct timespec *ts, + int cluster, struct inode_timespec *ts, struct fat_slot_info *sinfo) { struct msdos_dir_slot *slots; @@ -678,7 +678,9 @@ static int vfat_add_entry(struct inode *dir, struct qstr *qname, int is_dir, goto cleanup;
/* update timestamp */ - dir->i_ctime = dir->i_mtime = dir->i_atime = *ts; + VFS_INODE_SET_XTIME(i_ctime, dir, *ts); + VFS_INODE_SET_XTIME(i_mtime, dir, *ts); + VFS_INODE_SET_XTIME(i_atime, dir, *ts); if (IS_DIRSYNC(dir)) (void)fat_sync_inode(dir); else @@ -772,12 +774,12 @@ 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 inode_timespec ts; int err;
mutex_lock(&MSDOS_SB(sb)->s_lock);
- ts = CURRENT_TIME_SEC; + ts = current_fs_time_sec(sb); err = vfat_add_entry(dir, &dentry->d_name, 0, 0, &ts, &sinfo); if (err) goto out; @@ -790,7 +792,9 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, goto out; } inode->i_version++; - inode->i_mtime = inode->i_atime = inode->i_ctime = ts; + VFS_INODE_SET_XTIME(i_atime, inode, ts); + VFS_INODE_SET_XTIME(i_mtime, inode, ts); + VFS_INODE_SET_XTIME(i_ctime, inode, ts); /* timestamp is already written, so mark_inode_dirty() is unneeded. */
d_instantiate(dentry, inode); @@ -804,6 +808,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) struct inode *inode = d_inode(dentry); struct super_block *sb = dir->i_sb; struct fat_slot_info sinfo; + struct inode_timespec now; int err;
mutex_lock(&MSDOS_SB(sb)->s_lock); @@ -821,7 +826,9 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) drop_nlink(dir);
clear_nlink(inode); - inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; + now = current_fs_time_sec(sb); + VFS_INODE_SET_XTIME(i_atime, inode, now); + VFS_INODE_SET_XTIME(i_mtime, inode, now); fat_detach(inode); dentry->d_time = dir->i_version; out: @@ -835,6 +842,7 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry) struct inode *inode = d_inode(dentry); struct super_block *sb = dir->i_sb; struct fat_slot_info sinfo; + struct inode_timespec now; int err;
mutex_lock(&MSDOS_SB(sb)->s_lock); @@ -847,7 +855,9 @@ static int vfat_unlink(struct inode *dir, struct dentry *dentry) if (err) goto out; clear_nlink(inode); - inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC; + now = current_fs_time_sec(sb); + VFS_INODE_SET_XTIME(i_atime, dir, now); + VFS_INODE_SET_XTIME(i_mtime, dir, now); fat_detach(inode); dentry->d_time = dir->i_version; out: @@ -861,7 +871,7 @@ 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 inode_timespec ts; int err, cluster;
mutex_lock(&MSDOS_SB(sb)->s_lock); @@ -887,7 +897,9 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) } inode->i_version++; set_nlink(inode, 2); - inode->i_mtime = inode->i_atime = inode->i_ctime = ts; + VFS_INODE_SET_XTIME(i_atime, inode, ts); + VFS_INODE_SET_XTIME(i_mtime, inode, ts); + VFS_INODE_SET_XTIME(i_ctime, inode, ts); /* timestamp is already written, so mark_inode_dirty() is unneeded. */
d_instantiate(dentry, inode); @@ -909,7 +921,7 @@ 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 inode_timespec ts; loff_t new_i_pos; int err, is_dir, update_dotdot, corrupt = 0; struct super_block *sb = old_dir->i_sb; @@ -931,7 +943,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, } }
- ts = CURRENT_TIME_SEC; + ts = current_fs_time_sec(sb); if (new_inode) { if (is_dir) { err = fat_dir_empty(new_inode); @@ -976,7 +988,8 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, if (err) goto error_dotdot; old_dir->i_version++; - old_dir->i_ctime = old_dir->i_mtime = ts; + VFS_INODE_SET_XTIME(i_ctime, old_dir, ts); + VFS_INODE_SET_XTIME(i_mtime, old_dir, ts); if (IS_DIRSYNC(old_dir)) (void)fat_sync_inode(old_dir); else @@ -986,7 +999,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, drop_nlink(new_inode); if (is_dir) drop_nlink(new_inode); - new_inode->i_ctime = ts; + VFS_INODE_SET_XTIME(i_ctime, new_inode, ts); } out: brelse(sinfo.bh);