From patchwork Thu Jan 7 05:36:03 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepa Dinamani X-Patchwork-Id: 7973531 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 627D7BEEE5 for ; Thu, 7 Jan 2016 05:38:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A40A62017D for ; Thu, 7 Jan 2016 05:38:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C2A562012D for ; Thu, 7 Jan 2016 05:38:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752704AbcAGFhE (ORCPT ); Thu, 7 Jan 2016 00:37:04 -0500 Received: from mail-pa0-f65.google.com ([209.85.220.65]:34039 "EHLO mail-pa0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752032AbcAGFgw (ORCPT ); Thu, 7 Jan 2016 00:36:52 -0500 Received: by mail-pa0-f65.google.com with SMTP id yy13so19281759pab.1; Wed, 06 Jan 2016 21:36:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id:in-reply-to:references; bh=kHbysU5KHA9u4yuxD/oqyzMj4qL+nYwQvBdpoAp33sQ=; b=sSXroxZUqCvKxXrfoUnzWCiKEHKlaQJC79+2cRgPAPvY9Tkx2wXkC3KcASEQic6o+i wnphOfTbiwN0joWY+lhzau+N6Fr/4TgKJbL2wN+bLEyLlLq2oYT0/AdRNprwNGRHtfmp 4iflp/p/ps2MsgwxbccKiOO/pwnRcPOVAINnqVnPk2Vn2Plsz5QJDvzbyTL/RB/3WzQz xX0JUGq20mfErIwT+bg6jQhRSQziWkQ+GA5dqpiEIrEh0giXTm6xHOBX6zzS+fgeXfWD YNtQKexndbQ2OqCeGIBdlmDJZ2Bz2TeQEHNWtwXkncHDIZu4KR7x7stxUCtYSeSToCO7 PKUg== X-Received: by 10.66.216.7 with SMTP id om7mr146573367pac.90.1452145011605; Wed, 06 Jan 2016 21:36:51 -0800 (PST) Received: from localhost.localdomain ([106.51.24.71]) by smtp.gmail.com with ESMTPSA id kk5sm131390736pab.16.2016.01.06.21.36.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 06 Jan 2016 21:36:51 -0800 (PST) From: Deepa Dinamani To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, y2038@lists.linaro.org Subject: [RFC 06/15] fs: fat: convert fat to 64 bit time Date: Wed, 6 Jan 2016 21:36:03 -0800 Message-Id: <1452144972-15802-7-git-send-email-deepa.kernel@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1452144972-15802-1-git-send-email-deepa.kernel@gmail.com> References: <1452144972-15802-1-git-send-email-deepa.kernel@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-3.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SBL_CSS, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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);