From patchwork Sat Sep 22 20:19:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Sorenson X-Patchwork-Id: 10611555 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7D9EA15A6 for ; Sat, 22 Sep 2018 20:20:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D997B2AE80 for ; Sat, 22 Sep 2018 20:20:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CBDD82AEC4; Sat, 22 Sep 2018 20:20:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B81F62AE80 for ; Sat, 22 Sep 2018 20:20:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727474AbeIWCOt (ORCPT ); Sat, 22 Sep 2018 22:14:49 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38362 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726226AbeIWCOt (ORCPT ); Sat, 22 Sep 2018 22:14:49 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5995830820D5; Sat, 22 Sep 2018 20:20:01 +0000 (UTC) Received: from hut.sorensonfamily.com.com (ovpn-116-190.phx2.redhat.com [10.3.116.190]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D9B1187DE; Sat, 22 Sep 2018 20:20:00 +0000 (UTC) From: Frank Sorenson To: linux-fsdevel@vger.kernel.org Cc: hirofumi@mail.parknet.co.jp Subject: [PATCH 1/4] fat: set the s_time_gran for msdos or vfat mounts Date: Sat, 22 Sep 2018 15:19:56 -0500 Message-Id: <20180922201959.10477-2-sorenson@redhat.com> In-Reply-To: <20180922201959.10477-1-sorenson@redhat.com> References: <20180922201959.10477-1-sorenson@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Sat, 22 Sep 2018 20:20:01 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP For vfat, ctime granularity is 10ms; set the super_block's s_time_gran to 10ms for vfat and 1 second for msdos mounts. Signed-off-by: Frank Sorenson --- fs/fat/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/fat/inode.c b/fs/fat/inode.c index d6b81e31f9f5..36071866a324 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1626,6 +1626,7 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, int isvfat, sb->s_magic = MSDOS_SUPER_MAGIC; sb->s_op = &fat_sops; sb->s_export_op = &fat_export_ops; + sb->s_time_gran = isvfat ? 10000000 : 1000000000; mutex_init(&sbi->nfs_build_inode_lock); ratelimit_state_init(&sbi->ratelimit, DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); From patchwork Sat Sep 22 20:19:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Sorenson X-Patchwork-Id: 10611559 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 861B115A6 for ; Sat, 22 Sep 2018 20:20:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 757502AEAA for ; Sat, 22 Sep 2018 20:20:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 452032AE9F; Sat, 22 Sep 2018 20:20:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D8F2A2AE85 for ; Sat, 22 Sep 2018 20:20:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727588AbeIWCOu (ORCPT ); Sat, 22 Sep 2018 22:14:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59490 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726226AbeIWCOu (ORCPT ); Sat, 22 Sep 2018 22:14:50 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E3B5C5F734; Sat, 22 Sep 2018 20:20:01 +0000 (UTC) Received: from hut.sorensonfamily.com.com (ovpn-116-190.phx2.redhat.com [10.3.116.190]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7809B87DE; Sat, 22 Sep 2018 20:20:01 +0000 (UTC) From: Frank Sorenson To: linux-fsdevel@vger.kernel.org Cc: hirofumi@mail.parknet.co.jp Subject: [PATCH 2/4] fat: create function to calculate timezone offset Date: Sat, 22 Sep 2018 15:19:57 -0500 Message-Id: <20180922201959.10477-3-sorenson@redhat.com> In-Reply-To: <20180922201959.10477-1-sorenson@redhat.com> References: <20180922201959.10477-1-sorenson@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Sat, 22 Sep 2018 20:20:02 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a function to calculate the timezone offset in minutes. Signed-off-by: Frank Sorenson --- fs/fat/fat.h | 12 ++++++++++++ fs/fat/misc.c | 12 ++---------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/fs/fat/fat.h b/fs/fat/fat.h index 9d7d2d5da28b..c40f7e69f078 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -412,6 +412,18 @@ 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); + +#define SECS_PER_MIN 60 +#define SECS_PER_HOUR (60 * 60) +#define SECS_PER_DAY (SECS_PER_HOUR * 24) + +static inline int fat_tz_offset(struct msdos_sb_info *sbi) +{ + return (sbi->options.tz_set ? + - sbi->options.time_offset : + sys_tz.tz_minuteswest) * SECS_PER_MIN; +} + extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts, __le16 __time, __le16 __date, u8 time_cs); extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts, diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 573836dcaefc..58580c7e558e 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -170,9 +170,6 @@ int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster) * time: 5 - 10: min (0 - 59) * time: 11 - 15: hour (0 - 23) */ -#define SECS_PER_MIN 60 -#define SECS_PER_HOUR (60 * 60) -#define SECS_PER_DAY (SECS_PER_HOUR * 24) /* days between 1.1.70 and 1.1.80 (2 leap days) */ #define DAYS_DELTA (365 * 10 + 2) /* 120 (2100 - 1980) isn't leap year */ @@ -210,10 +207,7 @@ void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts, + days_in_year[month] + day + DAYS_DELTA) * SECS_PER_DAY; - if (!sbi->options.tz_set) - second += sys_tz.tz_minuteswest * SECS_PER_MIN; - else - second -= sbi->options.time_offset * SECS_PER_MIN; + second += fat_tz_offset(sbi); if (time_cs) { ts->tv_sec = second + (time_cs / 100); @@ -229,9 +223,7 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts, __le16 *time, __le16 *date, u8 *time_cs) { struct tm tm; - time64_to_tm(ts->tv_sec, - (sbi->options.tz_set ? sbi->options.time_offset : - -sys_tz.tz_minuteswest) * SECS_PER_MIN, &tm); + time64_to_tm(ts->tv_sec, -fat_tz_offset(sbi), &tm); /* FAT can only support year between 1980 to 2107 */ if (tm.tm_year < 1980 - 1900) { From patchwork Sat Sep 22 20:19:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Sorenson X-Patchwork-Id: 10611561 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 93848174F for ; Sat, 22 Sep 2018 20:20:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7D4742AF78 for ; Sat, 22 Sep 2018 20:20:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6704E2AE86; Sat, 22 Sep 2018 20:20:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 05B312AE86 for ; Sat, 22 Sep 2018 20:20:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727673AbeIWCOv (ORCPT ); Sat, 22 Sep 2018 22:14:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37030 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726226AbeIWCOu (ORCPT ); Sat, 22 Sep 2018 22:14:50 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5C5483083390; Sat, 22 Sep 2018 20:20:02 +0000 (UTC) Received: from hut.sorensonfamily.com.com (ovpn-116-190.phx2.redhat.com [10.3.116.190]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 00EC39CC2; Sat, 22 Sep 2018 20:20:01 +0000 (UTC) From: Frank Sorenson To: linux-fsdevel@vger.kernel.org Cc: hirofumi@mail.parknet.co.jp Subject: [PATCH 3/4] fat: add functions to update and truncate the timestamps appropriately Date: Sat, 22 Sep 2018 15:19:58 -0500 Message-Id: <20180922201959.10477-4-sorenson@redhat.com> In-Reply-To: <20180922201959.10477-1-sorenson@redhat.com> References: <20180922201959.10477-1-sorenson@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Sat, 22 Sep 2018 20:20:02 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add the fat-specific inode_operation ->update_time() and fat_truncate_time() function to truncate the inode timestamps with the appropriate granularity. Signed-off-by: Frank Sorenson --- fs/fat/fat.h | 2 ++ fs/fat/file.c | 1 + fs/fat/misc.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/fat/namei_msdos.c | 1 + fs/fat/namei_vfat.c | 1 + 5 files changed, 67 insertions(+) diff --git a/fs/fat/fat.h b/fs/fat/fat.h index c40f7e69f078..6201c6bdb5f9 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -428,6 +428,8 @@ extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts, __le16 __time, __le16 __date, u8 time_cs); extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts, __le16 *time, __le16 *date, u8 *time_cs); +extern int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags); +extern int fat_update_time(struct inode *inode, struct timespec64 *now, int flags); extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs); int fat_cache_init(void); diff --git a/fs/fat/file.c b/fs/fat/file.c index 4f3d72fb1e60..19b6b0566411 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -552,4 +552,5 @@ EXPORT_SYMBOL_GPL(fat_setattr); const struct inode_operations fat_file_inode_operations = { .setattr = fat_setattr, .getattr = fat_getattr, + .update_time = fat_update_time, }; diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 58580c7e558e..42c4fb063287 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c @@ -255,6 +255,68 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts, } EXPORT_SYMBOL_GPL(fat_time_unix2fat); +/* + * truncate the various times with appropriate granularity: + * root inode: + * all times always 0 + * all other inodes: + * mtime - 2 seconds + * ctime + * msdos - 2 seconds + * vfat - 10 milliseconds + * atime - 24 hours (00:00:00 in local timezone) + */ +noinline int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags) +{ + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb); + struct timespec64 ts; + + if (inode->i_ino == MSDOS_ROOT_INO) + return 0; + + if (now == NULL) { + now = &ts; + ts = current_time(inode); + } + + if (flags & S_ATIME) { + int offset = fat_tz_offset(sbi); + long seconds; + + seconds = now->tv_sec; + seconds -= (now->tv_sec - offset) % 86400; + + inode->i_atime = (struct timespec64){ seconds, 0 }; + } + if (flags & S_CTIME) { + if (sbi->options.isvfat) + inode->i_ctime = *now; + else + inode->i_ctime = (struct timespec64){ now->tv_sec & ~1, 0 }; + } + if (flags & S_MTIME) + inode->i_mtime = (struct timespec64){ now->tv_sec & ~1, 0 }; + return 0; +} +EXPORT_SYMBOL_GPL(fat_truncate_time); + +int fat_update_time(struct inode *inode, struct timespec64 *now, int flags) +{ + int iflags = I_DIRTY_TIME; + + if (inode->i_ino == MSDOS_ROOT_INO) + return 0; + fat_truncate_time(inode, now, flags); + + if ((flags & (S_ATIME | S_CTIME | S_MTIME)) && + !(inode->i_sb->s_flags & SB_LAZYTIME)) + iflags |= I_DIRTY_SYNC; + + __mark_inode_dirty(inode, iflags); + return 0; +} +EXPORT_SYMBOL_GPL(fat_update_time); + int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs) { int i, err = 0; diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index efb8c40c9d27..effbdd5fbf6e 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c @@ -637,6 +637,7 @@ static const struct inode_operations msdos_dir_inode_operations = { .rename = msdos_rename, .setattr = fat_setattr, .getattr = fat_getattr, + .update_time = fat_update_time, }; static void setup(struct super_block *sb) diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 82cd1e69cbdf..1daa57cf4bf3 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -1032,6 +1032,7 @@ static const struct inode_operations vfat_dir_inode_operations = { .rename = vfat_rename, .setattr = fat_setattr, .getattr = fat_getattr, + .update_time = fat_update_time, }; static void setup(struct super_block *sb) From patchwork Sat Sep 22 20:19:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Sorenson X-Patchwork-Id: 10611563 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DD1226CB for ; Sat, 22 Sep 2018 20:20:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5FCE2AEEF for ; Sat, 22 Sep 2018 20:20:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BFC9F2AEB0; Sat, 22 Sep 2018 20:20:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2699A2AE87 for ; Sat, 22 Sep 2018 20:20:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727691AbeIWCOv (ORCPT ); Sat, 22 Sep 2018 22:14:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46234 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727611AbeIWCOv (ORCPT ); Sat, 22 Sep 2018 22:14:51 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CB1BF32B696; Sat, 22 Sep 2018 20:20:02 +0000 (UTC) Received: from hut.sorensonfamily.com.com (ovpn-116-190.phx2.redhat.com [10.3.116.190]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 772779CC2; Sat, 22 Sep 2018 20:20:02 +0000 (UTC) From: Frank Sorenson To: linux-fsdevel@vger.kernel.org Cc: hirofumi@mail.parknet.co.jp Subject: [PATCH 4/4] fat: change timestamp updates to fat_update_time or fat_truncate_time Date: Sat, 22 Sep 2018 15:19:59 -0500 Message-Id: <20180922201959.10477-5-sorenson@redhat.com> In-Reply-To: <20180922201959.10477-1-sorenson@redhat.com> References: <20180922201959.10477-1-sorenson@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Sat, 22 Sep 2018 20:20:02 +0000 (UTC) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Make the inode timestamp updates use fat_update_time or fat_truncate_time, depending on whether to call mark_inode_dirty. Signed-off-by: Frank Sorenson --- fs/fat/dir.c | 2 +- fs/fat/file.c | 17 ++++++++++++++--- fs/fat/inode.c | 5 ++--- fs/fat/namei_msdos.c | 16 ++++++++-------- fs/fat/namei_vfat.c | 14 +++++++------- 5 files changed, 32 insertions(+), 22 deletions(-) diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 7f5f3699fc6c..1f9bad2c06c7 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c @@ -1071,7 +1071,7 @@ int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo) } } - dir->i_mtime = dir->i_atime = current_time(dir); + fat_truncate_time(dir, NULL, S_ATIME|S_MTIME); if (IS_DIRSYNC(dir)) (void)fat_sync_inode(dir); else diff --git a/fs/fat/file.c b/fs/fat/file.c index 19b6b0566411..cf0d5aea6e43 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -227,8 +227,7 @@ static int fat_cont_expand(struct inode *inode, loff_t size) if (err) goto out; - inode->i_ctime = inode->i_mtime = current_time(inode); - mark_inode_dirty(inode); + fat_update_time(inode, NULL, S_CTIME|S_MTIME); if (IS_SYNC(inode)) { int err2; @@ -330,7 +329,7 @@ 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(inode); + fat_truncate_time(inode, NULL, S_CTIME|S_MTIME); if (wait) { err = fat_sync_inode(inode); if (err) { @@ -542,6 +541,18 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) up_write(&MSDOS_I(inode)->truncate_lock); } + /* + * setattr_copy can't truncate these appropriately, so we'll + * copy them ourselves + */ + if (attr->ia_valid & ATTR_ATIME) + fat_truncate_time(inode, &attr->ia_atime, S_ATIME); + if (attr->ia_valid & ATTR_CTIME) + fat_truncate_time(inode, &attr->ia_ctime, S_CTIME); + if (attr->ia_valid & ATTR_MTIME) + fat_truncate_time(inode, &attr->ia_mtime, S_MTIME); + attr->ia_valid &= ~(ATTR_ATIME|ATTR_CTIME|ATTR_MTIME); + setattr_copy(inode, attr); mark_inode_dirty(inode); out: diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 36071866a324..a803008d8100 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -244,9 +244,8 @@ static int fat_write_end(struct file *file, struct address_space *mapping, 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(inode); MSDOS_I(inode)->i_attrs |= ATTR_ARCH; - mark_inode_dirty(inode); + fat_update_time(inode, NULL, S_CTIME|S_MTIME); } return err; } @@ -564,7 +563,7 @@ int fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de) 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; + fat_update_time(inode, &inode->i_mtime, S_ATIME|S_CTIME); return 0; } diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index effbdd5fbf6e..6506290a3e99 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c @@ -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; + fat_truncate_time(dir, ts, S_CTIME|S_MTIME); if (IS_DIRSYNC(dir)) (void)fat_sync_inode(dir); else @@ -294,7 +294,7 @@ 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; + fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME); /* timestamp is already written, so mark_inode_dirty() is unneeded. */ d_instantiate(dentry, inode); @@ -327,7 +327,7 @@ static int msdos_rmdir(struct inode *dir, struct dentry *dentry) drop_nlink(dir); clear_nlink(inode); - inode->i_ctime = current_time(inode); + fat_update_time(inode, NULL, S_CTIME); fat_detach(inode); out: mutex_unlock(&MSDOS_SB(sb)->s_lock); @@ -380,7 +380,7 @@ 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; + fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME); /* timestamp is already written, so mark_inode_dirty() is unneeded. */ d_instantiate(dentry, inode); @@ -413,7 +413,7 @@ static int msdos_unlink(struct inode *dir, struct dentry *dentry) if (err) goto out; clear_nlink(inode); - inode->i_ctime = current_time(inode); + fat_update_time(inode, NULL, S_CTIME); fat_detach(inode); out: mutex_unlock(&MSDOS_SB(sb)->s_lock); @@ -478,7 +478,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, mark_inode_dirty(old_inode); inode_inc_iversion(old_dir); - old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir); + fat_truncate_time(old_dir, NULL, S_CTIME|S_MTIME); if (IS_DIRSYNC(old_dir)) (void)fat_sync_inode(old_dir); else @@ -538,7 +538,7 @@ static int do_msdos_rename(struct inode *old_dir, unsigned char *old_name, if (err) goto error_dotdot; inode_inc_iversion(old_dir); - old_dir->i_ctime = old_dir->i_mtime = ts; + fat_truncate_time(old_dir, &ts, S_CTIME|S_MTIME); if (IS_DIRSYNC(old_dir)) (void)fat_sync_inode(old_dir); else @@ -548,7 +548,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; + fat_truncate_time(new_inode, &ts, S_CTIME); } out: brelse(sinfo.bh); diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 1daa57cf4bf3..e384f2b7d088 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -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; + fat_truncate_time(dir, ts, S_CTIME|S_MTIME); if (IS_DIRSYNC(dir)) (void)fat_sync_inode(dir); else @@ -779,7 +779,7 @@ static int vfat_create(struct inode *dir, struct dentry *dentry, umode_t mode, goto out; } inode_inc_iversion(inode); - inode->i_mtime = inode->i_atime = inode->i_ctime = ts; + fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME); /* timestamp is already written, so mark_inode_dirty() is unneeded. */ d_instantiate(dentry, inode); @@ -810,7 +810,7 @@ static int vfat_rmdir(struct inode *dir, struct dentry *dentry) drop_nlink(dir); clear_nlink(inode); - inode->i_mtime = inode->i_atime = current_time(inode); + fat_update_time(inode, NULL, S_ATIME|S_MTIME); fat_detach(inode); vfat_d_version_set(dentry, inode_query_iversion(dir)); out: @@ -836,7 +836,7 @@ 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(inode); + fat_update_time(inode, NULL, S_ATIME|S_MTIME); fat_detach(inode); vfat_d_version_set(dentry, inode_query_iversion(dir)); out: @@ -876,7 +876,7 @@ static int vfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) } inode_inc_iversion(inode); set_nlink(inode, 2); - inode->i_mtime = inode->i_atime = inode->i_ctime = ts; + fat_truncate_time(inode, &ts, S_ATIME|S_CTIME|S_MTIME); /* timestamp is already written, so mark_inode_dirty() is unneeded. */ d_instantiate(dentry, inode); @@ -969,7 +969,7 @@ static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, if (err) goto error_dotdot; inode_inc_iversion(old_dir); - old_dir->i_ctime = old_dir->i_mtime = ts; + fat_truncate_time(old_dir, &ts, S_CTIME|S_MTIME); if (IS_DIRSYNC(old_dir)) (void)fat_sync_inode(old_dir); else @@ -979,7 +979,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; + fat_truncate_time(new_inode, &ts, S_CTIME); } out: brelse(sinfo.bh);